diff --git a/CREDITS b/CREDITS index ba57698dcc10..32abf67ee1fa 100644 --- a/CREDITS +++ b/CREDITS @@ -4112,6 +4112,10 @@ S: 4226 Landgreen Street S: Rockville, Maryland 20853 S: USA +N: Michael Turquette +E: mturquette@baylibre.com +D: common clk maintenance + N: Stephen Tweedie E: sct@redhat.com P: 1024/E7A417AD E2 FE A4 20 34 EC ED FC 7D 7E 67 8D E0 31 D1 69 diff --git a/Documentation/devicetree/bindings/clock/amlogic,a9-aoclkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a9-aoclkc.yaml new file mode 100644 index 000000000000..1fa9b3a32fbb --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,a9-aoclkc.yaml @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2026 Amlogic, Inc. All rights reserved +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/amlogic,a9-aoclkc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic A9 Series Always-On Clock Controller + +maintainers: + - Neil Armstrong + - Jerome Brunet + - Jian Hu + - Xianwei Zhao + +properties: + compatible: + const: amlogic,a9-aoclkc + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + + clocks: + minItems: 5 + items: + - description: input oscillator + - description: input fclk div 3 + - description: input fclk div 4 + - description: input fclk div 5 + - description: input sys clk + - description: external fixed 32k (optional) + + clock-names: + minItems: 5 + items: + - const: xtal + - const: fdiv3 + - const: fdiv4 + - const: fdiv5 + - const: sys + - const: ext_32k + +required: + - compatible + - reg + - '#clock-cells' + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@0 { + compatible = "amlogic,a9-aoclkc"; + reg = <0x0 0x0 0x0 0x58>; + #clock-cells = <1>; + clocks = <&xtal>, + <&scmi_clk 14>, + <&scmi_clk 16>, + <&scmi_clk 18>, + <&scmi_clk 21>; + clock-names = "xtal", + "fdiv3", + "fdiv4", + "fdiv5", + "sys"; + }; + }; diff --git a/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml new file mode 100644 index 000000000000..f0aef005ecf3 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2026 Amlogic, Inc. All rights reserved +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/amlogic,a9-peripherals-clkc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic A9 Series Peripherals Clock Controller + +maintainers: + - Neil Armstrong + - Jerome Brunet + - Jian Hu + - Xianwei Zhao + +properties: + compatible: + const: amlogic,a9-peripherals-clkc + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + + clocks: + minItems: 27 + items: + - description: input oscillator + - description: input fclk div 2 + - description: input fclk div 3 + - description: input fclk div 4 + - description: input fclk div 5 + - description: input fclk div 7 + - description: input fclk div 2p5 + - description: input sys clk + - description: input gp1 pll + - description: input gp2 pll + - description: input sys pll div 16 + - description: input cpu clk div 16 + - description: input a78 clk div 16 + - description: input dsu clk div 16 + - description: input rtc clk + - description: input gp0 pll + - description: input hifi0 pll + - description: input hifi1 pll + - description: input mclk0 pll + - description: input mclk1 pll + - description: input video1 pll + - description: input video2 pll + - description: input hdmi out2 clk + - description: input hdmi pixel clk + - description: input pixel0 pll + - description: input pixel1 pll + - description: input ddr pll test clk + - description: external input rmii oscillator (optional) + + clock-names: + minItems: 27 + items: + - const: xtal + - const: fdiv2 + - const: fdiv3 + - const: fdiv4 + - const: fdiv5 + - const: fdiv7 + - const: fdiv2p5 + - const: sys + - const: gp1 + - const: gp2 + - const: sysplldiv16 + - const: cpudiv16 + - const: a78div16 + - const: dsudiv16 + - const: rtc + - const: gp0 + - const: hifi0 + - const: hifi1 + - const: mclk0 + - const: mclk1 + - const: vid1 + - const: vid2 + - const: hdmiout2 + - const: hdmipix + - const: pix0 + - const: pix1 + - const: ddr_test + - const: ext_rmii + +required: + - compatible + - reg + - '#clock-cells' + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@200 { + compatible = "amlogic,a9-peripherals-clkc"; + reg = <0x0 0x200 0x0 0x2f8>; + #clock-cells = <1>; + clocks = <&xtal>, + <&scmi_clk 10>, + <&scmi_clk 12>, + <&scmi_clk 14>, + <&scmi_clk 16>, + <&scmi_clk 18>, + <&scmi_clk 20>, + <&scmi_clk 21>, + <&scmi_clk 33>, + <&scmi_clk 34>, + <&scmi_clk 35>, + <&scmi_clk 36>, + <&scmi_clk 37>, + <&scmi_clk 38>, + <&scmi_clk 40>, + <&gp0 3>, + <&hifi0 3>, + <&hifi1 3>, + <&mclk0 3>, + <&mclk1 3>, + <&vid1>, + <&vid2>, + <&hdmitx 10>, + <&hdmitx 11>, + <&pix0>, + <&pix1>, + <&ddr 3>; + clock-names = "xtal", + "fdiv2", + "fdiv3", + "fdiv4", + "fdiv5", + "fdiv7", + "fdiv2p5", + "sys", + "gp1", + "gp2", + "sysplldiv16", + "cpudiv16", + "a78div16", + "dsudiv16", + "rtc", + "gp0", + "hifi0", + "hifi1", + "mclk0", + "mclk1", + "vid1", + "vid2", + "hdmiout2", + "hdmipix", + "pix0", + "pix1", + "ddr_test"; + }; + }; diff --git a/Documentation/devicetree/bindings/clock/eswin,eic7700-hspcrg.yaml b/Documentation/devicetree/bindings/clock/eswin,eic7700-hspcrg.yaml new file mode 100644 index 000000000000..43df689ae647 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/eswin,eic7700-hspcrg.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/eswin,eic7700-hspcrg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ESWIN EIC7700 HSP Clock and Reset Generator + +maintainers: + - Xuyang Dong + +description: + Clock and reset generator for the ESWIN EIC7700 HSP (high-speed peripherals). + +properties: + compatible: + const: eswin,eic7700-hspcrg + + reg: + maxItems: 1 + + clocks: + items: + - description: HSP configuration top clock + - description: MMC top clock + - description: SATA top clock + + clock-names: + items: + - const: cfg + - const: mmc + - const: sata + + '#clock-cells': + const: 1 + description: + See for valid indices. + + '#reset-cells': + const: 1 + description: + See for valid indices. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + clock-controller@50440000 { + compatible = "eswin,eic7700-hspcrg"; + reg = <0x50440000 0x2000>; + clocks = <&clock 171>, <&clock 254>, <&clock 187>; + clock-names = "cfg", "mmc", "sata"; + #clock-cells = <1>; + #reset-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/clock/keystone-gate.txt b/Documentation/devicetree/bindings/clock/keystone-gate.txt deleted file mode 100644 index 43f6fb6c9392..000000000000 --- a/Documentation/devicetree/bindings/clock/keystone-gate.txt +++ /dev/null @@ -1,27 +0,0 @@ -Binding for Keystone gate control driver which uses PSC controller IP. - -This binding uses the common clock binding[1]. - -[1] Documentation/devicetree/bindings/clock/clock-bindings.txt - -Required properties: -- compatible : shall be "ti,keystone,psc-clock". -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : parent clock phandle -- reg : psc control and domain address address space -- reg-names : psc control and domain registers -- domain-id : psc domain id needed to check the transition state register - -Optional properties: -- clock-output-names : From common clock binding to override the - default output clock name -Example: - clkusb: clkusb { - #clock-cells = <0>; - compatible = "ti,keystone,psc-clock"; - clocks = <&chipclk16>; - clock-output-names = "usb"; - reg = <0x02350008 0xb00>, <0x02350000 0x400>; - reg-names = "control", "domain"; - domain-id = <0>; - }; diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8173-mfgtop.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8173-mfgtop.yaml new file mode 100644 index 000000000000..03db1ee9e594 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/mediatek,mt8173-mfgtop.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- + +$id: http://devicetree.org/schemas/clock/mediatek,mt8173-mfgtop.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT8173 MFG TOP controller + +maintainers: + - AngeloGioacchino Del Regno + +description: + The MFG TOP glue layer controls various signals going to the MFG (GPU) + block on the MT8173. + +properties: + compatible: + const: mediatek,mt8173-mfgtop + + reg: + maxItems: 1 + + clocks: + maxItems: 4 + + clock-names: + items: + - const: sys + - const: mem + - const: core + - const: clk26m + + power-domains: + maxItems: 1 + + '#clock-cells': + const: 1 + + '#power-domain-cells': + const: 0 + +required: + - compatible + - reg + - clocks + - clock-names + - power-domains + - '#clock-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | + #include + #include + + clock-controller@13fff000 { + compatible = "mediatek,mt8173-mfgtop"; + reg = <0x13fff000 0x1000>; + clocks = <&topckgen CLK_TOP_AXI_MFG_IN_SEL>, + <&topckgen CLK_TOP_MEM_MFG_IN_SEL>, + <&topckgen CLK_TOP_MFG_SEL>, + <&clk26m>; + clock-names = "sys", "mem", "core", "clk26m"; + power-domains = <&spm MT8173_POWER_DOMAIN_MFG>; + #clock-cells = <1>; + #power-domain-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/clock/mediatek,pericfg.yaml b/Documentation/devicetree/bindings/clock/mediatek,pericfg.yaml index b98cf45efe2f..f0c8df4d10c8 100644 --- a/Documentation/devicetree/bindings/clock/mediatek,pericfg.yaml +++ b/Documentation/devicetree/bindings/clock/mediatek,pericfg.yaml @@ -65,7 +65,7 @@ examples: - | pericfg@10003000 { - compatible = "mediatek,mt7623-pericfg", "mediatek,mt2701-pericfg", "syscon"; + compatible = "mediatek,mt7623-pericfg", "mediatek,mt2701-pericfg", "syscon"; reg = <0x10003000 0x1000>; #clock-cells = <1>; #reset-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml b/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml index 47ceab641a4c..1eec77e75a0a 100644 --- a/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml @@ -17,6 +17,7 @@ properties: compatible: enum: - qcom,ipq5018-a53pll + - qcom,ipq5210-a53pll - qcom,ipq5332-a53pll - qcom,ipq6018-a53pll - qcom,ipq8074-a53pll diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9607.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9607.yaml index 0a7be7583bdd..d4dd51fb4b8a 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9607.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9607.yaml @@ -25,19 +25,33 @@ properties: enum: - qcom,gcc-mdm9607 + clocks: + items: + - description: XO source + - description: Sleep clock source + + clock-names: + items: + - const: xo + - const: sleep_clk + required: - compatible + - clocks + - clock-names - '#power-domain-cells' unevaluatedProperties: false examples: - | - clock-controller@900000 { + clock-controller@1800000 { compatible = "qcom,gcc-mdm9607"; - reg = <0x900000 0x4000>; + reg = <0x01800000 0x80000>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + clocks = <&xo_board>, <&sleep_clk>; + clock-names = "xo", "sleep_clk"; }; ... diff --git a/Documentation/devicetree/bindings/clock/qcom,glymur-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,glymur-gcc.yaml index b05b0e6c4483..7a4054c9f215 100644 --- a/Documentation/devicetree/bindings/clock/qcom,glymur-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,glymur-gcc.yaml @@ -65,9 +65,15 @@ properties: - description: USB4 PHY 2 pcie pipe clock source - description: USB4 PHY 2 Max pipe clock source + power-domains: + description: + A phandle and PM domain specifier for the CX power domain. + maxItems: 1 + required: - compatible - clocks + - power-domains - '#power-domain-cells' allOf: @@ -78,6 +84,7 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,glymur-gcc"; reg = <0x100000 0x1f9000>; @@ -113,6 +120,7 @@ examples: <&usb4_phy_0_pcie_pipe>, <&usb4_phy_0_max_pipe>, <&usb4_phy_1_pcie_pipe>, <&usb4_phy_1_max_pipe>, <&usb4_phy_2_pcie_pipe>, <&usb4_phy_2_max_pipe>; + power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,glymur-tcsr.yaml b/Documentation/devicetree/bindings/clock/qcom,glymur-tcsr.yaml new file mode 100644 index 000000000000..2b6422627165 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,glymur-tcsr.yaml @@ -0,0 +1,146 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,glymur-tcsr.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm TCSR Clock Controller on Glymur + +maintainers: + - Bjorn Andersson + - Taniya Das + +description: | + Qualcomm TCSR clock control module provides the clocks, resets and + power domains on Glymur + + See also: + - include/dt-bindings/clock/qcom,glymur-tcsr.h + +properties: + compatible: + items: + - enum: + - qcom,glymur-tcsr + - qcom,mahua-tcsr + - const: syscon + + clocks: + items: + - description: TCXO pad clock + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 1 + + vdda-qrefrpt0-0p9-supply: true + vdda-qrefrpt1-0p9-supply: true + vdda-qrefrpt2-0p9-supply: true + vdda-qrefrpt3-0p9-supply: true + vdda-qrefrpt4-0p9-supply: true + vdda-qrefrpt5-0p9-supply: true + vdda-qrefrx0-0p9-supply: true + vdda-qrefrx1-0p9-supply: true + vdda-qrefrx2-0p9-supply: true + vdda-qrefrx3-0p9-supply: true + vdda-qrefrx4-0p9-supply: true + vdda-qrefrx5-0p9-supply: true + vdda-qreftx0-0p9-supply: true + vdda-qreftx0-1p2-supply: true + vdda-qreftx1-0p9-supply: true + vdda-refgen3-0p9-supply: true + vdda-refgen3-1p2-supply: true + vdda-refgen4-0p9-supply: true + vdda-refgen4-1p2-supply: true + +allOf: + - if: + properties: + compatible: + contains: + const: qcom,glymur-tcsr + then: + required: + - vdda-qrefrpt0-0p9-supply + - vdda-qrefrpt1-0p9-supply + - vdda-qrefrpt2-0p9-supply + - vdda-qrefrpt3-0p9-supply + - vdda-qrefrpt4-0p9-supply + - vdda-qrefrx0-0p9-supply + - vdda-qrefrx1-0p9-supply + - vdda-qrefrx2-0p9-supply + - vdda-qrefrx4-0p9-supply + - vdda-qrefrx5-0p9-supply + - vdda-qreftx0-0p9-supply + - vdda-qreftx0-1p2-supply + - vdda-qreftx1-0p9-supply + - vdda-refgen3-0p9-supply + - vdda-refgen3-1p2-supply + - vdda-refgen4-0p9-supply + - vdda-refgen4-1p2-supply + - if: + properties: + compatible: + contains: + const: qcom,mahua-tcsr + then: + required: + - vdda-qrefrpt0-0p9-supply + - vdda-qrefrpt1-0p9-supply + - vdda-qrefrpt2-0p9-supply + - vdda-qrefrpt3-0p9-supply + - vdda-qrefrpt4-0p9-supply + - vdda-qrefrpt5-0p9-supply + - vdda-qrefrx1-0p9-supply + - vdda-qrefrx2-0p9-supply + - vdda-qrefrx3-0p9-supply + - vdda-qreftx1-0p9-supply + - vdda-refgen3-0p9-supply + - vdda-refgen3-1p2-supply + +required: + - compatible + - clocks + +additionalProperties: false + +examples: + - | + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@1fd5000 { + compatible = "qcom,glymur-tcsr", "syscon"; + reg = <0x0 0x1fd5000 0x0 0x21000>; + clocks = <&rpmhcc RPMH_CXO_CLK>; + #clock-cells = <1>; + #reset-cells = <1>; + vdda-qrefrpt0-0p9-supply = <&vreg_l1a>; + vdda-qrefrpt1-0p9-supply = <&vreg_l1a>; + vdda-qrefrpt2-0p9-supply = <&vreg_l1a>; + vdda-qrefrpt3-0p9-supply = <&vreg_l1a>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1a>; + vdda-qrefrx0-0p9-supply = <&vreg_l1a>; + vdda-qrefrx1-0p9-supply = <&vreg_l1a>; + vdda-qrefrx2-0p9-supply = <&vreg_l1a>; + vdda-qrefrx4-0p9-supply = <&vreg_l1a>; + vdda-qrefrx5-0p9-supply = <&vreg_l1a>; + vdda-qreftx0-0p9-supply = <&vreg_l1a>; + vdda-qreftx0-1p2-supply = <&vreg_l2a>; + vdda-qreftx1-0p9-supply = <&vreg_l1a>; + vdda-refgen3-0p9-supply = <&vreg_l1a>; + vdda-refgen3-1p2-supply = <&vreg_l2a>; + vdda-refgen4-0p9-supply = <&vreg_l1a>; + vdda-refgen4-1p2-supply = <&vreg_l2a>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/clock/qcom,hawi-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,hawi-gcc.yaml index 4f428c0f7286..2101f4e4bb0d 100644 --- a/Documentation/devicetree/bindings/clock/qcom,hawi-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,hawi-gcc.yaml @@ -8,16 +8,21 @@ title: Qualcomm Global Clock & Reset Controller on Hawi maintainers: - Vivek Aknurwar + - Taniya Das description: | Qualcomm global clock control module provides the clocks, resets and power - domains on Hawi. + domains on Hawi and Maili. - See also: include/dt-bindings/clock/qcom,hawi-gcc.h + See also: + include/dt-bindings/clock/qcom,hawi-gcc.h + include/dt-bindings/clock/qcom,maili-gcc.h properties: compatible: - const: qcom,hawi-gcc + enum: + - qcom,hawi-gcc + - qcom,maili-gcc clocks: items: diff --git a/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml index 4a533b45eec2..8d4f53c8a6cb 100644 --- a/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml @@ -17,7 +17,13 @@ description: | properties: compatible: - const: qcom,qcm2290-dispcc + oneOf: + - items: + - enum: + - qcom,shikra-dispcc + - const: qcom,qcm2290-dispcc + - enum: + - qcom,qcm2290-dispcc clocks: items: @@ -37,10 +43,15 @@ properties: - const: dsi0_phy_pll_out_byteclk - const: dsi0_phy_pll_out_dsiclk + power-domains: + items: + - description: CX domain + required: - compatible - clocks - clock-names + - power-domains - '#power-domain-cells' allOf: @@ -53,6 +64,7 @@ examples: #include #include #include + #include clock-controller@5f00000 { compatible = "qcom,qcm2290-dispcc"; reg = <0x5f00000 0x20000>; @@ -68,6 +80,7 @@ examples: "gcc_disp_gpll0_div_clk_src", "dsi0_phy_pll_out_byteclk", "dsi0_phy_pll_out_dsiclk"; + power-domains = <&rpmpd RPMPD_VDDCX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml index bedbdabef672..ad2386190346 100644 --- a/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml @@ -18,7 +18,9 @@ description: | properties: compatible: - const: qcom,qcm2290-gpucc + enum: + - qcom,qcm2290-gpucc + - qcom,shikra-gpucc reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml index d344b3386042..2b446aca5207 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml @@ -16,36 +16,41 @@ description: | properties: compatible: - enum: - - qcom,eliza-rpmh-clk - - qcom,glymur-rpmh-clk - - qcom,hawi-rpmh-clk - - qcom,kaanapali-rpmh-clk - - qcom,milos-rpmh-clk - - qcom,nord-rpmh-clk - - qcom,qcs615-rpmh-clk - - qcom,qdu1000-rpmh-clk - - qcom,sa8775p-rpmh-clk - - qcom,sar2130p-rpmh-clk - - qcom,sc7180-rpmh-clk - - qcom,sc7280-rpmh-clk - - qcom,sc8180x-rpmh-clk - - qcom,sc8280xp-rpmh-clk - - qcom,sdm670-rpmh-clk - - qcom,sdm845-rpmh-clk - - qcom,sdx55-rpmh-clk - - qcom,sdx65-rpmh-clk - - qcom,sdx75-rpmh-clk - - qcom,sm4450-rpmh-clk - - qcom,sm6350-rpmh-clk - - qcom,sm8150-rpmh-clk - - qcom,sm8250-rpmh-clk - - qcom,sm8350-rpmh-clk - - qcom,sm8450-rpmh-clk - - qcom,sm8550-rpmh-clk - - qcom,sm8650-rpmh-clk - - qcom,sm8750-rpmh-clk - - qcom,x1e80100-rpmh-clk + oneOf: + - enum: + - qcom,eliza-rpmh-clk + - qcom,glymur-rpmh-clk + - qcom,hawi-rpmh-clk + - qcom,kaanapali-rpmh-clk + - qcom,milos-rpmh-clk + - qcom,nord-rpmh-clk + - qcom,qcs615-rpmh-clk + - qcom,qdu1000-rpmh-clk + - qcom,sa8775p-rpmh-clk + - qcom,sar2130p-rpmh-clk + - qcom,sc7180-rpmh-clk + - qcom,sc7280-rpmh-clk + - qcom,sc8180x-rpmh-clk + - qcom,sc8280xp-rpmh-clk + - qcom,sdm670-rpmh-clk + - qcom,sdm845-rpmh-clk + - qcom,sdx55-rpmh-clk + - qcom,sdx65-rpmh-clk + - qcom,sdx75-rpmh-clk + - qcom,sm4450-rpmh-clk + - qcom,sm6350-rpmh-clk + - qcom,sm8150-rpmh-clk + - qcom,sm8250-rpmh-clk + - qcom,sm8350-rpmh-clk + - qcom,sm8450-rpmh-clk + - qcom,sm8550-rpmh-clk + - qcom,sm8650-rpmh-clk + - qcom,sm8750-rpmh-clk + - qcom,x1e80100-rpmh-clk + - items: + - enum: + - qcom,maili-rpmh-clk + - const: qcom,hawi-rpmh-clk clocks: maxItems: 1 diff --git a/Documentation/devicetree/bindings/clock/qcom,shikra-audiocorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,shikra-audiocorecc.yaml new file mode 100644 index 000000000000..d59f7e47a0d7 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,shikra-audiocorecc.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,shikra-audiocorecc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Audio Core Clock Controller for Qualcomm Shikra SoC + +maintainers: + - Imran Shaik + +description: | + Audio core clock control module provides the clocks on Qualcomm Shikra + SoC platform. + + See also: + - include/dt-bindings/clock/qcom,shikra-audiocorecc.h + +properties: + compatible: + const: qcom,shikra-audiocorecc + + clocks: + items: + - description: Board XO source + - description: Board sleep clock + - description: Audio ref clock source + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + +required: + - compatible + - reg + - clocks + - '#clock-cells' + +additionalProperties: false + +examples: + - | + #include + #include + clock-controller@a0a0000 { + compatible = "qcom,shikra-audiocorecc"; + reg = <0x0a0a0000 0x10000>; + clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, + <&sleep_clk>, + <&aud_ref_clk_src>; + #clock-cells = <1>; + }; +... diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml index 8492a7ef7324..b41247b257b1 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml @@ -70,13 +70,11 @@ allOf: - if: properties: compatible: - contains: - enum: - - qcom,kaanapali-cambistmclkcc - - qcom,kaanapali-camcc - - qcom,sc8280xp-camcc - - qcom,sm8450-camcc - - qcom,sm8550-camcc + not: + contains: + enum: + - qcom,sm8475-camcc + - qcom,sm8650-camcc then: required: - required-opps diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml index fdbdf605ee69..2a2d37c59442 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml @@ -18,6 +18,8 @@ description: | include/dt-bindings/clock/qcom,glymur-gpucc.h include/dt-bindings/clock/qcom,kaanapali-gpucc.h include/dt-bindings/clock/qcom,milos-gpucc.h + include/dt-bindings/clock/qcom,nord-gpu2cc.h + include/dt-bindings/clock/qcom,nord-gpucc.h include/dt-bindings/clock/qcom,sar2130p-gpucc.h include/dt-bindings/clock/qcom,sm4450-gpucc.h include/dt-bindings/clock/qcom,sm8450-gpucc.h @@ -33,6 +35,8 @@ properties: - qcom,glymur-gpucc - qcom,kaanapali-gpucc - qcom,milos-gpucc + - qcom,nord-gpu2cc + - qcom,nord-gpucc - qcom,sar2130p-gpucc - qcom,sm4450-gpucc - qcom,sm8450-gpucc diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml index 5d77029bfaf8..910c6d5672b8 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml @@ -16,7 +16,9 @@ description: | See also: include/dt-bindings/clock/qcom,glymur-videocc.h + include/dt-bindings/clock/qcom,hawi-videocc.h include/dt-bindings/clock/qcom,kaanapali-videocc.h + include/dt-bindings/clock/qcom,maili-videocc.h include/dt-bindings/clock/qcom,sm8450-videocc.h include/dt-bindings/clock/qcom,sm8650-videocc.h include/dt-bindings/clock/qcom,sm8750-videocc.h @@ -26,7 +28,9 @@ properties: compatible: enum: - qcom,glymur-videocc + - qcom,hawi-videocc - qcom,kaanapali-videocc + - qcom,maili-videocc - qcom,sm8450-videocc - qcom,sm8475-videocc - qcom,sm8550-videocc @@ -65,14 +69,11 @@ allOf: - if: properties: compatible: - contains: - enum: - - qcom,glymur-videocc - - qcom,kaanapali-videocc - - qcom,sm8450-videocc - - qcom,sm8550-videocc - - qcom,sm8750-videocc - - qcom,x1p42100-videocc + not: + contains: + enum: + - qcom,sm8475-videocc + - qcom,sm8650-videocc then: required: - required-opps diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml index 591ce91b8d54..61f58fbd5bd2 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml @@ -16,6 +16,7 @@ description: | See also: - include/dt-bindings/clock/qcom,kaanapali-dispcc.h + - include/dt-bindings/clock/qcom,nord-dispcc.h - include/dt-bindings/clock/qcom,sm8550-dispcc.h - include/dt-bindings/clock/qcom,sm8650-dispcc.h - include/dt-bindings/clock/qcom,sm8750-dispcc.h @@ -25,6 +26,8 @@ properties: compatible: enum: - qcom,kaanapali-dispcc + - qcom,nord-dispcc0 + - qcom,nord-dispcc1 - qcom,sar2130p-dispcc - qcom,sm8550-dispcc - qcom,sm8650-dispcc diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml index 08824f848973..1f3332275c17 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml @@ -16,7 +16,6 @@ description: | See also: - include/dt-bindings/clock/qcom,eliza-tcsr.h - - include/dt-bindings/clock/qcom,glymur-tcsr.h - include/dt-bindings/clock/qcom,hawi-tcsrcc.h - include/dt-bindings/clock/qcom,nord-tcsrcc.h - include/dt-bindings/clock/qcom,sm8550-tcsr.h @@ -25,20 +24,25 @@ description: | properties: compatible: - items: - - enum: - - qcom,eliza-tcsr - - qcom,glymur-tcsr - - qcom,hawi-tcsrcc - - qcom,kaanapali-tcsr - - qcom,milos-tcsr - - qcom,nord-tcsrcc - - qcom,sar2130p-tcsr - - qcom,sm8550-tcsr - - qcom,sm8650-tcsr - - qcom,sm8750-tcsr - - qcom,x1e80100-tcsr - - const: syscon + oneOf: + - items: + - enum: + - qcom,eliza-tcsr + - qcom,hawi-tcsrcc + - qcom,kaanapali-tcsr + - qcom,milos-tcsr + - qcom,nord-tcsrcc + - qcom,sar2130p-tcsr + - qcom,sm8550-tcsr + - qcom,sm8650-tcsr + - qcom,sm8750-tcsr + - qcom,x1e80100-tcsr + - const: syscon + - items: + - enum: + - qcom,maili-tcsrcc + - const: qcom,hawi-tcsrcc + - const: syscon clocks: items: diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a78000-cpg.yaml b/Documentation/devicetree/bindings/clock/renesas,r8a78000-cpg.yaml new file mode 100644 index 000000000000..4e23bba33438 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,r8a78000-cpg.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/renesas,r8a78000-cpg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas R-Car X5H Clock Pulse Generator + +maintainers: + - Geert Uytterhoeven + +description: + The R-Car X5H Clock Pulse Generator (CLK CONTROL) consists of oscillators, + PLL circuits, clock dividers and clock control circuits. It provides various + clocks for other modules. + +properties: + compatible: + const: renesas,r8a78000-cpg + + reg: + maxItems: 1 + + clocks: + maxItems: 2 + + clock-names: + items: + - const: extal + - const: extalr + + '#clock-cells': + description: + The single clock specifier cell must be the clock number, as defined in + . + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + +additionalProperties: false + +examples: + - | + clock-controller@c1320000 { + compatible = "renesas,r8a78000-cpg"; + reg = <0xc1320000 0x10000>; + clocks = <&extal_clk>, <&extalr_clk>; + clock-names = "extal", "extalr"; + #clock-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/clock/renesas,rzv2h-cpg.yaml b/Documentation/devicetree/bindings/clock/renesas,rzv2h-cpg.yaml index f261445bf341..dd3e66a4559b 100644 --- a/Documentation/devicetree/bindings/clock/renesas,rzv2h-cpg.yaml +++ b/Documentation/devicetree/bindings/clock/renesas,rzv2h-cpg.yaml @@ -26,16 +26,22 @@ properties: maxItems: 1 clocks: + minItems: 3 items: - description: AUDIO_EXTAL clock input - description: RTXIN clock input - description: QEXTAL clock input + - description: AUDIO_CLKB clock input + - description: AUDIO_CLKC clock input clock-names: + minItems: 3 items: - const: audio_extal - const: rtxin - const: qextal + - const: audio_clkb + - const: audio_clkc '#clock-cells': description: | diff --git a/Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml b/Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml index b339f1f9f072..990d287d0a90 100644 --- a/Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml +++ b/Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Renesas Versaclock7 Programmable Clock maintainers: - - Alex Helms + - Biju Das description: | Renesas Versaclock7 is a family of configurable clock generator and diff --git a/Documentation/devicetree/bindings/clock/rockchip,rv1106-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rv1106-cru.yaml new file mode 100644 index 000000000000..b99dce9ff935 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/rockchip,rv1106-cru.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/rockchip,rv1106-cru.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip RV1106 Clock and Reset Unit + +maintainers: + - Simon Glass + - Heiko Stuebner + +description: + The RV1106 clock controller generates the clock and also implements a + reset controller for SoC peripherals. + +properties: + compatible: + const: rockchip,rv1106-cru + + reg: + maxItems: 1 + + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + + clocks: + maxItems: 1 + + clock-names: + const: xin24m + + rockchip,grf: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to the syscon managing the "general register files" (GRF). + If missing, pll rates are not changeable due to the missing pll + lock status, and the MMC drive and sample phase clocks, whose + control registers live in the GRF region, are not registered. + +required: + - compatible + - reg + - "#clock-cells" + - "#reset-cells" + +additionalProperties: false + +examples: + - | + clock-controller@ff3b0000 { + compatible = "rockchip,rv1106-cru"; + reg = <0xff3b0000 0x20000>; + rockchip,grf = <&grf>; + #clock-cells = <1>; + #reset-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/clock/silabs,si544.yaml b/Documentation/devicetree/bindings/clock/silabs,si544.yaml index f87e71867108..218f5abdef26 100644 --- a/Documentation/devicetree/bindings/clock/silabs,si544.yaml +++ b/Documentation/devicetree/bindings/clock/silabs,si544.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/clock/silabs,si544.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Silicon Labs SI514/SI544 clock generator +title: Silicon Labs SI514/SI544/SI549 clock generator maintainers: - Mike Looijmans @@ -13,8 +13,9 @@ description: > Silicon Labs 514/544 programmable I2C clock generator. Details about the device can be found in the datasheet: - https://www.silabs.com/Support%20Documents/TechnicalDocs/si514.pdf - https://www.silabs.com/documents/public/data-sheets/si544-datasheet.pdf + https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/data-sheets/Si514.pdf + https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/data-sheets/si544-datasheet.pdf + https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/data-sheets/si549-datasheet.pdf properties: compatible: @@ -23,6 +24,9 @@ properties: - silabs,si544a - silabs,si544b - silabs,si544c + - silabs,si549a + - silabs,si549b + - silabs,si549c reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/clock/st,stm32mp21-rcc.yaml b/Documentation/devicetree/bindings/clock/st,stm32mp21-rcc.yaml index 4368063c6709..e4d64d4b63c6 100644 --- a/Documentation/devicetree/bindings/clock/st,stm32mp21-rcc.yaml +++ b/Documentation/devicetree/bindings/clock/st,stm32mp21-rcc.yaml @@ -125,75 +125,75 @@ examples: reg = <0x44200000 0x10000>; #clock-cells = <1>; #reset-cells = <1>; - clocks = <&scmi_clk CK_SCMI_HSE>, - <&scmi_clk CK_SCMI_HSI>, - <&scmi_clk CK_SCMI_MSI>, - <&scmi_clk CK_SCMI_LSE>, - <&scmi_clk CK_SCMI_LSI>, - <&scmi_clk CK_SCMI_HSE_DIV2>, - <&scmi_clk CK_SCMI_ICN_HS_MCU>, - <&scmi_clk CK_SCMI_ICN_LS_MCU>, - <&scmi_clk CK_SCMI_ICN_SDMMC>, - <&scmi_clk CK_SCMI_ICN_DDR>, - <&scmi_clk CK_SCMI_ICN_DISPLAY>, - <&scmi_clk CK_SCMI_ICN_HSL>, - <&scmi_clk CK_SCMI_ICN_NIC>, - <&scmi_clk CK_SCMI_FLEXGEN_07>, - <&scmi_clk CK_SCMI_FLEXGEN_08>, - <&scmi_clk CK_SCMI_FLEXGEN_09>, - <&scmi_clk CK_SCMI_FLEXGEN_10>, - <&scmi_clk CK_SCMI_FLEXGEN_11>, - <&scmi_clk CK_SCMI_FLEXGEN_12>, - <&scmi_clk CK_SCMI_FLEXGEN_13>, - <&scmi_clk CK_SCMI_FLEXGEN_14>, - <&scmi_clk CK_SCMI_FLEXGEN_16>, - <&scmi_clk CK_SCMI_FLEXGEN_17>, - <&scmi_clk CK_SCMI_FLEXGEN_18>, - <&scmi_clk CK_SCMI_FLEXGEN_19>, - <&scmi_clk CK_SCMI_FLEXGEN_20>, - <&scmi_clk CK_SCMI_FLEXGEN_21>, - <&scmi_clk CK_SCMI_FLEXGEN_22>, - <&scmi_clk CK_SCMI_FLEXGEN_23>, - <&scmi_clk CK_SCMI_FLEXGEN_24>, - <&scmi_clk CK_SCMI_FLEXGEN_25>, - <&scmi_clk CK_SCMI_FLEXGEN_26>, - <&scmi_clk CK_SCMI_FLEXGEN_27>, - <&scmi_clk CK_SCMI_FLEXGEN_29>, - <&scmi_clk CK_SCMI_FLEXGEN_30>, - <&scmi_clk CK_SCMI_FLEXGEN_31>, - <&scmi_clk CK_SCMI_FLEXGEN_33>, - <&scmi_clk CK_SCMI_FLEXGEN_36>, - <&scmi_clk CK_SCMI_FLEXGEN_37>, - <&scmi_clk CK_SCMI_FLEXGEN_38>, - <&scmi_clk CK_SCMI_FLEXGEN_39>, - <&scmi_clk CK_SCMI_FLEXGEN_40>, - <&scmi_clk CK_SCMI_FLEXGEN_41>, - <&scmi_clk CK_SCMI_FLEXGEN_42>, - <&scmi_clk CK_SCMI_FLEXGEN_43>, - <&scmi_clk CK_SCMI_FLEXGEN_44>, - <&scmi_clk CK_SCMI_FLEXGEN_45>, - <&scmi_clk CK_SCMI_FLEXGEN_46>, - <&scmi_clk CK_SCMI_FLEXGEN_47>, - <&scmi_clk CK_SCMI_FLEXGEN_48>, - <&scmi_clk CK_SCMI_FLEXGEN_50>, - <&scmi_clk CK_SCMI_FLEXGEN_51>, - <&scmi_clk CK_SCMI_FLEXGEN_52>, - <&scmi_clk CK_SCMI_FLEXGEN_53>, - <&scmi_clk CK_SCMI_FLEXGEN_54>, - <&scmi_clk CK_SCMI_FLEXGEN_55>, - <&scmi_clk CK_SCMI_FLEXGEN_56>, - <&scmi_clk CK_SCMI_FLEXGEN_57>, - <&scmi_clk CK_SCMI_FLEXGEN_58>, - <&scmi_clk CK_SCMI_FLEXGEN_61>, - <&scmi_clk CK_SCMI_FLEXGEN_62>, - <&scmi_clk CK_SCMI_FLEXGEN_63>, - <&scmi_clk CK_SCMI_ICN_APB1>, - <&scmi_clk CK_SCMI_ICN_APB2>, - <&scmi_clk CK_SCMI_ICN_APB3>, - <&scmi_clk CK_SCMI_ICN_APB4>, - <&scmi_clk CK_SCMI_ICN_APB5>, - <&scmi_clk CK_SCMI_ICN_APBDBG>, - <&scmi_clk CK_SCMI_TIMG1>, - <&scmi_clk CK_SCMI_TIMG2>; + clocks = <&scmi_clk CK_SCMI_HSE>, + <&scmi_clk CK_SCMI_HSI>, + <&scmi_clk CK_SCMI_MSI>, + <&scmi_clk CK_SCMI_LSE>, + <&scmi_clk CK_SCMI_LSI>, + <&scmi_clk CK_SCMI_HSE_DIV2>, + <&scmi_clk CK_SCMI_ICN_HS_MCU>, + <&scmi_clk CK_SCMI_ICN_LS_MCU>, + <&scmi_clk CK_SCMI_ICN_SDMMC>, + <&scmi_clk CK_SCMI_ICN_DDR>, + <&scmi_clk CK_SCMI_ICN_DISPLAY>, + <&scmi_clk CK_SCMI_ICN_HSL>, + <&scmi_clk CK_SCMI_ICN_NIC>, + <&scmi_clk CK_SCMI_FLEXGEN_07>, + <&scmi_clk CK_SCMI_FLEXGEN_08>, + <&scmi_clk CK_SCMI_FLEXGEN_09>, + <&scmi_clk CK_SCMI_FLEXGEN_10>, + <&scmi_clk CK_SCMI_FLEXGEN_11>, + <&scmi_clk CK_SCMI_FLEXGEN_12>, + <&scmi_clk CK_SCMI_FLEXGEN_13>, + <&scmi_clk CK_SCMI_FLEXGEN_14>, + <&scmi_clk CK_SCMI_FLEXGEN_16>, + <&scmi_clk CK_SCMI_FLEXGEN_17>, + <&scmi_clk CK_SCMI_FLEXGEN_18>, + <&scmi_clk CK_SCMI_FLEXGEN_19>, + <&scmi_clk CK_SCMI_FLEXGEN_20>, + <&scmi_clk CK_SCMI_FLEXGEN_21>, + <&scmi_clk CK_SCMI_FLEXGEN_22>, + <&scmi_clk CK_SCMI_FLEXGEN_23>, + <&scmi_clk CK_SCMI_FLEXGEN_24>, + <&scmi_clk CK_SCMI_FLEXGEN_25>, + <&scmi_clk CK_SCMI_FLEXGEN_26>, + <&scmi_clk CK_SCMI_FLEXGEN_27>, + <&scmi_clk CK_SCMI_FLEXGEN_29>, + <&scmi_clk CK_SCMI_FLEXGEN_30>, + <&scmi_clk CK_SCMI_FLEXGEN_31>, + <&scmi_clk CK_SCMI_FLEXGEN_33>, + <&scmi_clk CK_SCMI_FLEXGEN_36>, + <&scmi_clk CK_SCMI_FLEXGEN_37>, + <&scmi_clk CK_SCMI_FLEXGEN_38>, + <&scmi_clk CK_SCMI_FLEXGEN_39>, + <&scmi_clk CK_SCMI_FLEXGEN_40>, + <&scmi_clk CK_SCMI_FLEXGEN_41>, + <&scmi_clk CK_SCMI_FLEXGEN_42>, + <&scmi_clk CK_SCMI_FLEXGEN_43>, + <&scmi_clk CK_SCMI_FLEXGEN_44>, + <&scmi_clk CK_SCMI_FLEXGEN_45>, + <&scmi_clk CK_SCMI_FLEXGEN_46>, + <&scmi_clk CK_SCMI_FLEXGEN_47>, + <&scmi_clk CK_SCMI_FLEXGEN_48>, + <&scmi_clk CK_SCMI_FLEXGEN_50>, + <&scmi_clk CK_SCMI_FLEXGEN_51>, + <&scmi_clk CK_SCMI_FLEXGEN_52>, + <&scmi_clk CK_SCMI_FLEXGEN_53>, + <&scmi_clk CK_SCMI_FLEXGEN_54>, + <&scmi_clk CK_SCMI_FLEXGEN_55>, + <&scmi_clk CK_SCMI_FLEXGEN_56>, + <&scmi_clk CK_SCMI_FLEXGEN_57>, + <&scmi_clk CK_SCMI_FLEXGEN_58>, + <&scmi_clk CK_SCMI_FLEXGEN_61>, + <&scmi_clk CK_SCMI_FLEXGEN_62>, + <&scmi_clk CK_SCMI_FLEXGEN_63>, + <&scmi_clk CK_SCMI_ICN_APB1>, + <&scmi_clk CK_SCMI_ICN_APB2>, + <&scmi_clk CK_SCMI_ICN_APB3>, + <&scmi_clk CK_SCMI_ICN_APB4>, + <&scmi_clk CK_SCMI_ICN_APB5>, + <&scmi_clk CK_SCMI_ICN_APBDBG>, + <&scmi_clk CK_SCMI_TIMG1>, + <&scmi_clk CK_SCMI_TIMG2>; }; ... diff --git a/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml b/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml index 1e3b5d218bb0..3b7925d2c175 100644 --- a/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml +++ b/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml @@ -135,85 +135,85 @@ examples: reg = <0x44200000 0x10000>; #clock-cells = <1>; #reset-cells = <1>; - clocks = <&scmi_clk CK_SCMI_HSE>, - <&scmi_clk CK_SCMI_HSI>, - <&scmi_clk CK_SCMI_MSI>, - <&scmi_clk CK_SCMI_LSE>, - <&scmi_clk CK_SCMI_LSI>, - <&scmi_clk CK_SCMI_HSE_DIV2>, - <&scmi_clk CK_SCMI_ICN_HS_MCU>, - <&scmi_clk CK_SCMI_ICN_LS_MCU>, - <&scmi_clk CK_SCMI_ICN_SDMMC>, - <&scmi_clk CK_SCMI_ICN_DDR>, - <&scmi_clk CK_SCMI_ICN_DISPLAY>, - <&scmi_clk CK_SCMI_ICN_HSL>, - <&scmi_clk CK_SCMI_ICN_NIC>, - <&scmi_clk CK_SCMI_ICN_VID>, - <&scmi_clk CK_SCMI_FLEXGEN_07>, - <&scmi_clk CK_SCMI_FLEXGEN_08>, - <&scmi_clk CK_SCMI_FLEXGEN_09>, - <&scmi_clk CK_SCMI_FLEXGEN_10>, - <&scmi_clk CK_SCMI_FLEXGEN_11>, - <&scmi_clk CK_SCMI_FLEXGEN_12>, - <&scmi_clk CK_SCMI_FLEXGEN_13>, - <&scmi_clk CK_SCMI_FLEXGEN_14>, - <&scmi_clk CK_SCMI_FLEXGEN_15>, - <&scmi_clk CK_SCMI_FLEXGEN_16>, - <&scmi_clk CK_SCMI_FLEXGEN_17>, - <&scmi_clk CK_SCMI_FLEXGEN_18>, - <&scmi_clk CK_SCMI_FLEXGEN_19>, - <&scmi_clk CK_SCMI_FLEXGEN_20>, - <&scmi_clk CK_SCMI_FLEXGEN_21>, - <&scmi_clk CK_SCMI_FLEXGEN_22>, - <&scmi_clk CK_SCMI_FLEXGEN_23>, - <&scmi_clk CK_SCMI_FLEXGEN_24>, - <&scmi_clk CK_SCMI_FLEXGEN_25>, - <&scmi_clk CK_SCMI_FLEXGEN_26>, - <&scmi_clk CK_SCMI_FLEXGEN_27>, - <&scmi_clk CK_SCMI_FLEXGEN_28>, - <&scmi_clk CK_SCMI_FLEXGEN_29>, - <&scmi_clk CK_SCMI_FLEXGEN_30>, - <&scmi_clk CK_SCMI_FLEXGEN_31>, - <&scmi_clk CK_SCMI_FLEXGEN_32>, - <&scmi_clk CK_SCMI_FLEXGEN_33>, - <&scmi_clk CK_SCMI_FLEXGEN_34>, - <&scmi_clk CK_SCMI_FLEXGEN_35>, - <&scmi_clk CK_SCMI_FLEXGEN_36>, - <&scmi_clk CK_SCMI_FLEXGEN_37>, - <&scmi_clk CK_SCMI_FLEXGEN_38>, - <&scmi_clk CK_SCMI_FLEXGEN_39>, - <&scmi_clk CK_SCMI_FLEXGEN_40>, - <&scmi_clk CK_SCMI_FLEXGEN_41>, - <&scmi_clk CK_SCMI_FLEXGEN_42>, - <&scmi_clk CK_SCMI_FLEXGEN_43>, - <&scmi_clk CK_SCMI_FLEXGEN_44>, - <&scmi_clk CK_SCMI_FLEXGEN_45>, - <&scmi_clk CK_SCMI_FLEXGEN_46>, - <&scmi_clk CK_SCMI_FLEXGEN_47>, - <&scmi_clk CK_SCMI_FLEXGEN_48>, - <&scmi_clk CK_SCMI_FLEXGEN_49>, - <&scmi_clk CK_SCMI_FLEXGEN_50>, - <&scmi_clk CK_SCMI_FLEXGEN_51>, - <&scmi_clk CK_SCMI_FLEXGEN_52>, - <&scmi_clk CK_SCMI_FLEXGEN_53>, - <&scmi_clk CK_SCMI_FLEXGEN_54>, - <&scmi_clk CK_SCMI_FLEXGEN_55>, - <&scmi_clk CK_SCMI_FLEXGEN_56>, - <&scmi_clk CK_SCMI_FLEXGEN_57>, - <&scmi_clk CK_SCMI_FLEXGEN_58>, - <&scmi_clk CK_SCMI_FLEXGEN_59>, - <&scmi_clk CK_SCMI_FLEXGEN_60>, - <&scmi_clk CK_SCMI_FLEXGEN_61>, - <&scmi_clk CK_SCMI_FLEXGEN_62>, - <&scmi_clk CK_SCMI_FLEXGEN_63>, - <&scmi_clk CK_SCMI_ICN_APB1>, - <&scmi_clk CK_SCMI_ICN_APB2>, - <&scmi_clk CK_SCMI_ICN_APB3>, - <&scmi_clk CK_SCMI_ICN_APB4>, - <&scmi_clk CK_SCMI_ICN_APBDBG>, - <&scmi_clk CK_SCMI_TIMG1>, - <&scmi_clk CK_SCMI_TIMG2>, - <&scmi_clk CK_SCMI_PLL3>, - <&clk_dsi_txbyte>; + clocks = <&scmi_clk CK_SCMI_HSE>, + <&scmi_clk CK_SCMI_HSI>, + <&scmi_clk CK_SCMI_MSI>, + <&scmi_clk CK_SCMI_LSE>, + <&scmi_clk CK_SCMI_LSI>, + <&scmi_clk CK_SCMI_HSE_DIV2>, + <&scmi_clk CK_SCMI_ICN_HS_MCU>, + <&scmi_clk CK_SCMI_ICN_LS_MCU>, + <&scmi_clk CK_SCMI_ICN_SDMMC>, + <&scmi_clk CK_SCMI_ICN_DDR>, + <&scmi_clk CK_SCMI_ICN_DISPLAY>, + <&scmi_clk CK_SCMI_ICN_HSL>, + <&scmi_clk CK_SCMI_ICN_NIC>, + <&scmi_clk CK_SCMI_ICN_VID>, + <&scmi_clk CK_SCMI_FLEXGEN_07>, + <&scmi_clk CK_SCMI_FLEXGEN_08>, + <&scmi_clk CK_SCMI_FLEXGEN_09>, + <&scmi_clk CK_SCMI_FLEXGEN_10>, + <&scmi_clk CK_SCMI_FLEXGEN_11>, + <&scmi_clk CK_SCMI_FLEXGEN_12>, + <&scmi_clk CK_SCMI_FLEXGEN_13>, + <&scmi_clk CK_SCMI_FLEXGEN_14>, + <&scmi_clk CK_SCMI_FLEXGEN_15>, + <&scmi_clk CK_SCMI_FLEXGEN_16>, + <&scmi_clk CK_SCMI_FLEXGEN_17>, + <&scmi_clk CK_SCMI_FLEXGEN_18>, + <&scmi_clk CK_SCMI_FLEXGEN_19>, + <&scmi_clk CK_SCMI_FLEXGEN_20>, + <&scmi_clk CK_SCMI_FLEXGEN_21>, + <&scmi_clk CK_SCMI_FLEXGEN_22>, + <&scmi_clk CK_SCMI_FLEXGEN_23>, + <&scmi_clk CK_SCMI_FLEXGEN_24>, + <&scmi_clk CK_SCMI_FLEXGEN_25>, + <&scmi_clk CK_SCMI_FLEXGEN_26>, + <&scmi_clk CK_SCMI_FLEXGEN_27>, + <&scmi_clk CK_SCMI_FLEXGEN_28>, + <&scmi_clk CK_SCMI_FLEXGEN_29>, + <&scmi_clk CK_SCMI_FLEXGEN_30>, + <&scmi_clk CK_SCMI_FLEXGEN_31>, + <&scmi_clk CK_SCMI_FLEXGEN_32>, + <&scmi_clk CK_SCMI_FLEXGEN_33>, + <&scmi_clk CK_SCMI_FLEXGEN_34>, + <&scmi_clk CK_SCMI_FLEXGEN_35>, + <&scmi_clk CK_SCMI_FLEXGEN_36>, + <&scmi_clk CK_SCMI_FLEXGEN_37>, + <&scmi_clk CK_SCMI_FLEXGEN_38>, + <&scmi_clk CK_SCMI_FLEXGEN_39>, + <&scmi_clk CK_SCMI_FLEXGEN_40>, + <&scmi_clk CK_SCMI_FLEXGEN_41>, + <&scmi_clk CK_SCMI_FLEXGEN_42>, + <&scmi_clk CK_SCMI_FLEXGEN_43>, + <&scmi_clk CK_SCMI_FLEXGEN_44>, + <&scmi_clk CK_SCMI_FLEXGEN_45>, + <&scmi_clk CK_SCMI_FLEXGEN_46>, + <&scmi_clk CK_SCMI_FLEXGEN_47>, + <&scmi_clk CK_SCMI_FLEXGEN_48>, + <&scmi_clk CK_SCMI_FLEXGEN_49>, + <&scmi_clk CK_SCMI_FLEXGEN_50>, + <&scmi_clk CK_SCMI_FLEXGEN_51>, + <&scmi_clk CK_SCMI_FLEXGEN_52>, + <&scmi_clk CK_SCMI_FLEXGEN_53>, + <&scmi_clk CK_SCMI_FLEXGEN_54>, + <&scmi_clk CK_SCMI_FLEXGEN_55>, + <&scmi_clk CK_SCMI_FLEXGEN_56>, + <&scmi_clk CK_SCMI_FLEXGEN_57>, + <&scmi_clk CK_SCMI_FLEXGEN_58>, + <&scmi_clk CK_SCMI_FLEXGEN_59>, + <&scmi_clk CK_SCMI_FLEXGEN_60>, + <&scmi_clk CK_SCMI_FLEXGEN_61>, + <&scmi_clk CK_SCMI_FLEXGEN_62>, + <&scmi_clk CK_SCMI_FLEXGEN_63>, + <&scmi_clk CK_SCMI_ICN_APB1>, + <&scmi_clk CK_SCMI_ICN_APB2>, + <&scmi_clk CK_SCMI_ICN_APB3>, + <&scmi_clk CK_SCMI_ICN_APB4>, + <&scmi_clk CK_SCMI_ICN_APBDBG>, + <&scmi_clk CK_SCMI_TIMG1>, + <&scmi_clk CK_SCMI_TIMG2>, + <&scmi_clk CK_SCMI_PLL3>, + <&clk_dsi_txbyte>; }; ... diff --git a/Documentation/devicetree/bindings/clock/ti,keystone,psc-clock.yaml b/Documentation/devicetree/bindings/clock/ti,keystone,psc-clock.yaml new file mode 100644 index 000000000000..ed42adb27832 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti,keystone,psc-clock.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ti,keystone,psc-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI Keystone PSC clock + +maintainers: + - Santosh Shilimkar + - Murali Karicheri + +properties: + compatible: + const: ti,keystone,psc-clock + + reg: + items: + - description: PSC control + - description: Domain + + reg-names: + items: + - const: control + - const: domain + + domain-id: + $ref: /schemas/types.yaml#/definitions/uint32 + description: PSC domain id needed to check the transition state register + + clocks: + maxItems: 1 + + clock-output-names: + maxItems: 1 + + "#clock-cells": + const: 0 + +required: + - compatible + - reg + - reg-names + - domain-id + - clocks + - "#clock-cells" + +additionalProperties: false + +examples: + - | + clkusb@2350008 { + compatible = "ti,keystone,psc-clock"; + reg = <0x02350008 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + clocks = <&chipclk16>; + clock-output-names = "usb"; + #clock-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/clock/ti/apll.txt b/Documentation/devicetree/bindings/clock/ti/apll.txt deleted file mode 100644 index bbd505c1199d..000000000000 --- a/Documentation/devicetree/bindings/clock/ti/apll.txt +++ /dev/null @@ -1,43 +0,0 @@ -Binding for Texas Instruments APLL clock. - -This binding uses the common clock binding[1]. It assumes a -register-mapped APLL with usually two selectable input clocks -(reference clock and bypass clock), with analog phase locked -loop logic for multiplying the input clock to a desired output -clock. This clock also typically supports different operation -modes (locked, low power stop etc.) APLL mostly behaves like -a subtype of a DPLL [2], although a simplified one at that. - -[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -[2] Documentation/devicetree/bindings/clock/ti/dpll.txt - -Required properties: -- compatible : shall be "ti,dra7-apll-clock" or "ti,omap2-apll-clock" -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : link phandles of parent clocks (clk-ref and clk-bypass) -- reg : address and length of the register set for controlling the APLL. - It contains the information of registers in the following order: - "control" - contains the control register offset - "idlest" - contains the idlest register offset - "autoidle" - contains the autoidle register offset (OMAP2 only) -- ti,clock-frequency : static clock frequency for the clock (OMAP2 only) -- ti,idlest-shift : bit-shift for the idlest field (OMAP2 only) -- ti,bit-shift : bit-shift for enable and autoidle fields (OMAP2 only) - -Examples: - apll_pcie_ck: apll_pcie_ck { - #clock-cells = <0>; - clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>; - reg = <0x021c>, <0x0220>; - compatible = "ti,dra7-apll-clock"; - }; - - apll96_ck: apll96_ck { - #clock-cells = <0>; - compatible = "ti,omap2-apll-clock"; - clocks = <&sys_ck>; - ti,bit-shift = <2>; - ti,idlest-shift = <8>; - ti,clock-frequency = <96000000>; - reg = <0x0500>, <0x0530>, <0x0520>; - }; diff --git a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt deleted file mode 100644 index edf0b5d42768..000000000000 --- a/Documentation/devicetree/bindings/clock/ti/clockdomain.txt +++ /dev/null @@ -1,25 +0,0 @@ -Binding for Texas Instruments clockdomain. - -This binding uses the common clock binding[1] in consumer role. -Every clock on TI SoC belongs to one clockdomain, but software -only needs this information for specific clocks which require -their parent clockdomain to be controlled when the clock is -enabled/disabled. This binding doesn't define a new clock -binding type, it is used to group existing clock nodes under -hardware hierarchy. - -[1] Documentation/devicetree/bindings/clock/clock-bindings.txt - -Required properties: -- compatible : shall be "ti,clockdomain" -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : link phandles of clocks within this domain - -Optional properties: -- clock-output-names : from common clock binding. - -Examples: - dss_clkdm: dss_clkdm { - compatible = "ti,clockdomain"; - clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>; - }; diff --git a/Documentation/devicetree/bindings/clock/ti/ti,apll-clock.yaml b/Documentation/devicetree/bindings/clock/ti/ti,apll-clock.yaml new file mode 100644 index 000000000000..e14a76254ce7 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti/ti,apll-clock.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ti/ti,apll-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments APLL clock + +maintainers: + - Eduard Bostina + +allOf: + - $ref: /schemas/clock/clock.yaml# + +description: + This binding assumes a register-mapped APLL with usually two selectable + input clocks (reference clock and bypass clock), with analog phase locked + loop logic for multiplying the input clock to a desired output clock. + This clock also typically supports different operation modes (locked, low + power stop etc.) APLL mostly behaves like a subtype of a DPLL, although + a simplified one at that. + +properties: + compatible: + enum: + - ti,dra7-apll-clock + - ti,omap2-apll-clock + + "#clock-cells": + const: 0 + + clocks: + minItems: 1 + maxItems: 2 + description: Link phandles of parent clocks (clk-ref and clk-bypass) + + reg: + minItems: 2 + maxItems: 3 + description: | + Address and length of the register set for controlling the APLL. + It contains the information of registers in the following order: + "control" - contains the control register offset + "idlest" - contains the idlest register offset + "autoidle" - contains the autoidle register offset (OMAP2 only) + + ti,clock-frequency: + $ref: /schemas/types.yaml#/definitions/uint32 + description: static clock frequency for the clock (OMAP2 only) + + ti,idlest-shift: + $ref: /schemas/types.yaml#/definitions/uint32 + description: bit-shift for the idlest field (OMAP2 only) + + ti,bit-shift: + $ref: /schemas/types.yaml#/definitions/uint32 + description: bit-shift for enable and autoidle fields (OMAP2 only) + +required: + - compatible + - "#clock-cells" + - clocks + - reg + +unevaluatedProperties: false + +examples: + - | + bus { + #address-cells = <1>; + #size-cells = <0>; + + clock@21c { + #clock-cells = <0>; + compatible = "ti,dra7-apll-clock"; + clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>; + reg = <0x021c>, <0x0220>; + }; + + clock@500 { + #clock-cells = <0>; + compatible = "ti,omap2-apll-clock"; + clocks = <&sys_ck>; + ti,bit-shift = <2>; + ti,idlest-shift = <8>; + ti,clock-frequency = <96000000>; + reg = <0x0500>, <0x0530>, <0x0520>; + }; + }; diff --git a/Documentation/devicetree/bindings/clock/ti/ti,clockdomain.yaml b/Documentation/devicetree/bindings/clock/ti/ti,clockdomain.yaml new file mode 100644 index 000000000000..95746bfdced4 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti/ti,clockdomain.yaml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ti/ti,clockdomain.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments clockdomain + +maintainers: + - Tero Kristo + +description: + This binding uses the common clock binding in consumer role. Every clock on TI + SoC belongs to one clockdomain, but software only needs this information for + specific clocks which require their parent clockdomain to be controlled when + the clock is enabled/disabled. This binding doesn't define a new clock binding + type, it is used to group existing clock nodes under hardware hierarchy. + +properties: + compatible: + const: ti,clockdomain + + "#clock-cells": + const: 0 + + clocks: + minItems: 1 + maxItems: 64 + + clock-output-names: + maxItems: 1 + +required: + - compatible + - clocks + +additionalProperties: false + +examples: + - | + dss_clkdm { + compatible = "ti,clockdomain"; + clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>; + }; diff --git a/Documentation/devicetree/bindings/clock/ti/ti,gate-clock.yaml b/Documentation/devicetree/bindings/clock/ti/ti,gate-clock.yaml index eaa727ab0d7f..438e190d1067 100644 --- a/Documentation/devicetree/bindings/clock/ti/ti,gate-clock.yaml +++ b/Documentation/devicetree/bindings/clock/ti/ti,gate-clock.yaml @@ -19,7 +19,7 @@ description: | that is used. [1] Documentation/devicetree/bindings/clock/gpio-gate-clock.yaml - [2] Documentation/devicetree/bindings/clock/ti/clockdomain.txt + [2] Documentation/devicetree/bindings/clock/ti/ti,clockdomain.yaml properties: compatible: diff --git a/Documentation/devicetree/bindings/clock/ultrarisc,dp1000-clk.yaml b/Documentation/devicetree/bindings/clock/ultrarisc,dp1000-clk.yaml new file mode 100644 index 000000000000..ede565ec440c --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ultrarisc,dp1000-clk.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ultrarisc,dp1000-clk.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: UltraRISC DP1000 Clock Controller + +maintainers: + - Jia Wang + +description: | + The UltraRISC DP1000 clock controller is driven from a single external + oscillator input. It provides a system PLL with fractional multiplier + and post-divider stages, several fixed-ratio derived clocks for + the on-chip subsystem, Clock Configuration Register (CCR) divider + outputs for GMAC and the UART, I2C, and SPI root clocks, and + per-instance gate clocks for UART0-3, I2C0-3, and SPI0-1. + + All available clocks are defined as preprocessor macros in + include/dt-bindings/clock/ultrarisc,dp1000-clk.h + +properties: + compatible: + const: ultrarisc,dp1000-clk + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + description: + External oscillator input clock used as the parent of the PLLs. + + "#clock-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - "#clock-cells" + +additionalProperties: false + +examples: + - | + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@11080000 { + compatible = "ultrarisc,dp1000-clk"; + reg = <0x0 0x11080000 0x0 0x1000>; + clocks = <&osc>; + #clock-cells = <1>; + }; + }; diff --git a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml index b497c28e8094..3f311f90294e 100644 --- a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml +++ b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml @@ -70,7 +70,7 @@ additionalProperties: false examples: - | - clock-controller@b0000000 { + clock-controller@b0000000 { compatible = "xlnx,clocking-wizard"; reg = <0xb0000000 0x10000>; #clock-cells = <1>; diff --git a/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt b/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt index 91f0a3b0c0b2..847552133633 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt +++ b/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt @@ -75,7 +75,7 @@ SoCs only: - clocks: Should contain the device's input clock, and should be defined as per the bindings in, - Documentation/devicetree/bindings/clock/keystone-gate.txt + Documentation/devicetree/bindings/clock/ti,keystone,psc-clock.yaml The following are mandatory properties for Keystone 2 66AK2G SoCs only: diff --git a/Documentation/devicetree/bindings/reset/qcom,shikra-audiocore-csr.yaml b/Documentation/devicetree/bindings/reset/qcom,shikra-audiocore-csr.yaml new file mode 100644 index 000000000000..bfad1d20e7cd --- /dev/null +++ b/Documentation/devicetree/bindings/reset/qcom,shikra-audiocore-csr.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/qcom,shikra-audiocore-csr.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Audio Core CSR for Qualcomm Shikra SoC + +maintainers: + - Imran Shaik + +description: | + Audio Core CSR module provides the resets on Qualcomm Shikra SoC platform. + + See also: + - include/dt-bindings/clock/qcom,shikra-audiocorecc.h + +properties: + compatible: + const: qcom,shikra-audiocore-csr + + reg: + maxItems: 1 + + '#reset-cells': + const: 1 + +required: + - compatible + - reg + - '#reset-cells' + +additionalProperties: false + +examples: + - | + reset-controller@a0b4000 { + compatible = "qcom,shikra-audiocore-csr"; + reg = <0x0a0b4000 0x1000>; + #reset-cells = <1>; + }; +... diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml index 9df5cdb6f63f..f2b91186ed37 100644 --- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml @@ -33,6 +33,7 @@ properties: - enum: - allwinner,sun20i-d1-rtc - allwinner,sun55i-a523-rtc + - allwinner,sun60i-a733-rtc - const: allwinner,sun50i-r329-rtc reg: @@ -175,6 +176,18 @@ allOf: interrupts: minItems: 2 + - if: + properties: + compatible: + contains: + enum: + - allwinner,sun50i-h616-rtc + - allwinner,sun50i-r329-rtc + + then: + properties: + clock-output-names: false + required: - "#clock-cells" - compatible diff --git a/Documentation/devicetree/bindings/soc/cix/cix,sky1-audss-cru.yaml b/Documentation/devicetree/bindings/soc/cix/cix,sky1-audss-cru.yaml new file mode 100644 index 000000000000..50dd0593e1d9 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/cix/cix,sky1-audss-cru.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/cix/cix,sky1-audss-cru.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cix Sky1 audio subsystem clock and reset unit + +maintainers: + - Joakim Zhang + +description: | + The Cix Sky1 Audio Subsystem (AUDSS) Clock and Reset Unit (CRU) groups + audio-related clock muxing, gating and block-level software reset control + in a single register block. + + A single device node exposes both the clock controller and software reset + lines. The clock driver registers as a platform driver; the reset controller + is registered by an auxiliary driver bound from the clock driver. + + Four SoC-level reference clocks listed in clocks/clock-names feed the AUDSS + clock tree. Internal AUDSS clocks are exposed via #clock-cells; indices are + defined in include/dt-bindings/clock/cix,sky1-audss-cru.h. + + Block-level software reset indices are exposed via #reset-cells; indices + are defined in include/dt-bindings/reset/cix,sky1-audss-cru.h. + + The SoC syscon NoC (or bus) reset is described via resets. The audio + subsystem power domain is described via power-domains. + +properties: + compatible: + const: cix,sky1-audss-cru + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + description: + Clock indices are defined in include/dt-bindings/clock/cix,sky1-audss-cru.h. + + '#reset-cells': + const: 1 + description: + Reset indices are defined in include/dt-bindings/reset/cix,sky1-audss-cru.h. + + clocks: + items: + - description: I2S parent clock for sampling rates multiple of 8kHz. + - description: I2S parent clock for sampling rates multiple of 11.025kHz. + - description: Clock feeding most devices in AUDSS (NOC, DSP, SRAM, HDA, DMAC, I2S, and mailbox). + - description: Clock feeding HDA, timer and watchdog, which is a dedicated 48 MHz clock. + + clock-names: + items: + - const: x8k + - const: x11k + - const: sys + - const: 48m + + power-domains: + maxItems: 1 + + resets: + maxItems: 1 + +required: + - compatible + - reg + - '#clock-cells' + - '#reset-cells' + - clocks + - clock-names + - power-domains + - resets + +additionalProperties: false + +examples: + - | + audss_cru: clock-controller@7110000 { + compatible = "cix,sky1-audss-cru"; + reg = <0x7110000 0x10000>; + #clock-cells = <1>; + #reset-cells = <1>; + clocks = <&scmi_clk 76>, <&scmi_clk 78>, + <&scmi_clk 70>, <&scmi_clk 71>; + clock-names = "x8k", "x11k", "sys", "48m"; + power-domains = <&smc_devpd 0>; + resets = <&s5_syscon 31>; + }; diff --git a/Documentation/devicetree/bindings/soc/mobileye/mobileye,eyeq7h-olb.yaml b/Documentation/devicetree/bindings/soc/mobileye/mobileye,eyeq7h-olb.yaml new file mode 100644 index 000000000000..2958ca9e330b --- /dev/null +++ b/Documentation/devicetree/bindings/soc/mobileye/mobileye,eyeq7h-olb.yaml @@ -0,0 +1,192 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/mobileye/mobileye,eyeq7h-olb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mobileye EyeQ7H SoC system controller + +maintainers: + - Benoît Monin + - Grégory Clement + - Théo Lebrun + - Vladimir Kondratiev + +description: + OLB ("Other Logic Block") is a hardware system controller grouping + smaller blocks. Clocks and resets are generated by those blocks and + used by internal controllers of the SoC. The EyeQ7H SoC hosts 14 + different OLB. + +properties: + compatible: + items: + - enum: + - mobileye,eyeq7h-acc0-olb + - mobileye,eyeq7h-acc1-olb + - mobileye,eyeq7h-ddr0-olb + - mobileye,eyeq7h-ddr1-olb + - mobileye,eyeq7h-east-olb + - mobileye,eyeq7h-mips0-olb + - mobileye,eyeq7h-mips1-olb + - mobileye,eyeq7h-mips2-olb + - mobileye,eyeq7h-periph-east-olb + - mobileye,eyeq7h-periph-west-olb + - mobileye,eyeq7h-south-olb + - mobileye,eyeq7h-west-olb + - mobileye,eyeq7h-xnn0-olb + - mobileye,eyeq7h-xnn1-olb + - const: syscon + + reg: + maxItems: 1 + + '#reset-cells': + description: + First cell is domain and optional if compatible has a single reset domain. + Second cell is reset index inside that domain. + enum: [ 1, 2 ] + + '#clock-cells': + const: 1 + + clocks: + minItems: 1 + maxItems: 2 + + clock-names: + minItems: 1 + maxItems: 2 + +required: + - compatible + - reg + - '#clock-cells' + - clocks + - clock-names + +allOf: + - if: + properties: + compatible: + contains: + enum: + - mobileye,eyeq7h-ddr0-olb + - mobileye,eyeq7h-ddr1-olb + - mobileye,eyeq7h-mips0-olb + - mobileye,eyeq7h-mips1-olb + - mobileye,eyeq7h-mips2-olb + - mobileye,eyeq7h-periph-east-olb + - mobileye,eyeq7h-south-olb + then: + properties: + clocks: + items: + - description: Reference input clock. + clock-names: + items: + - const: ref + + - if: + properties: + compatible: + contains: + enum: + - mobileye,eyeq7h-east-olb + - mobileye,eyeq7h-west-olb + then: + properties: + clocks: + items: + - description: Reference input clock from the main oscillator. + - description: 100MHz reference input clock. + clock-names: + items: + - const: ref + - const: ref_100p0 + + - if: + properties: + compatible: + contains: + enum: + - mobileye,eyeq7h-acc0-olb + - mobileye,eyeq7h-acc1-olb + - mobileye,eyeq7h-periph-west-olb + - mobileye,eyeq7h-xnn0-olb + - mobileye,eyeq7h-xnn1-olb + then: + properties: + clocks: + items: + - description: 100MHz reference input clock. + - description: 106.6MHz reference input clock. + clock-names: + items: + - const: ref_100p0 + - const: ref_106p6 + + - if: + properties: + compatible: + contains: + enum: + - mobileye,eyeq7h-ddr0-olb + - mobileye,eyeq7h-ddr1-olb + - mobileye,eyeq7h-east-olb + - mobileye,eyeq7h-periph-east-olb + - mobileye,eyeq7h-periph-west-olb + - mobileye,eyeq7h-west-olb + then: + properties: + '#reset-cells': + const: 1 + required: + - '#reset-cells' + + - if: + properties: + compatible: + contains: + enum: + - mobileye,eyeq7h-acc0-olb + - mobileye,eyeq7h-acc1-olb + - mobileye,eyeq7h-south-olb + - mobileye,eyeq7h-xnn0-olb + - mobileye,eyeq7h-xnn1-olb + then: + properties: + '#reset-cells': + const: 2 + required: + - '#reset-cells' + + - if: + properties: + compatible: + contains: + enum: + - mobileye,eyeq7h-mips0-olb + - mobileye,eyeq7h-mips1-olb + - mobileye,eyeq7h-mips2-olb + then: + properties: + '#reset-cells': false + +additionalProperties: false + +examples: + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + system-controller0@45000000 { + compatible = "mobileye,eyeq7h-acc0-olb", "syscon"; + reg = <0x0 0x45000000 0x0 0x1000>; + #reset-cells = <2>; + #clock-cells = <1>; + clocks = <&olb_south 7>, <&olb_east 5>; + clock-names = "ref_100p0", "ref_106p6"; + }; + }; diff --git a/Documentation/driver-api/clk.rst b/Documentation/driver-api/clk.rst index c6aca8186a78..294ead519bbf 100644 --- a/Documentation/driver-api/clk.rst +++ b/Documentation/driver-api/clk.rst @@ -42,21 +42,8 @@ clock interface. Common data structures and api ============================== -Below is the common struct clk_core definition from -drivers/clk/clk.c, modified for brevity:: - - struct clk_core { - const char *name; - const struct clk_ops *ops; - struct clk_hw *hw; - struct module *owner; - struct clk_core *parent; - const char **parent_names; - struct clk_core **parents; - u8 num_parents; - u8 new_parent_index; - ... - }; +.. kernel-doc:: drivers/clk/clk.c + :identifiers: struct clk_core The members above make up the core of the clk tree topology. The clk api itself defines several driver-facing functions which operate on @@ -64,38 +51,17 @@ struct clk. That api is documented in include/linux/clk.h. Platforms and devices utilizing the common struct clk_core use the struct clk_ops pointer in struct clk_core to perform the hardware-specific parts of -the operations defined in clk-provider.h:: +the operations defined in clk-provider.h, and can set one or more +framework-level flags documented below. - struct clk_ops { - int (*prepare)(struct clk_hw *hw); - void (*unprepare)(struct clk_hw *hw); - int (*is_prepared)(struct clk_hw *hw); - void (*unprepare_unused)(struct clk_hw *hw); - int (*enable)(struct clk_hw *hw); - void (*disable)(struct clk_hw *hw); - int (*is_enabled)(struct clk_hw *hw); - void (*disable_unused)(struct clk_hw *hw); - unsigned long (*recalc_rate)(struct clk_hw *hw, - unsigned long parent_rate); - int (*determine_rate)(struct clk_hw *hw, - struct clk_rate_request *req); - int (*set_parent)(struct clk_hw *hw, u8 index); - u8 (*get_parent)(struct clk_hw *hw); - int (*set_rate)(struct clk_hw *hw, - unsigned long rate, - unsigned long parent_rate); - int (*set_rate_and_parent)(struct clk_hw *hw, - unsigned long rate, - unsigned long parent_rate, - u8 index); - unsigned long (*recalc_accuracy)(struct clk_hw *hw, - unsigned long parent_accuracy); - int (*get_phase)(struct clk_hw *hw); - int (*set_phase)(struct clk_hw *hw, int degrees); - void (*init)(struct clk_hw *hw); - void (*debug_init)(struct clk_hw *hw, - struct dentry *dentry); - }; +.. kernel-doc:: include/linux/clk-provider.h + :identifiers: struct clk_ops + +Core flags +========== + +.. kernel-doc:: include/linux/clk-provider.h + :doc: clk framework flags Hardware clk implementations ============================ diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 017fb155a5bc..5067500ded5c 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -248,6 +248,7 @@ CLOCK devm_clk_put() devm_clk_bulk_get() devm_clk_bulk_get_all() + devm_clk_bulk_get_enable() devm_clk_bulk_get_optional() devm_get_clk_from_child() devm_clk_hw_register() diff --git a/MAINTAINERS b/MAINTAINERS index 24ca91ce5d86..7e44f413d9d9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6494,9 +6494,9 @@ F: include/linux/comedi/ F: include/uapi/linux/comedi.h COMMON CLK FRAMEWORK -M: Michael Turquette M: Stephen Boyd -R: Brian Masney +M: Brian Masney +M: Jerome Brunet L: linux-clk@vger.kernel.org S: Maintained Q: http://patchwork.kernel.org/project/linux-clk/list/ @@ -9729,9 +9729,10 @@ ESWIN EIC7700 CLOCK DRIVER M: Yifeng Huang M: Xuyang Dong S: Maintained -F: Documentation/devicetree/bindings/clock/eswin,eic7700-clock.yaml +F: Documentation/devicetree/bindings/clock/eswin,eic7700* F: drivers/clk/eswin/ -F: include/dt-bindings/clock/eswin,eic7700-clock.h +F: include/dt-bindings/clock/eswin,eic7700* +F: include/dt-bindings/reset/eswin,eic7700-hspcrg.h ET131X NETWORK DRIVER M: Mark Einon @@ -23337,10 +23338,12 @@ L: linux-renesas-soc@vger.kernel.org S: Maintained F: drivers/phy/renesas/phy-rcar-gen3-usb*.c -RENESAS VERSACLOCK 7 CLOCK DRIVER -M: Alex Helms +RENESAS VERSACLOCK 3 and VERSACLOCK 7 CLOCK DRIVER +M: Biju Das S: Maintained +F: Documentation/devicetree/bindings/clock/renesas,5p35023.yaml F: Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml +F: drivers/clk/clk-versaclock3.c F: drivers/clk/clk-versaclock7.c RENESAS X9250 DIGITAL POTENTIOMETERS DRIVER @@ -27967,6 +27970,14 @@ S: Maintained F: drivers/usb/common/ulpi.c F: include/linux/ulpi/ +ULTRARISC DP1000 CLOCK DRIVER +M: Jia Wang +L: linux-clk@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/clock/ultrarisc,dp1000-clk.yaml +F: drivers/clk/ultrarisc/* +F: include/dt-bindings/clock/ultrarisc,dp1000-clk.h + ULTRARISC DP1000 PINCTRL DRIVER M: Jia Wang L: linux-gpio@vger.kernel.org diff --git a/arch/arm64/boot/dts/cix/sky1.dtsi b/arch/arm64/boot/dts/cix/sky1.dtsi index 04b17ab866fb..0a820f45feb9 100644 --- a/arch/arm64/boot/dts/cix/sky1.dtsi +++ b/arch/arm64/boot/dts/cix/sky1.dtsi @@ -6,6 +6,10 @@ #include #include +#include +#include +#include +#include #include "sky1-power.h" / { @@ -572,6 +576,20 @@ cix,mbox-dir = "rx"; }; + audss_cru: clock-controller@7110000 { + compatible = "cix,sky1-audss-cru"; + reg = <0x0 0x07110000 0x0 0x10000>; + #clock-cells = <1>; + #reset-cells = <1>; + clocks = <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>, + <&scmi_clk CLK_TREE_AUDIO_CLK4>, + <&scmi_clk CLK_TREE_AUDIO_CLK5>; + clock-names = "x8k", "x11k", "sys", "48m"; + power-domains = <&smc_devpd SKY1_PD_AUDIO>; + resets = <&s5_syscon SKY1_AUDIO_HIFI5_NOC_RESET_N>; + }; + mbox_sfh2ap: mailbox@8090000 { compatible = "cix,sky1-mbox"; reg = <0x0 0x08090000 0x0 0x10000>; diff --git a/drivers/clk/.kunitconfig b/drivers/clk/.kunitconfig index 8a0ea41934a2..ea05b9a28c80 100644 --- a/drivers/clk/.kunitconfig +++ b/drivers/clk/.kunitconfig @@ -4,6 +4,7 @@ CONFIG_OF=y CONFIG_OF_OVERLAY=y CONFIG_COMMON_CLK=y CONFIG_CLK_KUNIT_TEST=y +CONFIG_CLK_DIVIDER_KUNIT_TEST=y CONFIG_CLK_FIXED_RATE_KUNIT_TEST=y CONFIG_CLK_GATE_KUNIT_TEST=y CONFIG_CLK_FD_KUNIT_TEST=y diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 1717ce75a907..f9592fd9ec2b 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -155,12 +155,12 @@ config COMMON_CLK_SI514 generator. config COMMON_CLK_SI544 - tristate "Clock driver for SiLabs 544 devices" + tristate "Clock driver for SiLabs 544 and compatible devices" depends on I2C select REGMAP_I2C help - This driver supports the Silicon Labs 544 programmable clock - generator. + This driver supports the Silicon Labs 544/549 programmable clock + generators. config COMMON_CLK_SI570 tristate "Clock driver for SiLabs 570 and compatible devices" @@ -278,7 +278,7 @@ config COMMON_CLK_LAN966X tristate "Generic Clock Controller driver for LAN966X SoC" depends on HAS_IOMEM depends on OF - depends on SOC_LAN966 || ARCH_LAN969X || COMPILE_TEST + depends on SOC_LAN966 || ARCH_LAN969X || MCHP_LAN966X_PCI || COMPILE_TEST help This driver provides support for Generic Clock Controller(GCK) on LAN966X SoC. GCK generates and supplies clock to various peripherals @@ -509,6 +509,7 @@ source "drivers/clk/actions/Kconfig" source "drivers/clk/analogbits/Kconfig" source "drivers/clk/aspeed/Kconfig" source "drivers/clk/bcm/Kconfig" +source "drivers/clk/cix/Kconfig" source "drivers/clk/eswin/Kconfig" source "drivers/clk/hisilicon/Kconfig" source "drivers/clk/imgtec/Kconfig" @@ -541,6 +542,7 @@ source "drivers/clk/tenstorrent/Kconfig" source "drivers/clk/thead/Kconfig" source "drivers/clk/stm32/Kconfig" source "drivers/clk/ti/Kconfig" +source "drivers/clk/ultrarisc/Kconfig" source "drivers/clk/uniphier/Kconfig" source "drivers/clk/visconti/Kconfig" source "drivers/clk/x86/Kconfig" @@ -579,4 +581,12 @@ config CLK_FD_KUNIT_TEST help Kunit test for the clk-fractional-divider type. +config CLK_DIVIDER_KUNIT_TEST + tristate "KUnit tests for clk divider bestdiv" if !KUNIT_ALL_TESTS + depends on KUNIT + depends on !S390 + default KUNIT_ALL_TESTS + help + Kunit test for the clk-divider type. + endif diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index cc108a75a900..b18af485d7f0 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -18,9 +18,20 @@ clk-test-y := clk_test.o \ kunit_clk_assigned_rates_without_consumer.dtbo.o \ kunit_clk_assigned_rates_zero.dtbo.o \ kunit_clk_assigned_rates_zero_consumer.dtbo.o \ + kunit_clk_assigned_sscs_one.dtbo.o \ + kunit_clk_assigned_sscs_one_consumer.dtbo.o \ + kunit_clk_assigned_sscs_multiple.dtbo.o \ + kunit_clk_assigned_sscs_multiple_consumer.dtbo.o \ + kunit_clk_assigned_sscs_null.dtbo.o \ + kunit_clk_assigned_sscs_null_consumer.dtbo.o \ + kunit_clk_assigned_sscs_without.dtbo.o \ + kunit_clk_assigned_sscs_without_consumer.dtbo.o \ + kunit_clk_assigned_sscs_zero.dtbo.o \ + kunit_clk_assigned_sscs_zero_consumer.dtbo.o \ kunit_clk_hw_get_dev_of_node.dtbo.o \ kunit_clk_parent_data_test.dtbo.o obj-$(CONFIG_COMMON_CLK) += clk-divider.o +obj-$(CONFIG_CLK_DIVIDER_KUNIT_TEST) += clk-divider_test.o obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o obj-$(CONFIG_CLK_FIXED_RATE_KUNIT_TEST) += clk-fixed-rate-test.o @@ -88,7 +99,8 @@ obj-$(CONFIG_COMMON_CLK_RP1) += clk-rp1.o obj-$(CONFIG_COMMON_CLK_RPMI) += clk-rpmi.o obj-$(CONFIG_COMMON_CLK_HI655X) += clk-hi655x.o obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o -obj-$(CONFIG_COMMON_CLK_SCMI) += clk-scmi.o +scmi-clk-y := clk-scmi.o clk-scmi-oem.o +obj-$(CONFIG_COMMON_CLK_SCMI) += scmi-clk.o obj-$(CONFIG_COMMON_CLK_SCPI) += clk-scpi.o obj-$(CONFIG_COMMON_CLK_SI5341) += clk-si5341.o obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o @@ -119,9 +131,10 @@ obj-$(CONFIG_ARCH_ARTPEC) += axis/ obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/ obj-y += bcm/ obj-$(CONFIG_ARCH_BERLIN) += berlin/ +obj-y += cix/ obj-$(CONFIG_ARCH_DAVINCI) += davinci/ obj-$(CONFIG_COMMON_CLK_ESWIN) += eswin/ -obj-$(CONFIG_ARCH_HISI) += hisilicon/ +obj-$(CONFIG_COMMON_CLK_HISI) += hisilicon/ obj-y += imgtec/ obj-y += imx/ obj-y += ingenic/ @@ -151,14 +164,15 @@ obj-y += spacemit/ obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-y += sprd/ obj-$(CONFIG_ARCH_STI) += st/ -obj-$(CONFIG_ARCH_STM32) += stm32/ +obj-$(CONFIG_COMMON_CLK_STM32MP) += stm32/ obj-y += starfive/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-y += sunxi-ng/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-y += tenstorrent/ -obj-$(CONFIG_ARCH_THEAD) += thead/ +obj-y += thead/ obj-y += ti/ +obj-y += ultrarisc/ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-y += versatile/ diff --git a/drivers/clk/aspeed/clk-ast2700.c b/drivers/clk/aspeed/clk-ast2700.c index aa4dd7f24608..536600fcd024 100644 --- a/drivers/clk/aspeed/clk-ast2700.c +++ b/drivers/clk/aspeed/clk-ast2700.c @@ -272,6 +272,13 @@ static const unsigned int sdclk_parent_ids[] = { static const struct clk_hw *sdclk_parent_hws[ARRAY_SIZE(sdclk_parent_ids)]; +static const unsigned int peciclk_parent_ids[] = { + SCU1_CLKIN, + SCU1_CLK_HPLL_DIV4 +}; + +static const struct clk_hw *peciclk_parent_hws[ARRAY_SIZE(peciclk_parent_ids)]; + #define FIXED_CLK(_id, _name, _rate) \ { \ .id = _id, \ @@ -457,6 +464,7 @@ static const struct ast2700_clk_info ast2700_scu1_clk_info[] __initconst = { PLL_CLK(SCU1_CLK_HPLL, CLK_PLL, "soc1-hpll", SCU1_CLKIN, SCU1_HPLL_PARAM), PLL_CLK(SCU1_CLK_APLL, CLK_PLL, "soc1-apll", SCU1_CLKIN, SCU1_APLL_PARAM), PLL_CLK(SCU1_CLK_DPLL, CLK_PLL, "soc1-dpll", SCU1_CLKIN, SCU1_DPLL_PARAM), + FIXED_FACTOR_CLK(SCU1_CLK_HPLL_DIV4, "soc1-hpll_div4", SCU1_CLK_HPLL, 1, 4), FIXED_FACTOR_CLK(SCU1_CLK_APLL_DIV2, "soc1-apll_div2", SCU1_CLK_APLL, 1, 2), FIXED_FACTOR_CLK(SCU1_CLK_APLL_DIV4, "soc1-apll_div4", SCU1_CLK_APLL, 1, 4), FIXED_FACTOR_CLK(SCU1_CLK_CAN, "canclk", SCU1_CLK_APLL, 1, 10), @@ -480,6 +488,8 @@ static const struct ast2700_clk_info ast2700_scu1_clk_info[] __initconst = { uxclk_parent_hws, SCU1_CLK_SEL2, 0, 2), MUX_CLK(SCU1_CLK_HUXCLK, "huxclk", uxclk_parent_ids, ARRAY_SIZE(uxclk_parent_ids), uxclk_parent_hws, SCU1_CLK_SEL2, 3, 2), + MUX_CLK(SCU1_CLK_PECI, "peciclk", peciclk_parent_ids, ARRAY_SIZE(peciclk_parent_ids), + peciclk_parent_hws, SCU1_CLK_SEL2, 16, 1), DIVIDER_CLK(SCU1_CLK_SDCLK, "sdclk", SCU1_CLK_SDMUX, SCU1_CLK_SEL1, 14, 3, ast2700_clk_div_table), PLL_CLK(SCU1_CLK_UARTX, CLK_UART_PLL, "uartxclk", SCU1_CLK_UXCLK, SCU1_UXCLK_CTRL), diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c index 5d543e807843..dad26dd5e71d 100644 --- a/drivers/clk/at91/dt-compat.c +++ b/drivers/clk/at91/dt-compat.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -217,7 +218,7 @@ CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx", static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np) { struct regmap *regmap_sfr; - u8 bus_id; + u64 bus_id; const char *parent_names[2]; struct device_node *i2s_mux_np; struct clk_hw *hw; @@ -228,7 +229,7 @@ static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np) return; for_each_child_of_node(np, i2s_mux_np) { - if (of_property_read_u8(i2s_mux_np, "reg", &bus_id)) + if (of_property_read_reg(i2s_mux_np, 0, &bus_id, NULL)) continue; if (bus_id > I2S_BUS_NR) diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c index 0171e6b2bfca..d6f5872d7d6a 100644 --- a/drivers/clk/bcm/clk-kona.c +++ b/drivers/clk/bcm/clk-kona.c @@ -1098,8 +1098,7 @@ static u8 kona_peri_clk_get_parent(struct clk_hw *hw) index = selector_read_index(bcm_clk->ccu, &data->sel); - /* Not all callers would handle an out-of-range value gracefully */ - return index == BAD_CLK_INDEX ? 0 : index; + return index; } static int kona_peri_clk_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/cix/Kconfig b/drivers/clk/cix/Kconfig new file mode 100644 index 000000000000..b057ef85fab6 --- /dev/null +++ b/drivers/clk/cix/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 +# Audio subsystem clock support for Cixtech SoC family +menu "Cixtech Audio Subsystem Clock Driver" + +config CLK_SKY1_AUDSS + tristate "Cixtech Sky1 Audio Subsystem Clock Driver" + depends on ARCH_CIX || COMPILE_TEST + select AUXILIARY_BUS + select REGMAP_MMIO + select RESET_CONTROLLER + help + Support for the Audio Subsystem clock controller present on + Cixtech Sky1 SoC. This driver provides mux, divider and gate + clocks for DSP, I2S, HDA and related blocks in the audio + subsystem. Say M or Y here if you want to build this driver. +endmenu diff --git a/drivers/clk/cix/Makefile b/drivers/clk/cix/Makefile new file mode 100644 index 000000000000..bc612f1d08b2 --- /dev/null +++ b/drivers/clk/cix/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_CLK_SKY1_AUDSS) += clk-sky1-audss.o diff --git a/drivers/clk/cix/clk-sky1-audss.c b/drivers/clk/cix/clk-sky1-audss.c new file mode 100644 index 000000000000..e096b8121df3 --- /dev/null +++ b/drivers/clk/cix/clk-sky1-audss.c @@ -0,0 +1,1206 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright 2026 Cix Technology Group Co., Ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define INFO_HIFI0 0x00 +#define INFO_CLK_GATE 0x10 +#define INFO_CLK_DIV 0x14 +#define INFO_CLK_MUX 0x18 +#define INFO_MCLK 0x70 + +#define SKY1_AUDSS_CLK_PARENTS_CNT 4 +#define SKY1_AUDSS_NUM_CLKS (CLK_MCLK4 + 1) + +static u32 sky1_reg_save[][2] = { + { INFO_HIFI0, 0 }, + { INFO_CLK_GATE, 0 }, + { INFO_CLK_DIV, 0 }, + { INFO_CLK_MUX, 0 }, + { INFO_MCLK, 0 }, +}; + +static const char * const sky1_audss_clk_names[SKY1_AUDSS_CLK_PARENTS_CNT] = { + "x8k", "x11k", "sys", "48m", +}; + +static const u32 sky1_clk_rate_default[SKY1_AUDSS_CLK_PARENTS_CNT] = { + 294912000, + 270950400, + 800000000, + 48000000, +}; + +static const char * const dsp_clk_parent[] = { + "audio_clk4" +}; + +static const char * const dsp_bclk_parent[] = { + "audio_clk4_div2" +}; + +static const char * const dsp_pbclk_parent[] = { + "audio_clk4_div4" +}; + +static const char * const sram_axi_parent[] = { + "audio_clk4_div2" +}; + +static const char * const hda_sys_parent[] = { + "audio_clk4_div2" +}; + +static const char * const hda_hda_parent[] = { + "audio_clk5" +}; + +static const char * const dmac_axi_parent[] = { + "audio_clk4_div2" +}; + +static const char * const wdg_apb_parent[] = { + "audio_clk5_div2" +}; + +static const char * const wdg_wdg_parent[] = { + "audio_clk5_div2" +}; + +static const char * const timer_apb_parent[] = { + "audio_clk4_div4" +}; + +static const char * const timer_timer_parent[] = { + "audio_clk5_div2" +}; + +static const char * const mailbox_apb_parent[] = { + "audio_clk4_div4" +}; + +static const char * const i2s_apb_parent[] = { + "audio_clk4_div4" +}; + +static const char * const i2s0_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s1_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s2_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s3_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s4_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s5_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s6_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s7_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s8_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s9_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const mclk_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const u32 i2s3_mux_table[] = { 0, 2 }; +static const u32 i2s4_mux_table[] = { 0, 2 }; + +/* + * audss composite clock definition + */ +struct muxdiv_cfg { + int offset; + u8 shift; + u8 width; + u8 flags; +}; + +struct gate_cfg { + int offset; + u8 shift; + u8 flags; +}; + +struct composite_clk_cfg { + u32 id; + const char * const name; + const char * const *parent_names; + int num_parents; + const u32 *mux_table; + struct muxdiv_cfg *mux_cfg; + struct muxdiv_cfg *div_cfg; + struct gate_cfg *gate_cfg; + unsigned long flags; +}; + +#define CFG(_id,\ + _name,\ + _parent_names,\ + _mux_table,\ + _mux_offset, _mux_shift, _mux_width, _mux_flags,\ + _div_offset, _div_shift, _div_width, _div_flags,\ + _gate_offset, _gate_shift, _gate_flags,\ + _flags)\ +{\ + .id = _id,\ + .name = _name,\ + .parent_names = _parent_names,\ + .num_parents = ARRAY_SIZE(_parent_names),\ + .mux_table = _mux_table,\ + .mux_cfg = &(struct muxdiv_cfg) { _mux_offset, _mux_shift, _mux_width, _mux_flags },\ + .div_cfg = &(struct muxdiv_cfg) { _div_offset, _div_shift, _div_width, _div_flags },\ + .gate_cfg = &(struct gate_cfg) { _gate_offset, _gate_shift, _gate_flags },\ + .flags = _flags,\ +} + +static const struct composite_clk_cfg sky1_audss_clks[] = { + /* dsp */ + CFG(CLK_DSP_CLK, + "audss_dsp_clk", + dsp_clk_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_HIFI0, 0, 0, + 0), + CFG(CLK_DSP_BCLK, + "audss_dsp_bclk", + dsp_bclk_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + -1, 0, 0, + 0), + CFG(CLK_DSP_PBCLK, + "audss_dsp_pbclk", + dsp_pbclk_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + -1, 0, 0, + 0), + /* sram */ + CFG(CLK_SRAM_AXI, + "audss_sram_axi", + sram_axi_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 16, 0, + 0), + /* hda */ + CFG(CLK_HDA_SYS, + "audss_hda_sys", + hda_sys_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 14, 0, + 0), + CFG(CLK_HDA_HDA, + "audss_hda_hda", + hda_hda_parent, + NULL, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 14, 0, + 0), + /* dmac */ + CFG(CLK_DMAC_AXI, + "audss_dmac_axi", + dmac_axi_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 15, 0, + 0), + /* wdg */ + CFG(CLK_WDG_APB, + "audss_wdg_apb", + wdg_apb_parent, + NULL, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 10, 0, + 0), + CFG(CLK_WDG_WDG, + "audss_wdg_wdg", + wdg_wdg_parent, + NULL, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 10, 0, + 0), + /* timer */ + CFG(CLK_TIMER_APB, + "audss_timer_apb", + timer_apb_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 11, 0, + 0), + CFG(CLK_TIMER_TIMER, + "audss_timer_timer", + timer_timer_parent, + NULL, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 11, 0, + 0), + /* mailbox: mb0(ap->dsp), mb1(dsp->ap) */ + CFG(CLK_MB_0_APB, + "audss_mb_0_apb", + mailbox_apb_parent, + NULL, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 12, 0, + 0), + CFG(CLK_MB_1_APB, + "audss_mb_1_apb", + mailbox_apb_parent, + NULL, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 13, 0, + 0), + /* i2s */ + CFG(CLK_I2S0_APB, + "audss_i2s0_apb", + i2s_apb_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 0, 0, + 0), + CFG(CLK_I2S1_APB, + "audss_i2s1_apb", + i2s_apb_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 1, 0, + 0), + CFG(CLK_I2S2_APB, + "audss_i2s2_apb", + i2s_apb_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 2, 0, + 0), + CFG(CLK_I2S3_APB, + "audss_i2s3_apb", + i2s_apb_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 3, 0, + 0), + CFG(CLK_I2S4_APB, + "audss_i2s4_apb", + i2s_apb_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 4, 0, + 0), + CFG(CLK_I2S5_APB, + "audss_i2s5_apb", + i2s_apb_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 5, 0, + 0), + CFG(CLK_I2S6_APB, + "audss_i2s6_apb", + i2s_apb_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 6, 0, + 0), + CFG(CLK_I2S7_APB, + "audss_i2s7_apb", + i2s_apb_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 7, 0, + 0), + CFG(CLK_I2S8_APB, + "audss_i2s8_apb", + i2s_apb_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 8, 0, + 0), + CFG(CLK_I2S9_APB, + "audss_i2s9_apb", + i2s_apb_parent, + NULL, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 9, 0, + 0), + CFG(CLK_I2S0, + "audss_i2s0", + i2s0_parents, + NULL, + INFO_CLK_MUX, 0, 2, 0, + INFO_CLK_DIV, 2, 2, 0, + INFO_CLK_GATE, 0, 0, + 0), + CFG(CLK_I2S1, + "audss_i2s1", + i2s1_parents, + NULL, + INFO_CLK_MUX, 2, 2, 0, + INFO_CLK_DIV, 4, 2, 0, + INFO_CLK_GATE, 1, 0, + 0), + CFG(CLK_I2S2, + "audss_i2s2", + i2s2_parents, + NULL, + INFO_CLK_MUX, 4, 2, 0, + INFO_CLK_DIV, 6, 2, 0, + INFO_CLK_GATE, 2, 0, + 0), + CFG(CLK_I2S3, + "audss_i2s3", + i2s3_parents, + i2s3_mux_table, + INFO_CLK_MUX, 6, 2, 0, + INFO_CLK_DIV, 8, 2, 0, + INFO_CLK_GATE, 3, 0, + 0), + CFG(CLK_I2S4, + "audss_i2s4", + i2s4_parents, + i2s4_mux_table, + INFO_CLK_MUX, 8, 2, 0, + INFO_CLK_DIV, 10, 2, 0, + INFO_CLK_GATE, 4, 0, + 0), + CFG(CLK_I2S5, + "audss_i2s5", + i2s5_parents, + NULL, + INFO_CLK_MUX, 10, 2, 0, + INFO_CLK_DIV, 12, 2, 0, + INFO_CLK_GATE, 5, 0, + 0), + CFG(CLK_I2S6, + "audss_i2s6", + i2s6_parents, + NULL, + INFO_CLK_MUX, 12, 2, 0, + INFO_CLK_DIV, 14, 2, 0, + INFO_CLK_GATE, 6, 0, + 0), + CFG(CLK_I2S7, + "audss_i2s7", + i2s7_parents, + NULL, + INFO_CLK_MUX, 14, 2, 0, + INFO_CLK_DIV, 16, 2, 0, + INFO_CLK_GATE, 7, 0, + 0), + CFG(CLK_I2S8, + "audss_i2s8", + i2s8_parents, + NULL, + INFO_CLK_MUX, 16, 2, 0, + INFO_CLK_DIV, 18, 2, 0, + INFO_CLK_GATE, 8, 0, + 0), + CFG(CLK_I2S9, + "audss_i2s9", + i2s9_parents, + NULL, + INFO_CLK_MUX, 18, 2, 0, + INFO_CLK_DIV, 20, 2, 0, + INFO_CLK_GATE, 9, 0, + 0), + /* mclk */ + CFG(CLK_MCLK0, + "audss_mclk0", + mclk_parents, + NULL, + INFO_MCLK, 5, 1, 0, + -1, 0, 0, 0, + INFO_MCLK, 0, 0, + 0), + CFG(CLK_MCLK1, + "audss_mclk1", + mclk_parents, + NULL, + INFO_MCLK, 6, 1, 0, + -1, 0, 0, 0, + INFO_MCLK, 1, 0, + 0), + CFG(CLK_MCLK2, + "audss_mclk2", + mclk_parents, + NULL, + INFO_MCLK, 7, 1, 0, + -1, 0, 0, 0, + INFO_MCLK, 2, 0, + 0), + CFG(CLK_MCLK3, + "audss_mclk3", + mclk_parents, + NULL, + INFO_MCLK, 8, 1, 0, + -1, 0, 0, 0, + INFO_MCLK, 3, 0, + 0), + CFG(CLK_MCLK4, + "audss_mclk4", + mclk_parents, + NULL, + INFO_MCLK, 9, 1, 0, + -1, 0, 0, 0, + INFO_MCLK, 4, 0, + 0), +}; + +struct sky1_audss_clks_devtype_data { + u32 (*reg_save)[2]; + size_t reg_save_size; + const char * const *clk_names; + size_t clk_num; + const u32 *clk_rate_default; + const struct composite_clk_cfg *clk_cfg; + size_t clk_cfg_size; +}; + +static const struct regmap_config sky1_audss_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +struct sky1_audss_clks_priv { + struct device *dev; + struct regmap *regmap_cru; + struct reset_control *rst_noc; + struct clk *clks[SKY1_AUDSS_CLK_PARENTS_CNT]; + const struct sky1_audss_clks_devtype_data *devtype_data; + spinlock_t lock; + struct clk_hw_onecell_data *clk_data; +}; + +#if IS_ENABLED(CONFIG_RESET_SKY1_AUDSS) + +static int sky1_audss_reset_controller_register(struct device *dev) +{ + struct auxiliary_device *adev; + + if (!of_property_present(dev->of_node, "#reset-cells")) + return 0; + + adev = devm_auxiliary_device_create(dev, "reset", NULL); + if (!adev) + return -ENODEV; + + return 0; +} + +#else + +static int sky1_audss_reset_controller_register(struct device *dev) +{ + return 0; +} + +#endif + +/* + * clk_ops for audss clock mux/divider/gate + */ +struct sky1_clk_divider { + struct clk_divider div; + struct regmap *regmap; + int offset; +}; + +struct sky1_clk_gate { + struct clk_gate gate; + struct regmap *regmap; + int offset; +}; + +struct sky1_clk_mux { + struct clk_mux mux; + struct regmap *regmap; + int offset; +}; + +static inline struct sky1_clk_mux *to_sky1_clk_mux(struct clk_mux *mux) +{ + return container_of(mux, struct sky1_clk_mux, mux); +} + +static u8 sky1_audss_clk_mux_get_parent(struct clk_hw *hw) +{ + struct clk_mux *mux = to_clk_mux(hw); + struct sky1_clk_mux *sky1_mux = to_sky1_clk_mux(mux); + u32 val; + + regmap_read(sky1_mux->regmap, sky1_mux->offset, &val); + val = val >> mux->shift; + val &= mux->mask; + + return clk_mux_val_to_index(hw, mux->table, mux->flags, val); +} + +static int sky1_audss_clk_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_mux *mux = to_clk_mux(hw); + u32 val = clk_mux_index_to_val(mux->table, mux->flags, index); + struct sky1_clk_mux *sky1_mux = to_sky1_clk_mux(mux); + unsigned long flags = 0; + u32 reg; + + if (mux->lock) + spin_lock_irqsave(mux->lock, flags); + else + __acquire(mux->lock); + + if (mux->flags & CLK_MUX_HIWORD_MASK) { + reg = mux->mask << (mux->shift + 16); + } else { + regmap_read(sky1_mux->regmap, sky1_mux->offset, ®); + reg &= ~(mux->mask << mux->shift); + } + val = val << mux->shift; + reg |= val; + regmap_write(sky1_mux->regmap, sky1_mux->offset, reg); + + if (mux->lock) + spin_unlock_irqrestore(mux->lock, flags); + else + __release(mux->lock); + + return 0; +} + +static int sky1_audss_clk_mux_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_mux *mux = to_clk_mux(hw); + + return clk_mux_determine_rate_flags(hw, req, mux->flags); +} + +static const struct clk_ops sky1_audss_clk_mux_ops = { + .get_parent = sky1_audss_clk_mux_get_parent, + .set_parent = sky1_audss_clk_mux_set_parent, + .determine_rate = sky1_audss_clk_mux_determine_rate, +}; + +static inline struct sky1_clk_divider *to_sky1_clk_divider(struct clk_divider *div) +{ + return container_of(div, struct sky1_clk_divider, div); +} + +static unsigned long sky1_audss_clk_divider_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_divider *divider = to_clk_divider(hw); + struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider); + unsigned int val; + + regmap_read(sky1_div->regmap, sky1_div->offset, &val); + val = val >> divider->shift; + val &= clk_div_mask(divider->width); + + return divider_recalc_rate(hw, parent_rate, val, divider->table, + divider->flags, divider->width); +} + +static int sky1_audss_clk_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_divider *divider = to_clk_divider(hw); + struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider); + + /* if read only, just return current value */ + if (divider->flags & CLK_DIVIDER_READ_ONLY) { + u32 val; + + regmap_read(sky1_div->regmap, sky1_div->offset, &val); + val = val >> divider->shift; + val &= clk_div_mask(divider->width); + + return divider_ro_determine_rate(hw, req, divider->table, + divider->width, + divider->flags, val); + } + + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); +} + +static int sky1_audss_clk_divider_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct clk_divider *divider = to_clk_divider(hw); + struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider); + int value; + unsigned long flags = 0; + u32 val; + + value = divider_get_val(rate, parent_rate, divider->table, + divider->width, divider->flags); + if (value < 0) + return value; + + if (divider->lock) + spin_lock_irqsave(divider->lock, flags); + else + __acquire(divider->lock); + + if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { + val = clk_div_mask(divider->width) << (divider->shift + 16); + } else { + regmap_read(sky1_div->regmap, sky1_div->offset, &val); + val &= ~(clk_div_mask(divider->width) << divider->shift); + } + val |= (u32)value << divider->shift; + regmap_write(sky1_div->regmap, sky1_div->offset, val); + + if (divider->lock) + spin_unlock_irqrestore(divider->lock, flags); + else + __release(divider->lock); + + return 0; +} + +static const struct clk_ops sky1_audss_clk_divider_ops = { + .recalc_rate = sky1_audss_clk_divider_recalc_rate, + .determine_rate = sky1_audss_clk_divider_determine_rate, + .set_rate = sky1_audss_clk_divider_set_rate, +}; + +static inline struct sky1_clk_gate *to_sky1_clk_gate(struct clk_gate *gate) +{ + return container_of(gate, struct sky1_clk_gate, gate); +} + +static void sky1_audss_clk_gate_endisable(struct clk_hw *hw, int enable) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct sky1_clk_gate *sky1_gate = to_sky1_clk_gate(gate); + int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0; + unsigned long flags = 0; + u32 reg; + + set ^= enable; + + if (gate->lock) + spin_lock_irqsave(gate->lock, flags); + else + __acquire(gate->lock); + + if (gate->flags & CLK_GATE_HIWORD_MASK) { + reg = BIT(gate->bit_idx + 16); + if (set) + reg |= BIT(gate->bit_idx); + } else { + regmap_read(sky1_gate->regmap, sky1_gate->offset, ®); + + if (set) + reg |= BIT(gate->bit_idx); + else + reg &= ~BIT(gate->bit_idx); + } + + regmap_write(sky1_gate->regmap, sky1_gate->offset, reg); + + if (gate->lock) + spin_unlock_irqrestore(gate->lock, flags); + else + __release(gate->lock); +} + +static int sky1_audss_clk_gate_enable(struct clk_hw *hw) +{ + sky1_audss_clk_gate_endisable(hw, 1); + + return 0; +} + +static void sky1_audss_clk_gate_disable(struct clk_hw *hw) +{ + sky1_audss_clk_gate_endisable(hw, 0); +} + +static int sky1_audss_clk_gate_is_enabled(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct sky1_clk_gate *sky1_gate = to_sky1_clk_gate(gate); + u32 reg; + + regmap_read(sky1_gate->regmap, sky1_gate->offset, ®); + + /* if a set bit disables this clk, flip it before masking */ + if (gate->flags & CLK_GATE_SET_TO_DISABLE) + reg ^= BIT(gate->bit_idx); + + reg &= BIT(gate->bit_idx); + + return !!reg; +} + +static const struct clk_ops sky1_audss_clk_gate_ops = { + .enable = sky1_audss_clk_gate_enable, + .disable = sky1_audss_clk_gate_disable, + .is_enabled = sky1_audss_clk_gate_is_enabled, +}; + +static struct clk_hw *sky1_audss_clk_register(struct device *dev, + const char *name, + const char * const *parent_names, + int num_parents, + struct regmap *regmap, + const u32 *mux_table, + struct muxdiv_cfg *mux_cfg, + struct muxdiv_cfg *div_cfg, + struct gate_cfg *gate_cfg, + unsigned long flags, + spinlock_t *lock) +{ + const struct clk_ops *sky1_gate_ops = NULL; + const struct clk_ops *sky1_mux_ops = NULL; + const struct clk_ops *sky1_div_ops = NULL; + struct sky1_clk_divider *sky1_div = NULL; + struct sky1_clk_gate *sky1_gate = NULL; + struct sky1_clk_mux *sky1_mux = NULL; + struct clk_hw *hw = ERR_PTR(-ENOMEM); + struct clk_parent_data *parent_data; + int i; + + parent_data = devm_kcalloc(dev, num_parents, sizeof(*parent_data), GFP_KERNEL); + if (!parent_data) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < num_parents; i++) + parent_data[i].name = parent_names[i]; + + if (mux_cfg->offset >= 0) { + sky1_mux = devm_kzalloc(dev, sizeof(*sky1_mux), GFP_KERNEL); + if (!sky1_mux) + return ERR_PTR(-ENOMEM); + + sky1_mux->mux.reg = NULL; + sky1_mux->mux.shift = mux_cfg->shift; + sky1_mux->mux.mask = BIT(mux_cfg->width) - 1; + sky1_mux->mux.flags = mux_cfg->flags; + sky1_mux->mux.table = mux_table; + sky1_mux->mux.lock = lock; + sky1_mux_ops = &sky1_audss_clk_mux_ops; + sky1_mux->regmap = regmap; + sky1_mux->offset = mux_cfg->offset; + } + + if (div_cfg->offset >= 0) { + sky1_div = devm_kzalloc(dev, sizeof(*sky1_div), GFP_KERNEL); + if (!sky1_div) + return ERR_PTR(-ENOMEM); + + sky1_div->div.reg = NULL; + sky1_div->div.shift = div_cfg->shift; + sky1_div->div.width = div_cfg->width; + sky1_div->div.flags = div_cfg->flags | CLK_DIVIDER_POWER_OF_TWO; + sky1_div->div.lock = lock; + sky1_div_ops = &sky1_audss_clk_divider_ops; + sky1_div->regmap = regmap; + sky1_div->offset = div_cfg->offset; + } + + if (gate_cfg->offset >= 0) { + sky1_gate = devm_kzalloc(dev, sizeof(*sky1_gate), GFP_KERNEL); + if (!sky1_gate) + return ERR_PTR(-ENOMEM); + + sky1_gate->gate.reg = NULL; + sky1_gate->gate.bit_idx = gate_cfg->shift; + sky1_gate->gate.flags = gate_cfg->flags; + sky1_gate->gate.lock = lock; + sky1_gate_ops = &sky1_audss_clk_gate_ops; + sky1_gate->regmap = regmap; + sky1_gate->offset = gate_cfg->offset; + } + + hw = devm_clk_hw_register_composite_pdata(dev, name, parent_data, num_parents, + sky1_mux ? &sky1_mux->mux.hw : NULL, sky1_mux_ops, + sky1_div ? &sky1_div->div.hw : NULL, sky1_div_ops, + sky1_gate ? &sky1_gate->gate.hw : NULL, sky1_gate_ops, + flags); + if (IS_ERR(hw)) { + dev_err(dev, "register %s clock failed with err = %ld\n", + name, PTR_ERR(hw)); + return hw; + } + + return hw; +} + +static int sky1_audss_clks_get(struct sky1_audss_clks_priv *priv) +{ + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data; + int i; + + for (i = 0; i < devtype_data->clk_num; i++) { + priv->clks[i] = devm_clk_get(priv->dev, devtype_data->clk_names[i]); + if (IS_ERR(priv->clks[i])) + return dev_err_probe(priv->dev, PTR_ERR(priv->clks[i]), + "failed to get clock %s", devtype_data->clk_names[i]); + } + + return 0; +} + +static int sky1_audss_clks_enable(struct sky1_audss_clks_priv *priv) +{ + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data; + int i, err; + + for (i = 0; i < devtype_data->clk_num; i++) { + err = clk_prepare_enable(priv->clks[i]); + if (err) { + dev_err(priv->dev, "failed to enable clock %s\n", + devtype_data->clk_names[i]); + goto err_clks; + } + } + + return 0; + +err_clks: + while (--i >= 0) + clk_disable_unprepare(priv->clks[i]); + + return err; +} + +static void sky1_audss_clks_disable(struct sky1_audss_clks_priv *priv) +{ + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data; + int i; + + for (i = 0; i < devtype_data->clk_num; i++) + clk_disable_unprepare(priv->clks[i]); +} + +static int sky1_audss_clks_set_rate(struct sky1_audss_clks_priv *priv) +{ + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data; + int i, err; + + for (i = 0; i < devtype_data->clk_num; i++) { + err = clk_set_rate(priv->clks[i], devtype_data->clk_rate_default[i]); + if (err) { + dev_err(priv->dev, "failed to set clock rate %s\n", + devtype_data->clk_names[i]); + return err; + } + } + + return 0; +} + +static void sky1_audss_clk_rpm_cleanup(void *data) +{ + pm_runtime_force_suspend(data); +} + +/* register sky1 audio subsystem clocks */ +static int sky1_audss_clk_probe(struct platform_device *pdev) +{ + const struct sky1_audss_clks_devtype_data *devtype_data; + struct sky1_audss_clks_priv *priv; + struct device *dev = &pdev->dev; + struct clk_hw **clk_table; + void __iomem *base; + int i, ret; + + devtype_data = device_get_match_data(dev); + if (!devtype_data) + return -ENODEV; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + spin_lock_init(&priv->lock); + + priv->clk_data = devm_kzalloc(dev, + struct_size(priv->clk_data, hws, SKY1_AUDSS_NUM_CLKS), + GFP_KERNEL); + if (!priv->clk_data) + return -ENOMEM; + + priv->clk_data->num = SKY1_AUDSS_NUM_CLKS; + clk_table = priv->clk_data->hws; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + priv->regmap_cru = devm_regmap_init_mmio(dev, base, &sky1_audss_regmap_config); + if (IS_ERR(priv->regmap_cru)) + return dev_err_probe(dev, PTR_ERR(priv->regmap_cru), + "failed to initialize regmap\n"); + + priv->dev = dev; + priv->devtype_data = devtype_data; + + priv->rst_noc = devm_reset_control_get_exclusive(dev, NULL); + if (IS_ERR(priv->rst_noc)) + return dev_err_probe(dev, PTR_ERR(priv->rst_noc), + "failed to get audss noc reset"); + + platform_set_drvdata(pdev, priv); + + reset_control_assert(priv->rst_noc); + + ret = sky1_audss_clks_get(priv); + if (ret) + return ret; + + ret = sky1_audss_clks_enable(priv); + if (ret) + return ret; + + /* release noc reset after clock on */ + ret = reset_control_deassert(priv->rst_noc); + if (ret) { + sky1_audss_clks_disable(priv); + return ret; + } + + pm_runtime_get_noresume(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + /* + * Register cleanup action before clocks/provider (released last under LIFO). + */ + ret = devm_add_action_or_reset(dev, sky1_audss_clk_rpm_cleanup, dev); + if (ret) + return ret; + + ret = sky1_audss_clks_set_rate(priv); + if (ret) + goto fail_pm; + + /* audio_clk4 clock fixed divider */ + clk_table[CLK_AUD_CLK4_DIV2] = + devm_clk_hw_register_fixed_factor(dev, + "audio_clk4_div2", + "audio_clk4", + 0, + 1, 2); + if (IS_ERR(clk_table[CLK_AUD_CLK4_DIV2])) { + ret = PTR_ERR(clk_table[CLK_AUD_CLK4_DIV2]); + dev_err(dev, "failed to register clock %d, ret:%d\n", CLK_AUD_CLK4_DIV2, ret); + goto fail_pm; + } + + clk_table[CLK_AUD_CLK4_DIV4] = + devm_clk_hw_register_fixed_factor(dev, + "audio_clk4_div4", + "audio_clk4", + 0, + 1, 4); + if (IS_ERR(clk_table[CLK_AUD_CLK4_DIV4])) { + ret = PTR_ERR(clk_table[CLK_AUD_CLK4_DIV4]); + dev_err(dev, "failed to register clock %d, ret:%d\n", CLK_AUD_CLK4_DIV4, ret); + goto fail_pm; + } + + /* audio_clk5 clock fixed divider */ + clk_table[CLK_AUD_CLK5_DIV2] = + devm_clk_hw_register_fixed_factor(dev, + "audio_clk5_div2", + "audio_clk5", + 0, + 1, 2); + if (IS_ERR(clk_table[CLK_AUD_CLK5_DIV2])) { + ret = PTR_ERR(clk_table[CLK_AUD_CLK5_DIV2]); + dev_err(dev, "failed to register clock %d, ret:%d\n", CLK_AUD_CLK5_DIV2, ret); + goto fail_pm; + } + + for (i = 0; i < devtype_data->clk_cfg_size; i++) { + clk_table[devtype_data->clk_cfg[i].id] = + sky1_audss_clk_register(dev, + devtype_data->clk_cfg[i].name, + devtype_data->clk_cfg[i].parent_names, + devtype_data->clk_cfg[i].num_parents, + priv->regmap_cru, + devtype_data->clk_cfg[i].mux_table, + devtype_data->clk_cfg[i].mux_cfg, + devtype_data->clk_cfg[i].div_cfg, + devtype_data->clk_cfg[i].gate_cfg, + devtype_data->clk_cfg[i].flags, + &priv->lock); + if (IS_ERR(clk_table[devtype_data->clk_cfg[i].id])) { + ret = PTR_ERR(clk_table[devtype_data->clk_cfg[i].id]); + dev_err(dev, "failed to register clock %d, ret:%d\n", + devtype_data->clk_cfg[i].id, ret); + goto fail_pm; + } + } + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, priv->clk_data); + if (ret) { + dev_err(dev, "failed to add clock provider: %d\n", ret); + goto fail_pm; + } + + ret = sky1_audss_reset_controller_register(dev); + if (ret) { + dev_err(dev, "failed to register reset controller: %d\n", ret); + goto fail_pm; + } + + pm_runtime_put_sync(dev); + + return 0; + +fail_pm: + pm_runtime_put_sync(dev); + return ret; +} + +static int __maybe_unused sky1_audss_clk_runtime_suspend(struct device *dev) +{ + struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev); + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data; + unsigned long flags; + int i; + + spin_lock_irqsave(&priv->lock, flags); + for (i = 0; i < devtype_data->reg_save_size; i++) + regmap_read(priv->regmap_cru, + devtype_data->reg_save[i][0], &devtype_data->reg_save[i][1]); + spin_unlock_irqrestore(&priv->lock, flags); + + reset_control_assert(priv->rst_noc); + + sky1_audss_clks_disable(priv); + + return 0; +} + +static int __maybe_unused sky1_audss_clk_runtime_resume(struct device *dev) +{ + struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev); + const struct sky1_audss_clks_devtype_data *devtype_data = priv->devtype_data; + unsigned long flags; + int i, ret; + + ret = sky1_audss_clks_enable(priv); + if (ret) { + dev_err(dev, "failed to enable clocks\n"); + return ret; + } + + ret = reset_control_deassert(priv->rst_noc); + if (ret) { + sky1_audss_clks_disable(priv); + return ret; + } + + spin_lock_irqsave(&priv->lock, flags); + for (i = 0; i < devtype_data->reg_save_size; i++) + regmap_write(priv->regmap_cru, + devtype_data->reg_save[i][0], devtype_data->reg_save[i][1]); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static const struct dev_pm_ops sky1_audss_clk_pm_ops = { + SET_RUNTIME_PM_OPS(sky1_audss_clk_runtime_suspend, + sky1_audss_clk_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + +static const struct sky1_audss_clks_devtype_data sky1_devtype_data = { + .reg_save = sky1_reg_save, + .reg_save_size = ARRAY_SIZE(sky1_reg_save), + .clk_names = sky1_audss_clk_names, + .clk_num = ARRAY_SIZE(sky1_audss_clk_names), + .clk_rate_default = sky1_clk_rate_default, + .clk_cfg = sky1_audss_clks, + .clk_cfg_size = ARRAY_SIZE(sky1_audss_clks), +}; + +static const struct of_device_id sky1_audss_clk_of_match[] = { + { .compatible = "cix,sky1-audss-cru", .data = &sky1_devtype_data, }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, sky1_audss_clk_of_match); + +static struct platform_driver sky1_audss_clk_driver = { + .probe = sky1_audss_clk_probe, + .driver = { + .name = "sky1-audss-clk", + .suppress_bind_attrs = true, + .of_match_table = sky1_audss_clk_of_match, + .pm = pm_ptr(&sky1_audss_clk_pm_ops), + }, +}; +module_platform_driver(sky1_audss_clk_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Joakim Zhang "); +MODULE_DESCRIPTION("Cixtech Sky1 Audio Subsystem Clock Controller Driver"); diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c index 1cae974e6d1d..8ddb50c67757 100644 --- a/drivers/clk/clk-bd718x7.c +++ b/drivers/clk/clk-bd718x7.c @@ -147,12 +147,12 @@ static int bd71837_clk_probe(struct platform_device *pdev) } static const struct platform_device_id bd718x7_clk_id[] = { - { "bd71837-clk", ROHM_CHIP_TYPE_BD71837 }, - { "bd71847-clk", ROHM_CHIP_TYPE_BD71847 }, - { "bd71828-clk", ROHM_CHIP_TYPE_BD71828 }, - { "bd71815-clk", ROHM_CHIP_TYPE_BD71815 }, - { "bd72720-clk", ROHM_CHIP_TYPE_BD72720 }, - { }, + { .name = "bd71837-clk", .driver_data = ROHM_CHIP_TYPE_BD71837 }, + { .name = "bd71847-clk", .driver_data = ROHM_CHIP_TYPE_BD71847 }, + { .name = "bd71828-clk", .driver_data = ROHM_CHIP_TYPE_BD71828 }, + { .name = "bd71815-clk", .driver_data = ROHM_CHIP_TYPE_BD71815 }, + { .name = "bd72720-clk", .driver_data = ROHM_CHIP_TYPE_BD72720 }, + { } }; MODULE_DEVICE_TABLE(platform, bd718x7_clk_id); diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c index b7063cf5c5c1..828125a8610b 100644 --- a/drivers/clk/clk-cdce706.c +++ b/drivers/clk/clk-cdce706.c @@ -679,7 +679,7 @@ MODULE_DEVICE_TABLE(of, cdce706_dt_match); #endif static const struct i2c_device_id cdce706_id[] = { - { "cdce706" }, + { .name = "cdce706" }, { } }; MODULE_DEVICE_TABLE(i2c, cdce706_id); diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c index 0b2ad21e6e4d..30d0493c7718 100644 --- a/drivers/clk/clk-cdce925.c +++ b/drivers/clk/clk-cdce925.c @@ -826,10 +826,10 @@ static const struct clk_cdce925_chip_info clk_cdce949_info = { }; static const struct i2c_device_id cdce925_id[] = { - { "cdce913", (kernel_ulong_t)&clk_cdce913_info }, - { "cdce925", (kernel_ulong_t)&clk_cdce925_info }, - { "cdce937", (kernel_ulong_t)&clk_cdce937_info }, - { "cdce949", (kernel_ulong_t)&clk_cdce949_info }, + { .name = "cdce913", .driver_data = (kernel_ulong_t)&clk_cdce913_info }, + { .name = "cdce925", .driver_data = (kernel_ulong_t)&clk_cdce925_info }, + { .name = "cdce937", .driver_data = (kernel_ulong_t)&clk_cdce937_info }, + { .name = "cdce949", .driver_data = (kernel_ulong_t)&clk_cdce949_info }, { } }; MODULE_DEVICE_TABLE(i2c, cdce925_id); diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 835b1e4e5869..11842bce5918 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -462,3 +462,4 @@ struct clk_hw *devm_clk_hw_register_composite_pdata(struct device *dev, rate_hw, rate_ops, gate_hw, gate_ops, flags); } +EXPORT_SYMBOL_GPL(devm_clk_hw_register_composite_pdata); diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c index 303a0bb26e54..550b8ae375a2 100644 --- a/drivers/clk/clk-conf.c +++ b/drivers/clk/clk-conf.c @@ -155,6 +155,78 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier) return 0; } +static int __set_clk_spread_spectrum(struct device_node *node, bool clk_supplier) +{ + u32 elem_size = sizeof(struct clk_spread_spectrum); + struct clk_spread_spectrum *sscs; + struct of_phandle_args clkspec; + int rc, count, index; + struct clk *clk; + + /* modfreq, spreadPercent, modmethod */ + count = of_property_count_elems_of_size(node, "assigned-clock-sscs", elem_size); + if (count <= 0) + return 0; + + sscs = kcalloc(count, elem_size, GFP_KERNEL); + if (!sscs) + return -ENOMEM; + + rc = of_property_read_u32_array(node, "assigned-clock-sscs", (u32 *)sscs, + count * 3); + if (rc) + goto free_sscs; + + for (index = 0; index < count; index++) { + struct clk_spread_spectrum *conf = &sscs[index]; + struct clk_hw *hw; + + if (!conf->modfreq_hz && !conf->spread_bp && !conf->method) + continue; + + rc = of_parse_phandle_with_args(node, "assigned-clocks", "#clock-cells", + index, &clkspec); + if (rc < 0) { + /* skip empty (null) phandles */ + if (rc == -ENOENT) { + rc = 0; + continue; + } else + goto free_sscs; + } + + if (clkspec.np == node && !clk_supplier) { + of_node_put(clkspec.np); + goto free_sscs; + } + + clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); + if (IS_ERR(clk)) { + if (PTR_ERR(clk) != -EPROBE_DEFER) + pr_warn("clk: couldn't get clock %d for %pOF\n", + index, node); + rc = PTR_ERR(clk); + goto free_sscs; + } + + hw = __clk_get_hw(clk); + rc = clk_hw_set_spread_spectrum(hw, conf); + if (rc < 0) { + pr_err("clk: couldn't set %s clk spread spectrum %u %u %u: %d\n", + __clk_get_name(clk), conf->modfreq_hz, conf->spread_bp, + conf->method, rc); + /* Do not fail */ + rc = 0; + } + clk_put(clk); + } + +free_sscs: + kfree(sscs); + return rc; +} + /** * of_clk_set_defaults() - parse and set assigned clocks configuration * @node: device node to apply clock settings for @@ -174,6 +246,10 @@ int of_clk_set_defaults(struct device_node *node, bool clk_supplier) if (!node) return 0; + rc = __set_clk_spread_spectrum(node, clk_supplier); + if (rc < 0) + return rc; + rc = __set_clk_parents(node, clk_supplier); if (rc < 0) return rc; diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c index 8800472ba63f..e415bdff4d97 100644 --- a/drivers/clk/clk-cs2000-cp.c +++ b/drivers/clk/clk-cs2000-cp.c @@ -122,8 +122,8 @@ static const struct of_device_id cs2000_of_match[] = { MODULE_DEVICE_TABLE(of, cs2000_of_match); static const struct i2c_device_id cs2000_id[] = { - { "cs2000-cp", }, - {} + { .name = "cs2000-cp" }, + { } }; MODULE_DEVICE_TABLE(i2c, cs2000_id); @@ -404,11 +404,7 @@ static int cs2000_enable(struct clk_hw *hw) if (ret < 0) return ret; - ret = cs2000_wait_pll_lock(priv); - if (ret < 0) - return ret; - - return ret; + return cs2000_wait_pll_lock(priv); } static void cs2000_disable(struct clk_hw *hw) diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c index 994d5bc5168b..4cc3863bd7da 100644 --- a/drivers/clk/clk-devres.c +++ b/drivers/clk/clk-devres.c @@ -99,6 +99,11 @@ struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled); +static void devm_clk_disable_unprepare(void *data) +{ + clk_disable_unprepare(data); +} + struct clk *devm_clk_get_optional_enabled_with_rate(struct device *dev, const char *id, unsigned long rate) @@ -106,8 +111,7 @@ struct clk *devm_clk_get_optional_enabled_with_rate(struct device *dev, struct clk *clk; int ret; - clk = __devm_clk_get(dev, id, clk_get_optional, NULL, - clk_disable_unprepare); + clk = devm_clk_get_optional(dev, id); if (IS_ERR(clk)) return ERR_CAST(clk); @@ -119,6 +123,10 @@ struct clk *devm_clk_get_optional_enabled_with_rate(struct device *dev, if (ret) goto out_put_clk; + ret = devm_add_action_or_reset(dev, devm_clk_disable_unprepare, clk); + if (ret) + goto out_put_clk; + return clk; out_put_clk: @@ -222,6 +230,13 @@ err_clk_get: return ret; } +int __must_check devm_clk_bulk_get_enable(struct device *dev, int num_clks, + struct clk_bulk_data *clks) +{ + return __devm_clk_bulk_get_enable(dev, num_clks, clks, false); +} +EXPORT_SYMBOL_GPL(devm_clk_bulk_get_enable); + int __must_check devm_clk_bulk_get_optional_enable(struct device *dev, int num_clks, struct clk_bulk_data *clks) { diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index b3b485d23ea8..f68216c65d3d 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -15,6 +15,7 @@ #include #include #include +#include /* * DOC: basic adjustable divider clock that cannot gate @@ -301,6 +302,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent, int i, bestdiv = 0; unsigned long parent_rate, best = 0, now, maxdiv; unsigned long parent_rate_saved = *best_parent_rate; + unsigned long target_parent_rate; if (!rate) rate = 1; @@ -315,15 +317,11 @@ static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent, return bestdiv; } - /* - * The maximum divider we can use without overflowing - * unsigned long in rate * i below - */ - maxdiv = min(ULONG_MAX / rate, maxdiv); - for (i = _next_div(table, 0, flags); i <= maxdiv; i = _next_div(table, i, flags)) { - if (rate * i == parent_rate_saved) { + bool overflow = check_mul_overflow(rate, (unsigned long)i, &target_parent_rate); + + if (!overflow && target_parent_rate == parent_rate_saved) { /* * It's the most ideal case if the requested rate can be * divided from parent clock without needing to change @@ -332,13 +330,24 @@ static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent, *best_parent_rate = parent_rate_saved; return i; } - parent_rate = clk_hw_round_rate(parent, rate * i); + /* + * Clamp target_parent_rate to ULONG_MAX on overflow. The true + * required parent rate exceeds what can be represented, so ask + * the parent for the highest rate it can produce. There is no + * point continuing the loop past this since larger dividers + * only move further from the requested rate. + */ + if (overflow) + target_parent_rate = ULONG_MAX; + parent_rate = clk_hw_round_rate(parent, target_parent_rate); now = DIV_ROUND_UP_ULL((u64)parent_rate, i); if (_is_best_div(rate, now, best, flags)) { bestdiv = i; best = now; *best_parent_rate = parent_rate; } + if (overflow) + break; } if (!bestdiv) { diff --git a/drivers/clk/clk-divider_test.c b/drivers/clk/clk-divider_test.c new file mode 100644 index 000000000000..8ee1614128d0 --- /dev/null +++ b/drivers/clk/clk-divider_test.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit tests for clk_divider_bestdiv() + */ +#include +#include +#include +#include +#include + +#define PARENT_RATE_1GHZ GIGA +#define PARENT_RATE_2GHZ (2 * GIGA) +#define PARENT_RATE_4GHZ (4 * GIGA) + +KUNIT_DEFINE_ACTION_WRAPPER(clk_hw_unregister_fixed_rate_wrapper, + clk_hw_unregister_fixed_rate, struct clk_hw *); +KUNIT_DEFINE_ACTION_WRAPPER(clk_hw_unregister_divider_wrapper, + clk_hw_unregister_divider, struct clk_hw *); +KUNIT_DEFINE_ACTION_WRAPPER(clk_hw_unregister_mux_wrapper, + clk_hw_unregister_mux, struct clk_hw *); + +static const struct clk_div_table bestdiv_table[] = { + { .val = 0, .div = 2 }, + { .val = 1, .div = 4 }, + { .val = 2, .div = 8 }, + { /* sentinel */ } +}; + +/* + * Test that clk_round_rate(clk, ULONG_MAX) returns the maximum achievable + * rate for a divider clock. + */ +static void clk_divider_bestdiv_ulong_max_returns_max_rate(struct kunit *test) +{ + struct clk_hw *parent_hw, *div_hw; + unsigned long rate; + u32 *fake_reg; + + fake_reg = kunit_kzalloc(test, sizeof(*fake_reg), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fake_reg); + + parent_hw = clk_hw_register_fixed_rate(NULL, "bestdiv-parent", + NULL, 0, PARENT_RATE_1GHZ); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_hw); + KUNIT_ASSERT_EQ(test, 0, + kunit_add_action_or_reset(test, clk_hw_unregister_fixed_rate_wrapper, + parent_hw)); + + div_hw = clk_hw_register_divider_table(NULL, "bestdiv-div", + "bestdiv-parent", + CLK_SET_RATE_PARENT, + (void __iomem __force *)fake_reg, + 0, 2, 0, bestdiv_table, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, div_hw); + KUNIT_ASSERT_EQ(test, 0, + kunit_add_action_or_reset(test, clk_hw_unregister_divider_wrapper, + div_hw)); + + /* + * ULONG_MAX is the canonical way to probe the maximum rate a clock + * can produce. + */ + rate = clk_hw_round_rate(div_hw, ULONG_MAX); + KUNIT_EXPECT_EQ(test, rate, PARENT_RATE_1GHZ / 2); +} + +/* + * Test that clk_round_rate(clk, ULONG_MAX) returns the correct maximum rate + * when a mux clock sits between a divider and its parent candidates. + * + * Topology: + * + * [fixed 4 GHz] --\ + * +--> [mux CLK_SET_RATE_PARENT] --> [div {2,4,8} CLK_SET_RATE_PARENT] + * [fixed 2 GHz] --/ + * + */ +static void clk_divider_bestdiv_mux_ulong_max_returns_max_rate(struct kunit *test) +{ + static const char * const mux_parents[] = { + "bestdiv-mux-parent-a", + "bestdiv-mux-parent-b", + }; + struct clk_hw *parent_a_hw, *parent_b_hw, *mux_hw, *div_hw; + u32 *fake_reg_mux, *fake_reg_div; + unsigned long rate; + + fake_reg_mux = kunit_kzalloc(test, sizeof(*fake_reg_mux), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fake_reg_mux); + + fake_reg_div = kunit_kzalloc(test, sizeof(*fake_reg_div), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fake_reg_div); + + /* Higher-rate parent: the mux should select this for ULONG_MAX. */ + parent_a_hw = clk_hw_register_fixed_rate(NULL, "bestdiv-mux-parent-a", + NULL, 0, PARENT_RATE_4GHZ); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_a_hw); + KUNIT_ASSERT_EQ(test, 0, + kunit_add_action_or_reset(test, clk_hw_unregister_fixed_rate_wrapper, + parent_a_hw)); + + /* Lower-rate parent: should not be selected. */ + parent_b_hw = clk_hw_register_fixed_rate(NULL, "bestdiv-mux-parent-b", + NULL, 0, PARENT_RATE_2GHZ); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_b_hw); + KUNIT_ASSERT_EQ(test, 0, + kunit_add_action_or_reset(test, clk_hw_unregister_fixed_rate_wrapper, + parent_b_hw)); + + /* + * 1-bit mux register selects between the two parents. + * CLK_SET_RATE_PARENT allows the divider's rate request to + * propagate into clk_mux_determine_rate(). + */ + mux_hw = clk_hw_register_mux(NULL, "bestdiv-mux", + mux_parents, ARRAY_SIZE(mux_parents), + CLK_SET_RATE_PARENT, + (void __iomem __force *)fake_reg_mux, + 0, 1, 0, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mux_hw); + KUNIT_ASSERT_EQ(test, 0, + kunit_add_action_or_reset(test, clk_hw_unregister_mux_wrapper, + mux_hw)); + + div_hw = clk_hw_register_divider_table(NULL, "bestdiv-mux-div", + "bestdiv-mux", + CLK_SET_RATE_PARENT, + (void __iomem __force *)fake_reg_div, + 0, 2, 0, bestdiv_table, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, div_hw); + KUNIT_ASSERT_EQ(test, 0, + kunit_add_action_or_reset(test, clk_hw_unregister_divider_wrapper, + div_hw)); + + rate = clk_hw_round_rate(div_hw, ULONG_MAX); + KUNIT_EXPECT_EQ(test, rate, PARENT_RATE_4GHZ / 2); +} + +static struct kunit_case clk_divider_bestdiv_test_cases[] = { + KUNIT_CASE(clk_divider_bestdiv_ulong_max_returns_max_rate), + KUNIT_CASE(clk_divider_bestdiv_mux_ulong_max_returns_max_rate), + {} +}; + +static struct kunit_suite clk_divider_bestdiv_test_suite = { + .name = "clk_divider_bestdiv", + .test_cases = clk_divider_bestdiv_test_cases, +}; + +kunit_test_suite(clk_divider_bestdiv_test_suite); + +MODULE_DESCRIPTION("KUnit tests for clk divider"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index 1ab0e2eca5d3..5c45aacb6409 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -57,6 +57,7 @@ #define REG_RST_CTRL2 0x830 #define REG_RST_CTRL1 0x834 +#define REG_PCIE_HB_RST BIT(29) #define EN751221_REG_RST_DMT 0x84 #define EN751221_REG_RST_USB 0xec @@ -338,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[] = { @@ -450,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[] = { @@ -635,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); @@ -650,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); @@ -754,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); @@ -783,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, @@ -853,6 +870,12 @@ static int en7581_clk_hw_init(struct platform_device *pdev, val = readl(base + REG_NP_SCU_PCIC); writel(val | 3, base + REG_NP_SCU_PCIC); + val = readl(base + REG_RST_CTRL1); + val |= REG_PCIE_HB_RST; + writel(val, base + REG_RST_CTRL1); + val &= ~REG_PCIE_HB_RST; + writel(val, base + REG_RST_CTRL1); + return en7581_reset_register(&pdev->dev, base, en7581_rst_map, ARRAY_SIZE(en7581_rst_map), en7581_rst_ofs); diff --git a/drivers/clk/clk-eyeq.c b/drivers/clk/clk-eyeq.c index 9743de55bdf8..cf37feccc734 100644 --- a/drivers/clk/clk-eyeq.c +++ b/drivers/clk/clk-eyeq.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * PLL clock driver for the Mobileye EyeQ5, EyeQ6L and EyeQ6H platforms. + * PLL clock driver for the Mobileye EyeQ platforms. * * This controller handles: * - Read-only PLLs, all derived from the same main crystal clock. @@ -45,67 +45,104 @@ #include #include +#include /* In frac mode, it enables fractional noise canceling DAC. Else, no function. */ -#define PCSR0_DAC_EN BIT(0) +#define FRACG_PCSR0_DAC_EN BIT(0) /* Fractional or integer mode */ -#define PCSR0_DSM_EN BIT(1) -#define PCSR0_PLL_EN BIT(2) +#define FRACG_PCSR0_DSM_EN BIT(1) +#define FRACG_PCSR0_PLL_EN BIT(2) /* All clocks output held at 0 */ -#define PCSR0_FOUTPOSTDIV_EN BIT(3) -#define PCSR0_POST_DIV1 GENMASK(6, 4) -#define PCSR0_POST_DIV2 GENMASK(9, 7) -#define PCSR0_REF_DIV GENMASK(15, 10) -#define PCSR0_INTIN GENMASK(27, 16) -#define PCSR0_BYPASS BIT(28) +#define FRACG_PCSR0_FOUTPOSTDIV_EN BIT(3) +#define FRACG_PCSR0_POST_DIV1 GENMASK(6, 4) +#define FRACG_PCSR0_POST_DIV2 GENMASK(9, 7) +#define FRACG_PCSR0_REF_DIV GENMASK(15, 10) +#define FRACG_PCSR0_INTIN GENMASK(27, 16) +#define FRACG_PCSR0_BYPASS BIT(28) /* Bits 30..29 are reserved */ -#define PCSR0_PLL_LOCKED BIT(31) +#define FRACG_PCSR0_PLL_LOCKED BIT(31) -#define PCSR1_RESET BIT(0) -#define PCSR1_SSGC_DIV GENMASK(4, 1) +#define FRACG_PCSR1_RESET BIT(0) +#define FRACG_PCSR1_SSGC_DIV GENMASK(4, 1) /* Spread amplitude (% = 0.1 * SPREAD[4:0]) */ -#define PCSR1_SPREAD GENMASK(9, 5) -#define PCSR1_DIS_SSCG BIT(10) +#define FRACG_PCSR1_SPREAD GENMASK(9, 5) +#define FRACG_PCSR1_DIS_SSCG BIT(10) /* Down-spread or center-spread */ -#define PCSR1_DOWN_SPREAD BIT(11) -#define PCSR1_FRAC_IN GENMASK(31, 12) +#define FRACG_PCSR1_DOWN_SPREAD BIT(11) +#define FRACG_PCSR1_FRAC_IN GENMASK(31, 12) -struct eqc_pll { - unsigned int index; - const char *name; - unsigned int reg64; -}; +#define JFRACR_PCSR0_BYPASS BIT(0) +#define JFRACR_PCSR0_PLL_EN BIT(1) +#define JFRACR_PCSR0_FOUTVCO_EN BIT(2) +#define JFRACR_PCSR0_FOUTPOSTDIV_EN BIT(3) +#define JFRACR_PCSR0_POST_DIV1 GENMASK(6, 4) +#define JFRACR_PCSR0_POST_DIV2 GENMASK(9, 7) +#define JFRACR_PCSR0_REF_DIV GENMASK(15, 10) +#define JFRACR_PCSR0_FB_DIV GENMASK(27, 16) +#define JFRACR_PCSR0_VCO_SEL GENMASK(29, 28) +#define JFRACR_PCSR0_PLL_LOCKED GENMASK(31, 30) + +#define JFRACR_PCSR1_FRAC_IN GENMASK(23, 0) +#define JFRACR_PCSR1_FOUT4PHASE_EN BIT(24) +#define JFRACR_PCSR1_DAC_EN BIT(25) +#define JFRACR_PCSR1_DSM_EN BIT(26) +/* Bits 31..27 are reserved */ +#define JFRACR_PCSR2_RESET BIT(0) +#define JFRACR_PCSR2_DIS_SSCG BIT(1) +#define JFRACR_PCSR2_DOWN_SPREAD BIT(2) +#define JFRACR_PCSR2_SSGC_DIV GENMASK(7, 4) +#define JFRACR_PCSR2_SPREAD GENMASK(12, 8) +/* Bits 31..13 are reserved */ + +#define AINTP_PCSR_BYPASS BIT(0) +#define AINTP_PCSR_PLL_EN BIT(1) +#define AINTP_PCSR_FOUTVCO_EN BIT(2) +#define AINTP_PCSR_FOUTPOSTDIV_EN BIT(3) +#define AINTP_PCSR_POST_DIV1 GENMASK(6, 4) +#define AINTP_PCSR_POST_DIV2 GENMASK(9, 7) +#define AINTP_PCSR_REF_DIV GENMASK(15, 10) +#define AINTP_PCSR_FB_DIV GENMASK(27, 16) +#define AINTP_PCSR_VCO_SEL GENMASK(29, 28) +/* bit 30 is reserved */ +#define AINTP_PCSR_PLL_LOCKED BIT(31) /* - * Divider clock. Divider is 2*(v+1), with v the register value. - * Min divider is 2, max is 2*(2^width). + * Special index values to lookup a parent clock by its name + * from the device tree or by its globally unique name. */ -struct eqc_div { - unsigned int index; - const char *name; - unsigned int parent; - unsigned int reg; - u8 shift; - u8 width; -}; +#define PARENT_BY_FWNAME (-1) +#define PARENT_BY_NAME (-2) -struct eqc_fixed_factor { - unsigned int index; +struct eqc_clock { + int index; + int parent_idx; const char *name; - unsigned int mult; - unsigned int div; - unsigned int parent; + const char *parent_name; + int (*probe)(struct device *dev, struct device_node *np, + const struct eqc_clock *clk, void __iomem *base, + struct clk_hw_onecell_data *cells); + void (*unregister)(struct clk_hw *hw); + union { + struct { + unsigned int reg; + u8 shift; + u8 width; + unsigned long flags; + const struct clk_div_table *table; + } div; + struct { + unsigned int mult; + unsigned int div; + } ff; + struct { + unsigned int reg; + } pll; + }; }; struct eqc_match_data { - unsigned int pll_count; - const struct eqc_pll *plls; - - unsigned int div_count; - const struct eqc_div *divs; - - unsigned int fixed_factor_count; - const struct eqc_fixed_factor *fixed_factors; + unsigned int clk_count; + const struct eqc_clock *clks; const char *reset_auxdev_name; const char *pinctrl_auxdev_name; @@ -115,11 +152,8 @@ struct eqc_match_data { }; struct eqc_early_match_data { - unsigned int early_pll_count; - const struct eqc_pll *early_plls; - - unsigned int early_fixed_factor_count; - const struct eqc_fixed_factor *early_fixed_factors; + unsigned int early_clk_count; + const struct eqc_clock *early_clks; /* * We want our of_xlate callback to EPROBE_DEFER instead of dev_err() @@ -129,8 +163,10 @@ struct eqc_early_match_data { }; /* - * Both factors (mult and div) must fit in 32 bits. When an operation overflows, - * this function throws away low bits so that factors still fit in 32 bits. + * All Mobileye EyeQ SoC have 64 bits long, but both factors (mult and div) + * must fit in 32 bits as clk_fixed_factor uses unsigned int. When an + * operation overflows, this function throws away low bits so that + * factors still fit in 32 bits. * * Precision loss depends on amplitude of mult and div. Worst theoretical * loss is: (UINT_MAX+1) / UINT_MAX - 1 = 2.3e-10. @@ -161,34 +197,63 @@ static void eqc_pll_downshift_factors(unsigned long *mult, unsigned long *div) *div >>= shift; } -static int eqc_pll_parse_registers(u32 r0, u32 r1, unsigned long *mult, - unsigned long *div, unsigned long *acc) +static int eqc_pll_parse_aintp(void __iomem *base, unsigned long *mult, unsigned long *div) +{ + u32 r0; + + r0 = readl(base); + if (r0 & AINTP_PCSR_BYPASS) { + *mult = 1; + *div = 1; + return 0; + } + + if (!(r0 & AINTP_PCSR_PLL_LOCKED)) + return -EINVAL; + + *mult = FIELD_GET(AINTP_PCSR_FB_DIV, r0); + *div = FIELD_GET(AINTP_PCSR_REF_DIV, r0); + + if (!*mult || !*div) + return -EINVAL; + + return 0; +} + +static int eqc_pll_parse_fracg(void __iomem *base, unsigned long *mult, + unsigned long *div, unsigned long *acc) { unsigned long spread; + u32 r0, r1; + u64 val; - if (r0 & PCSR0_BYPASS) { + val = readq(base); + r0 = val; + r1 = val >> 32; + + if (r0 & FRACG_PCSR0_BYPASS) { *mult = 1; *div = 1; *acc = 0; return 0; } - if (!(r0 & PCSR0_PLL_LOCKED)) + if (!(r0 & FRACG_PCSR0_PLL_LOCKED)) return -EINVAL; - *mult = FIELD_GET(PCSR0_INTIN, r0); - *div = FIELD_GET(PCSR0_REF_DIV, r0); + *mult = FIELD_GET(FRACG_PCSR0_INTIN, r0); + *div = FIELD_GET(FRACG_PCSR0_REF_DIV, r0); /* Fractional mode, in 2^20 (0x100000) parts. */ - if (r0 & PCSR0_DSM_EN) { + if (r0 & FRACG_PCSR0_DSM_EN) { *div *= (1ULL << 20); - *mult = *mult * (1ULL << 20) + FIELD_GET(PCSR1_FRAC_IN, r1); + *mult = *mult * (1ULL << 20) + FIELD_GET(FRACG_PCSR1_FRAC_IN, r1); } if (!*mult || !*div) return -EINVAL; - if (r1 & (PCSR1_RESET | PCSR1_DIS_SSCG)) { + if (r1 & (FRACG_PCSR1_RESET | FRACG_PCSR1_DIS_SSCG)) { *acc = 0; return 0; } @@ -203,10 +268,10 @@ static int eqc_pll_parse_registers(u32 r0, u32 r1, unsigned long *mult, * * Care is taken to avoid overflowing or losing precision. */ - spread = FIELD_GET(PCSR1_SPREAD, r1); + spread = FIELD_GET(FRACG_PCSR1_SPREAD, r1); *acc = DIV_ROUND_CLOSEST(spread * 1000000000, 1024 * 2); - if (r1 & PCSR1_DOWN_SPREAD) { + if (r1 & FRACG_PCSR1_DOWN_SPREAD) { /* * Downspreading: the central frequency is half a * spread lower. @@ -224,101 +289,58 @@ static int eqc_pll_parse_registers(u32 r0, u32 r1, unsigned long *mult, return 0; } -static void eqc_probe_init_plls(struct device *dev, const struct eqc_match_data *data, - void __iomem *base, struct clk_hw_onecell_data *cells) +static int eqc_pll_parse_jfracr(void __iomem *base, unsigned long *mult, + unsigned long *div, unsigned long *acc) { - unsigned long mult, div, acc; - const struct eqc_pll *pll; - struct clk_hw *hw; - unsigned int i; - u32 r0, r1; + unsigned long spread; + u32 r0, r1, r2; u64 val; - int ret; - for (i = 0; i < data->pll_count; i++) { - pll = &data->plls[i]; + val = readq(base); + r0 = val; + r1 = val >> 32; + r2 = readl(base + 8); - val = readq(base + pll->reg64); - r0 = val; - r1 = val >> 32; - - ret = eqc_pll_parse_registers(r0, r1, &mult, &div, &acc); - if (ret) { - dev_warn(dev, "failed parsing state of %s\n", pll->name); - cells->hws[pll->index] = ERR_PTR(ret); - continue; - } - - hw = clk_hw_register_fixed_factor_with_accuracy_fwname(dev, - dev->of_node, pll->name, "ref", 0, mult, div, acc); - cells->hws[pll->index] = hw; - if (IS_ERR(hw)) - dev_warn(dev, "failed registering %s: %pe\n", pll->name, hw); + if (r0 & JFRACR_PCSR0_BYPASS) { + *mult = 1; + *div = 1; + *acc = 0; + return 0; } -} -static void eqc_probe_init_divs(struct device *dev, const struct eqc_match_data *data, - void __iomem *base, struct clk_hw_onecell_data *cells) -{ - struct clk_parent_data parent_data = { }; - const struct eqc_div *div; - struct clk_hw *parent; - void __iomem *reg; - struct clk_hw *hw; - unsigned int i; + /* Consider the PLL locked if either the phase or the frequency is locked */ + if (!(r0 & JFRACR_PCSR0_PLL_LOCKED)) + return -EINVAL; - for (i = 0; i < data->div_count; i++) { - div = &data->divs[i]; - reg = base + div->reg; - parent = cells->hws[div->parent]; + *mult = FIELD_GET(JFRACR_PCSR0_FB_DIV, r0); + *div = FIELD_GET(JFRACR_PCSR0_REF_DIV, r0); - if (IS_ERR(parent)) { - /* Parent is in early clk provider. */ - parent_data.index = div->parent; - parent_data.hw = NULL; - } else { - /* Avoid clock lookup when we already have the hw reference. */ - parent_data.index = 0; - parent_data.hw = parent; - } - - hw = clk_hw_register_divider_table_parent_data(dev, div->name, - &parent_data, 0, reg, div->shift, div->width, - CLK_DIVIDER_EVEN_INTEGERS, NULL, NULL); - cells->hws[div->index] = hw; - if (IS_ERR(hw)) - dev_warn(dev, "failed registering %s: %pe\n", - div->name, hw); + /* fractional part on 24 bits */ + if (r1 & JFRACR_PCSR1_DSM_EN) { + *div *= (1ULL << 24); + *mult = *mult * (1ULL << 24) + FIELD_GET(JFRACR_PCSR1_FRAC_IN, r1); } -} -static void eqc_probe_init_fixed_factors(struct device *dev, - const struct eqc_match_data *data, - struct clk_hw_onecell_data *cells) -{ - const struct eqc_fixed_factor *ff; - struct clk_hw *hw, *parent_hw; - unsigned int i; + if (!*mult || !*div) + return -EINVAL; - for (i = 0; i < data->fixed_factor_count; i++) { - ff = &data->fixed_factors[i]; - parent_hw = cells->hws[ff->parent]; + if (r2 & (JFRACR_PCSR2_RESET | JFRACR_PCSR2_DIS_SSCG)) { + *acc = 0; + } else { + /* spread spectrum is identical to FRACG PLL */ + spread = FIELD_GET(JFRACR_PCSR2_SPREAD, r2); + *acc = DIV_ROUND_CLOSEST(spread * 1000000000, 1024 * 2); - if (IS_ERR(parent_hw)) { - /* Parent is in early clk provider. */ - hw = clk_hw_register_fixed_factor_index(dev, ff->name, - ff->parent, 0, ff->mult, ff->div); - } else { - /* Avoid clock lookup when we already have the hw reference. */ - hw = clk_hw_register_fixed_factor_parent_hw(dev, ff->name, - parent_hw, 0, ff->mult, ff->div); + if (r2 & JFRACR_PCSR2_DOWN_SPREAD) { + *mult *= 2048 - spread; + *div *= 2048; } - - cells->hws[ff->index] = hw; - if (IS_ERR(hw)) - dev_warn(dev, "failed registering %s: %pe\n", - ff->name, hw); } + + /* make sure mult and div fit in 32 bits */ + eqc_pll_downshift_factors(mult, div); + + return 0; } static void eqc_auxdev_create_optional(struct device *dev, void __iomem *base, @@ -335,6 +357,155 @@ static void eqc_auxdev_create_optional(struct device *dev, void __iomem *base, } } +static int eqc_fill_parent_data(const struct eqc_clock *clk, + struct clk_hw_onecell_data *cells, + struct clk_parent_data *parent_data) +{ + int pidx = clk->parent_idx; + + memset(parent_data, 0, sizeof(struct clk_parent_data)); + + if (pidx == PARENT_BY_FWNAME) { + /* lookup the parent clock by its fw_name */ + parent_data->index = -1; + parent_data->fw_name = clk->parent_name; + } else if (pidx == PARENT_BY_NAME) { + /* lookup the parent clock by its global name */ + parent_data->index = -1; + parent_data->name = clk->parent_name; + } else if (pidx >= 0 && pidx < cells->num && !IS_ERR(cells->hws[pidx])) { + /* get the parent hw directly */ + parent_data->hw = cells->hws[pidx]; + } else { + /* no parent lookup by index: explicitly fail */ + return -EINVAL; + } + + return 0; +} + +static int eqc_probe_divider(struct device *dev, struct device_node *np, + const struct eqc_clock *clk, void __iomem *base, + struct clk_hw_onecell_data *cells) +{ + struct clk_parent_data parent_data; + struct clk_hw *hw; + int ret; + + ret = eqc_fill_parent_data(clk, cells, &parent_data); + if (ret) + return ret; + + hw = clk_hw_register_divider_table_parent_data(dev, clk->name, + &parent_data, 0, base + clk->div.reg, clk->div.shift, + clk->div.width, clk->div.flags, clk->div.table, NULL); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + cells->hws[clk->index] = hw; + return 0; +} + +static int eqc_probe_fixed_factor(struct device *dev, struct device_node *np, + const struct eqc_clock *clk, void __iomem *base, + struct clk_hw_onecell_data *cells) +{ + struct clk_parent_data parent_data; + struct clk_hw *hw; + int ret; + + ret = eqc_fill_parent_data(clk, cells, &parent_data); + if (ret) + return ret; + + hw = clk_hw_register_fixed_factor_pdata(dev, np, clk->name, &parent_data, 0, + clk->ff.mult, clk->ff.div, 0, 0); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + cells->hws[clk->index] = hw; + return 0; +} + +static int eqc_probe_pll_aintp(struct device *dev, struct device_node *np, + const struct eqc_clock *clk, void __iomem *base, + struct clk_hw_onecell_data *cells) +{ + struct clk_parent_data parent_data = { }; + unsigned long mult, div; + struct clk_hw *hw; + int ret; + + ret = eqc_pll_parse_aintp(base + clk->pll.reg, &mult, &div); + if (ret) + return ret; + + ret = eqc_fill_parent_data(clk, cells, &parent_data); + if (ret) + return ret; + + hw = clk_hw_register_fixed_factor_pdata(dev, np, clk->name, &parent_data, + 0, mult, div, 0, 0); + + if (IS_ERR(hw)) + return PTR_ERR(hw); + + cells->hws[clk->index] = hw; + return 0; +} + +static int eqc_probe_pll_fracg(struct device *dev, struct device_node *np, + const struct eqc_clock *clk, void __iomem *base, + struct clk_hw_onecell_data *cells) +{ + struct clk_parent_data parent_data; + unsigned long mult, div, acc; + struct clk_hw *hw; + int ret; + + ret = eqc_pll_parse_fracg(base + clk->pll.reg, &mult, &div, &acc); + if (ret) + return ret; + + ret = eqc_fill_parent_data(clk, cells, &parent_data); + if (ret) + return ret; + + hw = clk_hw_register_fixed_factor_pdata(dev, np, clk->name, &parent_data, 0, mult, + div, acc, CLK_FIXED_FACTOR_FIXED_ACCURACY); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + cells->hws[clk->index] = hw; + return 0; +} + +static int eqc_probe_pll_jfracr(struct device *dev, struct device_node *np, + const struct eqc_clock *clk, void __iomem *base, + struct clk_hw_onecell_data *cells) +{ + struct clk_parent_data parent_data = { }; + unsigned long mult, div, acc; + struct clk_hw *hw; + int ret; + + ret = eqc_pll_parse_jfracr(base + clk->pll.reg, &mult, &div, &acc); + if (ret) + return ret; + + ret = eqc_fill_parent_data(clk, cells, &parent_data); + if (ret) + return ret; + + hw = clk_hw_register_fixed_factor_pdata(dev, np, clk->name, &parent_data, 0, mult, + div, acc, CLK_FIXED_FACTOR_FIXED_ACCURACY); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + cells->hws[clk->index] = hw; + return 0; +} + static int eqc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -344,6 +515,7 @@ static int eqc_probe(struct platform_device *pdev) unsigned int i, clk_count; struct resource *res; void __iomem *base; + int ret; data = device_get_match_data(dev); if (!data) @@ -362,11 +534,10 @@ static int eqc_probe(struct platform_device *pdev) eqc_auxdev_create_optional(dev, base, data->pinctrl_auxdev_name); eqc_auxdev_create_optional(dev, base, data->eth_phy_auxdev_name); - if (data->pll_count + data->div_count + data->fixed_factor_count == 0) + if (data->clk_count == 0) return 0; /* Zero clocks, we are done. */ - clk_count = data->pll_count + data->div_count + - data->fixed_factor_count + data->early_clk_count; + clk_count = data->clk_count + data->early_clk_count; cells = kzalloc_flex(*cells, hws, clk_count); if (!cells) return -ENOMEM; @@ -377,31 +548,96 @@ static int eqc_probe(struct platform_device *pdev) for (i = 0; i < clk_count; i++) cells->hws[i] = ERR_PTR(-EINVAL); - eqc_probe_init_plls(dev, data, base, cells); + for (i = 0; i < data->clk_count; i++) { + const struct eqc_clock *clk = &data->clks[i]; - eqc_probe_init_divs(dev, data, base, cells); - - eqc_probe_init_fixed_factors(dev, data, cells); + if (clk->probe) + ret = clk->probe(dev, NULL, clk, base, cells); + else + ret = -EINVAL; + if (ret) + dev_warn(dev, "failed probing clock %s: %d\n", clk->name, ret); + } return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, cells); } -/* Required early for GIC timer (pll-cpu) and UARTs (pll-per). */ -static const struct eqc_pll eqc_eyeq5_early_plls[] = { - { .index = EQ5C_PLL_CPU, .name = "pll-cpu", .reg64 = 0x02C }, - { .index = EQ5C_PLL_PER, .name = "pll-per", .reg64 = 0x05C }, -}; +#define DIV(_index, _parent_idx, _name, _parent_name, \ + _reg, _shift, _width) \ + { \ + .index = _index, \ + .parent_idx = _parent_idx, \ + .name = _name, \ + .parent_name = _parent_name, \ + .probe = eqc_probe_divider, \ + .unregister = clk_hw_unregister_divider, \ + .div.reg = _reg, \ + .div.shift = _shift, \ + .div.width = _width, \ + .div.flags = CLK_DIVIDER_EVEN_INTEGERS, \ + .div.table = NULL, \ + } -static const struct eqc_pll eqc_eyeq5_plls[] = { - { .index = EQ5C_PLL_VMP, .name = "pll-vmp", .reg64 = 0x034 }, - { .index = EQ5C_PLL_PMA, .name = "pll-pma", .reg64 = 0x03C }, - { .index = EQ5C_PLL_VDI, .name = "pll-vdi", .reg64 = 0x044 }, - { .index = EQ5C_PLL_DDR0, .name = "pll-ddr0", .reg64 = 0x04C }, - { .index = EQ5C_PLL_PCI, .name = "pll-pci", .reg64 = 0x054 }, - { .index = EQ5C_PLL_PMAC, .name = "pll-pmac", .reg64 = 0x064 }, - { .index = EQ5C_PLL_MPC, .name = "pll-mpc", .reg64 = 0x06C }, - { .index = EQ5C_PLL_DDR1, .name = "pll-ddr1", .reg64 = 0x074 }, -}; +#define DIV_TABLE_RO(_index, _parent_idx, _name, _parent_name, \ + _reg, _shift, _width, _table) \ + { \ + .index = _index, \ + .parent_idx = _parent_idx, \ + .name = _name, \ + .parent_name = _parent_name, \ + .probe = eqc_probe_divider, \ + .unregister = clk_hw_unregister_divider, \ + .div.reg = _reg, \ + .div.shift = _shift, \ + .div.width = _width, \ + .div.flags = CLK_DIVIDER_READ_ONLY, \ + .div.table = _table, \ + } + +#define FF(_index, _parent_idx, _name, _parent_name, _mult, _div) \ + { \ + .index = _index, \ + .parent_idx = _parent_idx, \ + .name = _name, \ + .parent_name = _parent_name, \ + .probe = eqc_probe_fixed_factor, \ + .unregister = clk_hw_unregister_fixed_factor, \ + .ff.mult = _mult, \ + .ff.div = _div, \ + } + +#define PLL_AINTP(_index, _parent_idx, _name, _parent_name, _reg) \ + { \ + .index = _index, \ + .parent_idx = _parent_idx, \ + .name = _name, \ + .parent_name = _parent_name, \ + .probe = eqc_probe_pll_aintp, \ + .unregister = clk_hw_unregister_fixed_factor, \ + .pll.reg = _reg, \ + } + +#define PLL_FRACG(_index, _parent_idx, _name, _parent_name, _reg) \ + { \ + .index = _index, \ + .parent_idx = _parent_idx, \ + .name = _name, \ + .parent_name = _parent_name, \ + .probe = eqc_probe_pll_fracg, \ + .unregister = clk_hw_unregister_fixed_factor, \ + .pll.reg = _reg, \ + } + +#define PLL_JFRACR(_index, _parent_idx, _name, _parent_name, _reg) \ + { \ + .index = _index, \ + .parent_idx = _parent_idx, \ + .name = _name, \ + .parent_name = _parent_name, \ + .probe = eqc_probe_pll_jfracr, \ + .unregister = clk_hw_unregister_fixed_factor, \ + .pll.reg = _reg, \ + } enum { /* @@ -440,267 +676,501 @@ enum { EQ5C_PER_FCMU_A, }; -static const struct eqc_fixed_factor eqc_eyeq5_early_fixed_factors[] = { - /* EQ5C_PLL_CPU children */ - { EQ5C_CPU_OCC, "occ-cpu", 1, 1, EQ5C_PLL_CPU }, - { EQ5C_CPU_SI_CSS0, "si-css0", 1, 1, EQ5C_CPU_OCC }, - { EQ5C_CPU_CORE0, "core0", 1, 1, EQ5C_CPU_SI_CSS0 }, - { EQ5C_CPU_CORE1, "core1", 1, 1, EQ5C_CPU_SI_CSS0 }, - { EQ5C_CPU_CORE2, "core2", 1, 1, EQ5C_CPU_SI_CSS0 }, - { EQ5C_CPU_CORE3, "core3", 1, 1, EQ5C_CPU_SI_CSS0 }, +/* Required early for GIC timer (pll-cpu) and UARTs (pll-per). */ +static const struct eqc_clock eqc_eyeq5_early_clks[] = { + PLL_FRACG(EQ5C_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu", "ref", 0x02C), + PLL_FRACG(EQ5C_PLL_PER, PARENT_BY_FWNAME, "pll-per", "ref", 0x05C), - /* EQ5C_PLL_PER children */ - { EQ5C_PER_OCC, "occ-periph", 1, 16, EQ5C_PLL_PER }, - { EQ5C_PER_UART, "uart", 1, 1, EQ5C_PER_OCC }, + FF(EQ5C_CPU_OCC, EQ5C_PLL_CPU, "occ-cpu", NULL, 1, 1), + FF(EQ5C_CPU_SI_CSS0, EQ5C_CPU_OCC, "si-css0", NULL, 1, 1), + FF(EQ5C_CPU_CORE0, EQ5C_CPU_SI_CSS0, "core0", NULL, 1, 1), + FF(EQ5C_CPU_CORE1, EQ5C_CPU_SI_CSS0, "core1", NULL, 1, 1), + FF(EQ5C_CPU_CORE2, EQ5C_CPU_SI_CSS0, "core2", NULL, 1, 1), + FF(EQ5C_CPU_CORE3, EQ5C_CPU_SI_CSS0, "core3", NULL, 1, 1), + + FF(EQ5C_PER_OCC, EQ5C_PLL_PER, "occ-periph", NULL, 1, 16), + FF(EQ5C_PER_UART, EQ5C_PER_OCC, "uart", NULL, 1, 1), }; -static const struct eqc_fixed_factor eqc_eyeq5_fixed_factors[] = { - /* EQ5C_PLL_CPU children */ - { EQ5C_CPU_CPC, "cpc", 1, 1, EQ5C_CPU_SI_CSS0 }, - { EQ5C_CPU_CM, "cm", 1, 1, EQ5C_CPU_SI_CSS0 }, - { EQ5C_CPU_MEM, "mem", 1, 1, EQ5C_CPU_SI_CSS0 }, - { EQ5C_CPU_OCC_ISRAM, "occ-isram", 1, 2, EQ5C_PLL_CPU }, - { EQ5C_CPU_ISRAM, "isram", 1, 1, EQ5C_CPU_OCC_ISRAM }, - { EQ5C_CPU_OCC_DBU, "occ-dbu", 1, 10, EQ5C_PLL_CPU }, - { EQ5C_CPU_SI_DBU_TP, "si-dbu-tp", 1, 1, EQ5C_CPU_OCC_DBU }, +static const struct eqc_clock eqc_eyeq5_clks[] = { + PLL_FRACG(EQ5C_PLL_VMP, PARENT_BY_FWNAME, "pll-vmp", "ref", 0x034), + PLL_FRACG(EQ5C_PLL_PMA, PARENT_BY_FWNAME, "pll-pma", "ref", 0x03C), + PLL_FRACG(EQ5C_PLL_VDI, PARENT_BY_FWNAME, "pll-vdi", "ref", 0x044), + PLL_FRACG(EQ5C_PLL_DDR0, PARENT_BY_FWNAME, "pll-ddr0", "ref", 0x04C), + PLL_FRACG(EQ5C_PLL_PCI, PARENT_BY_FWNAME, "pll-pci", "ref", 0x054), + PLL_FRACG(EQ5C_PLL_PMAC, PARENT_BY_FWNAME, "pll-pmac", "ref", 0x064), + PLL_FRACG(EQ5C_PLL_MPC, PARENT_BY_FWNAME, "pll-mpc", "ref", 0x06C), + PLL_FRACG(EQ5C_PLL_DDR1, PARENT_BY_FWNAME, "pll-ddr1", "ref", 0x074), - /* EQ5C_PLL_VDI children */ - { EQ5C_VDI_OCC_VDI, "occ-vdi", 1, 2, EQ5C_PLL_VDI }, - { EQ5C_VDI_VDI, "vdi", 1, 1, EQ5C_VDI_OCC_VDI }, - { EQ5C_VDI_OCC_CAN_SER, "occ-can-ser", 1, 16, EQ5C_PLL_VDI }, - { EQ5C_VDI_CAN_SER, "can-ser", 1, 1, EQ5C_VDI_OCC_CAN_SER }, - { EQ5C_VDI_I2C_SER, "i2c-ser", 1, 20, EQ5C_PLL_VDI }, + DIV(EQ5C_DIV_OSPI, PARENT_BY_NAME, "div-ospi", "pll-per", 0x11C, 0, 4), - /* EQ5C_PLL_PER children */ - { EQ5C_PER_PERIPH, "periph", 1, 1, EQ5C_PER_OCC }, - { EQ5C_PER_CAN, "can", 1, 1, EQ5C_PER_OCC }, - { EQ5C_PER_SPI, "spi", 1, 1, EQ5C_PER_OCC }, - { EQ5C_PER_I2C, "i2c", 1, 1, EQ5C_PER_OCC }, - { EQ5C_PER_TIMER, "timer", 1, 1, EQ5C_PER_OCC }, - { EQ5C_PER_GPIO, "gpio", 1, 1, EQ5C_PER_OCC }, - { EQ5C_PER_EMMC, "emmc-sys", 1, 10, EQ5C_PLL_PER }, - { EQ5C_PER_CCF, "ccf-ctrl", 1, 4, EQ5C_PLL_PER }, - { EQ5C_PER_OCC_MJPEG, "occ-mjpeg", 1, 2, EQ5C_PLL_PER }, - { EQ5C_PER_HSM, "hsm", 1, 1, EQ5C_PER_OCC_MJPEG }, - { EQ5C_PER_MJPEG, "mjpeg", 1, 1, EQ5C_PER_OCC_MJPEG }, - { EQ5C_PER_FCMU_A, "fcmu-a", 1, 20, EQ5C_PLL_PER }, - { EQ5C_PER_OCC_PCI, "occ-pci-sys", 1, 8, EQ5C_PLL_PER }, -}; + FF(EQ5C_CPU_CPC, PARENT_BY_NAME, "cpc", "si-css0", 1, 1), + FF(EQ5C_CPU_CM, PARENT_BY_NAME, "cm", "si-css0", 1, 1), + FF(EQ5C_CPU_MEM, PARENT_BY_NAME, "mem", "si-css0", 1, 1), + FF(EQ5C_CPU_OCC_ISRAM, PARENT_BY_NAME, "occ-isram", "pll-cpu", 1, 2), + FF(EQ5C_CPU_ISRAM, EQ5C_CPU_OCC_ISRAM, "isram", NULL, 1, 1), + FF(EQ5C_CPU_OCC_DBU, PARENT_BY_NAME, "occ-dbu", "pll-cpu", 1, 10), + FF(EQ5C_CPU_SI_DBU_TP, EQ5C_CPU_OCC_DBU, "si-dbu-tp", NULL, 1, 1), -static const struct eqc_div eqc_eyeq5_divs[] = { - { - .index = EQ5C_DIV_OSPI, - .name = "div-ospi", - .parent = EQ5C_PLL_PER, - .reg = 0x11C, - .shift = 0, - .width = 4, - }, + FF(EQ5C_VDI_OCC_VDI, PARENT_BY_NAME, "occ-vdi", "pll-vdi", 1, 2), + FF(EQ5C_VDI_VDI, EQ5C_VDI_OCC_VDI, "vdi", NULL, 1, 1), + FF(EQ5C_VDI_OCC_CAN_SER, PARENT_BY_NAME, "occ-can-ser", "pll-vdi", 1, 16), + FF(EQ5C_VDI_CAN_SER, EQ5C_VDI_OCC_CAN_SER, "can-ser", NULL, 1, 1), + FF(EQ5C_VDI_I2C_SER, PARENT_BY_NAME, "i2c-ser", "pll-vdi", 1, 20), + + FF(EQ5C_PER_PERIPH, PARENT_BY_NAME, "periph", "occ-periph", 1, 1), + FF(EQ5C_PER_CAN, PARENT_BY_NAME, "can", "occ-periph", 1, 1), + FF(EQ5C_PER_SPI, PARENT_BY_NAME, "spi", "occ-periph", 1, 1), + FF(EQ5C_PER_I2C, PARENT_BY_NAME, "i2c", "occ-periph", 1, 1), + FF(EQ5C_PER_TIMER, PARENT_BY_NAME, "timer", "occ-periph", 1, 1), + FF(EQ5C_PER_GPIO, PARENT_BY_NAME, "gpio", "occ-periph", 1, 1), + FF(EQ5C_PER_EMMC, PARENT_BY_NAME, "emmc-sys", "pll-per", 1, 10), + FF(EQ5C_PER_CCF, PARENT_BY_NAME, "ccf-ctrl", "pll-per", 1, 4), + FF(EQ5C_PER_OCC_MJPEG, PARENT_BY_NAME, "occ-mjpeg", "pll-per", 1, 2), + FF(EQ5C_PER_HSM, EQ5C_PER_OCC_MJPEG, "hsm", NULL, 1, 1), + FF(EQ5C_PER_MJPEG, EQ5C_PER_OCC_MJPEG, "mjpeg", NULL, 1, 1), + FF(EQ5C_PER_FCMU_A, PARENT_BY_NAME, "fcmu-a", "pll-per", 1, 20), + FF(EQ5C_PER_OCC_PCI, PARENT_BY_NAME, "occ-pci-sys", "pll-per", 1, 8), }; static const struct eqc_early_match_data eqc_eyeq5_early_match_data __initconst = { - .early_pll_count = ARRAY_SIZE(eqc_eyeq5_early_plls), - .early_plls = eqc_eyeq5_early_plls, + .early_clk_count = ARRAY_SIZE(eqc_eyeq5_early_clks), + .early_clks = eqc_eyeq5_early_clks, - .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq5_early_fixed_factors), - .early_fixed_factors = eqc_eyeq5_early_fixed_factors, - - .late_clk_count = ARRAY_SIZE(eqc_eyeq5_plls) + ARRAY_SIZE(eqc_eyeq5_divs) + - ARRAY_SIZE(eqc_eyeq5_fixed_factors), + .late_clk_count = ARRAY_SIZE(eqc_eyeq5_clks), }; static const struct eqc_match_data eqc_eyeq5_match_data = { - .pll_count = ARRAY_SIZE(eqc_eyeq5_plls), - .plls = eqc_eyeq5_plls, - - .div_count = ARRAY_SIZE(eqc_eyeq5_divs), - .divs = eqc_eyeq5_divs, - - .fixed_factor_count = ARRAY_SIZE(eqc_eyeq5_fixed_factors), - .fixed_factors = eqc_eyeq5_fixed_factors, + .clk_count = ARRAY_SIZE(eqc_eyeq5_clks), + .clks = eqc_eyeq5_clks, .reset_auxdev_name = "reset", .pinctrl_auxdev_name = "pinctrl", .eth_phy_auxdev_name = "phy", - .early_clk_count = ARRAY_SIZE(eqc_eyeq5_early_plls) + - ARRAY_SIZE(eqc_eyeq5_early_fixed_factors), + .early_clk_count = ARRAY_SIZE(eqc_eyeq5_early_clks), }; -static const struct eqc_pll eqc_eyeq6l_plls[] = { - { .index = EQ6LC_PLL_DDR, .name = "pll-ddr", .reg64 = 0x02C }, - { .index = EQ6LC_PLL_CPU, .name = "pll-cpu", .reg64 = 0x034 }, /* also acc */ - { .index = EQ6LC_PLL_PER, .name = "pll-per", .reg64 = 0x03C }, - { .index = EQ6LC_PLL_VDI, .name = "pll-vdi", .reg64 = 0x044 }, +static const struct eqc_clock eqc_eyeq6l_clks[] = { + PLL_FRACG(EQ6LC_PLL_DDR, PARENT_BY_FWNAME, "pll-ddr", "ref", 0x02C), + PLL_FRACG(EQ6LC_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu", "ref", 0x034), + PLL_FRACG(EQ6LC_PLL_PER, PARENT_BY_FWNAME, "pll-per", "ref", 0x03C), + PLL_FRACG(EQ6LC_PLL_VDI, PARENT_BY_FWNAME, "pll-vdi", "ref", 0x044), }; static const struct eqc_match_data eqc_eyeq6l_match_data = { - .pll_count = ARRAY_SIZE(eqc_eyeq6l_plls), - .plls = eqc_eyeq6l_plls, + .clk_count = ARRAY_SIZE(eqc_eyeq6l_clks), + .clks = eqc_eyeq6l_clks, .reset_auxdev_name = "reset", }; -static const struct eqc_pll eqc_eyeq6lplus_early_plls[] = { - { .index = EQ6LPC_PLL_CPU, .name = "pll-cpu", .reg64 = 0x058 }, +static const struct eqc_clock eqc_eyeq6lplus_early_clks[] = { + PLL_FRACG(EQ6LPC_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu", "ref", 0x058), + + FF(EQ6LPC_CPU_OCC, EQ6LPC_PLL_CPU, "occ-cpu", NULL, 1, 1), }; -static const struct eqc_pll eqc_eyeq6lplus_plls[] = { - { .index = EQ6LPC_PLL_DDR, .name = "pll-ddr", .reg64 = 0x02C }, - { .index = EQ6LPC_PLL_ACC, .name = "pll-acc", .reg64 = 0x034 }, - { .index = EQ6LPC_PLL_PER, .name = "pll-per", .reg64 = 0x03C }, - { .index = EQ6LPC_PLL_VDI, .name = "pll-vdi", .reg64 = 0x044 }, -}; +static const struct eqc_clock eqc_eyeq6lplus_clks[] = { + PLL_FRACG(EQ6LPC_PLL_DDR, PARENT_BY_FWNAME, "pll-ddr", "ref", 0x02C), + PLL_FRACG(EQ6LPC_PLL_ACC, PARENT_BY_FWNAME, "pll-acc", "ref", 0x034), + PLL_FRACG(EQ6LPC_PLL_PER, PARENT_BY_FWNAME, "pll-per", "ref", 0x03C), + PLL_FRACG(EQ6LPC_PLL_VDI, PARENT_BY_FWNAME, "pll-vdi", "ref", 0x044), -static const struct eqc_fixed_factor eqc_eyeq6lplus_early_fixed_factors[] = { - { EQ6LPC_CPU_OCC, "occ-cpu", 1, 1, EQ6LPC_PLL_CPU }, -}; + FF(EQ6LPC_DDR_OCC, EQ6LPC_PLL_DDR, "occ-ddr", NULL, 1, 1), -static const struct eqc_fixed_factor eqc_eyeq6lplus_fixed_factors[] = { - { EQ6LPC_DDR_OCC, "occ-ddr", 1, 1, EQ6LPC_PLL_DDR }, + FF(EQ6LPC_ACC_VDI, EQ6LPC_PLL_ACC, "vdi-div", NULL, 1, 10), + FF(EQ6LPC_ACC_OCC, EQ6LPC_PLL_ACC, "occ-acc", NULL, 1, 1), + FF(EQ6LPC_ACC_FCMU, EQ6LPC_ACC_OCC, "fcmu-a-clk", NULL, 1, 10), - { EQ6LPC_ACC_VDI, "vdi-div", 1, 10, EQ6LPC_PLL_ACC }, - { EQ6LPC_ACC_OCC, "occ-acc", 1, 1, EQ6LPC_PLL_ACC }, - { EQ6LPC_ACC_FCMU, "fcmu-a-clk", 1, 10, EQ6LPC_ACC_OCC }, + FF(EQ6LPC_PER_OCC, EQ6LPC_PLL_PER, "occ-per", NULL, 1, 1), + FF(EQ6LPC_PER_I2C_SER, EQ6LPC_PER_OCC, "i2c-ser-clk", NULL, 1, 10), + FF(EQ6LPC_PER_PCLK, EQ6LPC_PER_OCC, "pclk", NULL, 1, 4), + FF(EQ6LPC_PER_TSU, EQ6LPC_PER_OCC, "tsu-clk", NULL, 1, 8), + FF(EQ6LPC_PER_OSPI, EQ6LPC_PER_OCC, "ospi-ref-clk", NULL, 1, 10), + FF(EQ6LPC_PER_GPIO, EQ6LPC_PER_OCC, "gpio-clk", NULL, 1, 4), + FF(EQ6LPC_PER_TIMER, EQ6LPC_PER_OCC, "timer-clk", NULL, 1, 4), + FF(EQ6LPC_PER_I2C, EQ6LPC_PER_OCC, "i2c-clk", NULL, 1, 4), + FF(EQ6LPC_PER_UART, EQ6LPC_PER_OCC, "uart-clk", NULL, 1, 4), + FF(EQ6LPC_PER_SPI, EQ6LPC_PER_OCC, "spi-clk", NULL, 1, 4), + FF(EQ6LPC_PER_PERIPH, EQ6LPC_PER_OCC, "periph-clk", NULL, 1, 1), - { EQ6LPC_PER_OCC, "occ-per", 1, 1, EQ6LPC_PLL_PER }, - { EQ6LPC_PER_I2C_SER, "i2c-ser-clk", 1, 10, EQ6LPC_PER_OCC }, - { EQ6LPC_PER_PCLK, "pclk", 1, 4, EQ6LPC_PER_OCC }, - { EQ6LPC_PER_TSU, "tsu-clk", 1, 8, EQ6LPC_PER_OCC }, - { EQ6LPC_PER_OSPI, "ospi-ref-clk", 1, 10, EQ6LPC_PER_OCC }, - { EQ6LPC_PER_GPIO, "gpio-clk", 1, 4, EQ6LPC_PER_OCC }, - { EQ6LPC_PER_TIMER, "timer-clk", 1, 4, EQ6LPC_PER_OCC }, - { EQ6LPC_PER_I2C, "i2c-clk", 1, 4, EQ6LPC_PER_OCC }, - { EQ6LPC_PER_UART, "uart-clk", 1, 4, EQ6LPC_PER_OCC }, - { EQ6LPC_PER_SPI, "spi-clk", 1, 4, EQ6LPC_PER_OCC }, - { EQ6LPC_PER_PERIPH, "periph-clk", 1, 1, EQ6LPC_PER_OCC }, - - { EQ6LPC_VDI_OCC, "occ-vdi", 1, 1, EQ6LPC_PLL_VDI }, + FF(EQ6LPC_VDI_OCC, EQ6LPC_PLL_VDI, "occ-vdi", NULL, 1, 1), }; static const struct eqc_early_match_data eqc_eyeq6lplus_early_match_data __initconst = { - .early_pll_count = ARRAY_SIZE(eqc_eyeq6lplus_early_plls), - .early_plls = eqc_eyeq6lplus_early_plls, + .early_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_early_clks), + .early_clks = eqc_eyeq6lplus_early_clks, - .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq6lplus_early_fixed_factors), - .early_fixed_factors = eqc_eyeq6lplus_early_fixed_factors, - - .late_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_plls) + - ARRAY_SIZE(eqc_eyeq6lplus_fixed_factors), + .late_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_clks), }; static const struct eqc_match_data eqc_eyeq6lplus_match_data = { - .pll_count = ARRAY_SIZE(eqc_eyeq6lplus_plls), - .plls = eqc_eyeq6lplus_plls, - - .fixed_factor_count = ARRAY_SIZE(eqc_eyeq6lplus_fixed_factors), - .fixed_factors = eqc_eyeq6lplus_fixed_factors, + .clk_count = ARRAY_SIZE(eqc_eyeq6lplus_clks), + .clks = eqc_eyeq6lplus_clks, .reset_auxdev_name = "reset", .pinctrl_auxdev_name = "pinctrl", - .early_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_early_plls) + - ARRAY_SIZE(eqc_eyeq6lplus_early_fixed_factors), + .early_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_early_clks), }; static const struct eqc_match_data eqc_eyeq6h_west_match_data = { .reset_auxdev_name = "reset_west", }; -static const struct eqc_pll eqc_eyeq6h_east_plls[] = { - { .index = 0, .name = "pll-east", .reg64 = 0x074 }, +static const struct eqc_clock eqc_eyeq6h_east_clks[] = { + PLL_FRACG(0, PARENT_BY_FWNAME, "pll-east", "ref", 0x074), }; static const struct eqc_match_data eqc_eyeq6h_east_match_data = { - .pll_count = ARRAY_SIZE(eqc_eyeq6h_east_plls), - .plls = eqc_eyeq6h_east_plls, + .clk_count = ARRAY_SIZE(eqc_eyeq6h_east_clks), + .clks = eqc_eyeq6h_east_clks, .reset_auxdev_name = "reset_east", }; -static const struct eqc_pll eqc_eyeq6h_south_plls[] = { - { .index = EQ6HC_SOUTH_PLL_VDI, .name = "pll-vdi", .reg64 = 0x000 }, - { .index = EQ6HC_SOUTH_PLL_PCIE, .name = "pll-pcie", .reg64 = 0x008 }, - { .index = EQ6HC_SOUTH_PLL_PER, .name = "pll-per", .reg64 = 0x010 }, - { .index = EQ6HC_SOUTH_PLL_ISP, .name = "pll-isp", .reg64 = 0x018 }, -}; +static const struct eqc_clock eqc_eyeq6h_south_clks[] = { + PLL_FRACG(EQ6HC_SOUTH_PLL_VDI, PARENT_BY_FWNAME, "pll-vdi", "ref", 0x000), + PLL_FRACG(EQ6HC_SOUTH_PLL_PCIE, PARENT_BY_FWNAME, "pll-pcie", "ref", 0x008), + PLL_FRACG(EQ6HC_SOUTH_PLL_PER, PARENT_BY_FWNAME, "pll-per", "ref", 0x010), + PLL_FRACG(EQ6HC_SOUTH_PLL_ISP, PARENT_BY_FWNAME, "pll-isp", "ref", 0x018), -static const struct eqc_div eqc_eyeq6h_south_divs[] = { - { - .index = EQ6HC_SOUTH_DIV_EMMC, - .name = "div-emmc", - .parent = EQ6HC_SOUTH_PLL_PER, - .reg = 0x070, - .shift = 4, - .width = 4, - }, - { - .index = EQ6HC_SOUTH_DIV_OSPI_REF, - .name = "div-ospi-ref", - .parent = EQ6HC_SOUTH_PLL_PER, - .reg = 0x090, - .shift = 4, - .width = 4, - }, - { - .index = EQ6HC_SOUTH_DIV_OSPI_SYS, - .name = "div-ospi-sys", - .parent = EQ6HC_SOUTH_PLL_PER, - .reg = 0x090, - .shift = 8, - .width = 1, - }, - { - .index = EQ6HC_SOUTH_DIV_TSU, - .name = "div-tsu", - .parent = EQ6HC_SOUTH_PLL_PCIE, - .reg = 0x098, - .shift = 4, - .width = 8, - }, + DIV(EQ6HC_SOUTH_DIV_EMMC, EQ6HC_SOUTH_PLL_PER, "div-emmc", NULL, 0x070, 4, 4), + DIV(EQ6HC_SOUTH_DIV_OSPI_REF, EQ6HC_SOUTH_PLL_PER, "div-ospi-ref", NULL, 0x090, 4, 4), + DIV(EQ6HC_SOUTH_DIV_OSPI_SYS, EQ6HC_SOUTH_PLL_PER, "div-ospi-sys", NULL, 0x090, 8, 1), + DIV(EQ6HC_SOUTH_DIV_TSU, EQ6HC_SOUTH_PLL_PCIE, "div-tsu", NULL, 0x098, 4, 8), }; static const struct eqc_match_data eqc_eyeq6h_south_match_data = { - .pll_count = ARRAY_SIZE(eqc_eyeq6h_south_plls), - .plls = eqc_eyeq6h_south_plls, - - .div_count = ARRAY_SIZE(eqc_eyeq6h_south_divs), - .divs = eqc_eyeq6h_south_divs, + .clk_count = ARRAY_SIZE(eqc_eyeq6h_south_clks), + .clks = eqc_eyeq6h_south_clks, }; -static const struct eqc_pll eqc_eyeq6h_ddr0_plls[] = { - { .index = 0, .name = "pll-ddr0", .reg64 = 0x074 }, +static const struct eqc_clock eqc_eyeq6h_ddr0_clks[] = { + PLL_FRACG(0, PARENT_BY_FWNAME, "pll-ddr0", "ref", 0x074), }; static const struct eqc_match_data eqc_eyeq6h_ddr0_match_data = { - .pll_count = ARRAY_SIZE(eqc_eyeq6h_ddr0_plls), - .plls = eqc_eyeq6h_ddr0_plls, + .clk_count = ARRAY_SIZE(eqc_eyeq6h_ddr0_clks), + .clks = eqc_eyeq6h_ddr0_clks, }; -static const struct eqc_pll eqc_eyeq6h_ddr1_plls[] = { - { .index = 0, .name = "pll-ddr1", .reg64 = 0x074 }, +static const struct eqc_clock eqc_eyeq6h_ddr1_clks[] = { + PLL_FRACG(0, PARENT_BY_FWNAME, "pll-ddr1", "ref", 0x074), }; static const struct eqc_match_data eqc_eyeq6h_ddr1_match_data = { - .pll_count = ARRAY_SIZE(eqc_eyeq6h_ddr1_plls), - .plls = eqc_eyeq6h_ddr1_plls, + .clk_count = ARRAY_SIZE(eqc_eyeq6h_ddr1_clks), + .clks = eqc_eyeq6h_ddr1_clks, }; -static const struct eqc_pll eqc_eyeq6h_acc_plls[] = { - { .index = EQ6HC_ACC_PLL_XNN, .name = "pll-xnn", .reg64 = 0x040 }, - { .index = EQ6HC_ACC_PLL_VMP, .name = "pll-vmp", .reg64 = 0x050 }, - { .index = EQ6HC_ACC_PLL_PMA, .name = "pll-pma", .reg64 = 0x05C }, - { .index = EQ6HC_ACC_PLL_MPC, .name = "pll-mpc", .reg64 = 0x068 }, - { .index = EQ6HC_ACC_PLL_NOC, .name = "pll-noc", .reg64 = 0x070 }, +static const struct eqc_clock eqc_eyeq6h_acc_clks[] = { + PLL_FRACG(EQ6HC_ACC_PLL_XNN, PARENT_BY_FWNAME, "pll-xnn", "ref", 0x040), + PLL_FRACG(EQ6HC_ACC_PLL_VMP, PARENT_BY_FWNAME, "pll-vmp", "ref", 0x050), + PLL_FRACG(EQ6HC_ACC_PLL_PMA, PARENT_BY_FWNAME, "pll-pma", "ref", 0x05C), + PLL_FRACG(EQ6HC_ACC_PLL_MPC, PARENT_BY_FWNAME, "pll-mpc", "ref", 0x068), + PLL_FRACG(EQ6HC_ACC_PLL_NOC, PARENT_BY_FWNAME, "pll-noc", "ref", 0x070), }; static const struct eqc_match_data eqc_eyeq6h_acc_match_data = { - .pll_count = ARRAY_SIZE(eqc_eyeq6h_acc_plls), - .plls = eqc_eyeq6h_acc_plls, + .clk_count = ARRAY_SIZE(eqc_eyeq6h_acc_clks), + .clks = eqc_eyeq6h_acc_clks, .reset_auxdev_name = "reset_acc", }; +static const struct eqc_clock eqc_eyeq7h_acc0_clks[] = { + PLL_AINTP(EQ7HC_ACC_PLL_VMP, PARENT_BY_FWNAME, "pll-acc0-vmp", "ref_100p0", 0x400), + PLL_AINTP(EQ7HC_ACC_PLL_MPC, PARENT_BY_FWNAME, "pll-acc0-mpc", "ref_100p0", 0x404), + PLL_AINTP(EQ7HC_ACC_PLL_PMA, PARENT_BY_FWNAME, "pll-acc0-pma", "ref_100p0", 0x408), + PLL_AINTP(EQ7HC_ACC_PLL_NOC, PARENT_BY_FWNAME, "pll-acc0-noc-acc", "ref_106p6", 0x40c), + + FF(EQ7HC_ACC_DIV_PMA, EQ7HC_ACC_PLL_PMA, "acc0_pma", NULL, 1, 2), + FF(EQ7HC_ACC_DIV_NCORE, EQ7HC_ACC_PLL_NOC, "acc0_ncore", NULL, 1, 2), + FF(EQ7HC_ACC_DIV_CFG, EQ7HC_ACC_PLL_NOC, "acc0_cfg", NULL, 1, 8), +}; + +static const struct eqc_match_data eqc_eyeq7h_acc0_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_acc0_clks), + .clks = eqc_eyeq7h_acc0_clks, + + .reset_auxdev_name = "reset_acc0", +}; + +static const struct eqc_clock eqc_eyeq7h_acc1_clks[] = { + PLL_AINTP(EQ7HC_ACC_PLL_VMP, PARENT_BY_FWNAME, "pll-acc1-vmp", "ref_100p0", 0x400), + PLL_AINTP(EQ7HC_ACC_PLL_MPC, PARENT_BY_FWNAME, "pll-acc1-mpc", "ref_100p0", 0x404), + PLL_AINTP(EQ7HC_ACC_PLL_PMA, PARENT_BY_FWNAME, "pll-acc1-pma", "ref_100p0", 0x408), + PLL_AINTP(EQ7HC_ACC_PLL_NOC, PARENT_BY_FWNAME, "pll-acc1-noc-acc", "ref_106p6", 0x40c), +}; + +static const struct eqc_match_data eqc_eyeq7h_acc1_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_acc1_clks), + .clks = eqc_eyeq7h_acc1_clks, + + .reset_auxdev_name = "reset_acc1", +}; + +static const struct clk_div_table eqc_eyeq7h_ddr_apb_div_table[] = { + { .val = 0, .div = 8 }, + { .val = 1, .div = 128 }, + { .val = 0, .div = 0 }, +}; + +static const struct clk_div_table eqc_eyeq7h_ddr_ref_div_table[] = { + { .val = 0, .div = 2 }, + { .val = 1, .div = 8 }, + { .val = 0, .div = 0 }, +}; + +static const struct clk_div_table eqc_eyeq7h_ddr_dfi_div_table[] = { + { .val = 0, .div = 2 }, + { .val = 1, .div = 32 }, + { .val = 0, .div = 0 }, +}; + +static const struct eqc_clock eqc_eyeq7h_ddr0_clks[] = { + PLL_AINTP(EQ7HC_DDR_PLL, PARENT_BY_FWNAME, "pll-ddr0", "ref", 0x0), + + /* A single bit configures the 3 dividers below */ + DIV_TABLE_RO(EQ7HC_DDR_DIV_APB, EQ7HC_DDR_PLL, "div-ddr0_apb", NULL, + 0x08, 10, 1, eqc_eyeq7h_ddr_apb_div_table), + DIV_TABLE_RO(EQ7HC_DDR_DIV_PLLREF, EQ7HC_DDR_PLL, "div-ddr0_pllref", NULL, + 0x08, 10, 1, eqc_eyeq7h_ddr_ref_div_table), + DIV_TABLE_RO(EQ7HC_DDR_DIV_DFI, EQ7HC_DDR_PLL, "div-ddr0-dfi", NULL, + 0x08, 10, 1, eqc_eyeq7h_ddr_dfi_div_table), +}; + +static const struct eqc_match_data eqc_eyeq7h_ddr0_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_ddr0_clks), + .clks = eqc_eyeq7h_ddr0_clks, + + .reset_auxdev_name = "reset_ddr0", +}; + +static const struct eqc_clock eqc_eyeq7h_ddr1_clks[] = { + PLL_AINTP(EQ7HC_DDR_PLL, PARENT_BY_FWNAME, "pll-ddr1", "ref", 0x0), + + /* A single bit configures the 3 dividers below */ + DIV_TABLE_RO(EQ7HC_DDR_DIV_APB, EQ7HC_DDR_PLL, "div-ddr1_apb", NULL, + 0x08, 10, 1, eqc_eyeq7h_ddr_apb_div_table), + DIV_TABLE_RO(EQ7HC_DDR_DIV_PLLREF, EQ7HC_DDR_PLL, "div-ddr1_pllref", NULL, + 0x08, 10, 1, eqc_eyeq7h_ddr_ref_div_table), + DIV_TABLE_RO(EQ7HC_DDR_DIV_DFI, EQ7HC_DDR_PLL, "div-ddr1-dfi", NULL, + 0x08, 10, 1, eqc_eyeq7h_ddr_dfi_div_table), +}; + +static const struct eqc_match_data eqc_eyeq7h_ddr1_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_ddr1_clks), + .clks = eqc_eyeq7h_ddr1_clks, + + .reset_auxdev_name = "reset_ddr1", +}; + +static const struct eqc_clock eqc_eyeq7h_east_clocks[] = { + PLL_JFRACR(EQ7HC_EAST_PLL_106P6, PARENT_BY_FWNAME, "pll-106p6-e", "ref", 0x00), + + FF(EQ7HC_EAST_DIV_REF_106P6, EQ7HC_EAST_PLL_106P6, "ref_106p6_e", NULL, 1, 40), + + PLL_AINTP(EQ7HC_EAST_PLL_NOC, EQ7HC_EAST_DIV_REF_106P6, "pll-noc-e", NULL, 0x30), + PLL_AINTP(EQ7HC_EAST_PLL_ISP, PARENT_BY_FWNAME, "pll-isp", "ref_100p0", 0x38), + PLL_AINTP(EQ7HC_EAST_PLL_VEU, PARENT_BY_FWNAME, "pll-veu", "ref_100p0", 0x40), + + FF(EQ7HC_EAST_DIV_REF_DDR_PHY, EQ7HC_EAST_PLL_106P6, "ref_ddr_phy_e", NULL, 1, 2), + + FF(EQ7HC_EAST_DIV_CORE, EQ7HC_EAST_PLL_NOC, "core_e", NULL, 1, 2), + FF(EQ7HC_EAST_DIV_CORE_MBIST, EQ7HC_EAST_PLL_NOC, "core_mbist_e", NULL, 1, 2), + FF(EQ7HC_EAST_DIV_ISRAM_MBIST, EQ7HC_EAST_PLL_NOC, "isram_mbist_e", NULL, 1, 2), + FF(EQ7HC_EAST_DIV_CFG, EQ7HC_EAST_PLL_NOC, "cfg_e", NULL, 1, 4), + + FF(EQ7HC_EAST_DIV_VEU_CORE, EQ7HC_EAST_PLL_VEU, "veu_core", NULL, 1, 4), + FF(EQ7HC_EAST_DIV_VEU_MBIST, EQ7HC_EAST_PLL_VEU, "veu_mbist", NULL, 1, 4), + FF(EQ7HC_EAST_DIV_VEU_OCP, EQ7HC_EAST_PLL_VEU, "veu_ocp", NULL, 1, 16), + + FF(EQ7HC_EAST_DIV_LBITS, EQ7HC_EAST_PLL_ISP, "lbits_e", NULL, 1, 48), + FF(EQ7HC_EAST_DIV_ISP0_CORE, EQ7HC_EAST_PLL_ISP, "isp0_core", NULL, 1, 2), +}; + +static const struct eqc_match_data eqc_eyeq7h_east_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_east_clocks), + .clks = eqc_eyeq7h_east_clocks, + + .reset_auxdev_name = "reset_east", +}; + +static const struct eqc_clock eqc_eyeq7h_mips0_clks[] = { + PLL_AINTP(EQ7HC_MIPS_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu0", "ref", 0x0), + + FF(EQ7HC_MIPS_DIV_CM, EQ7HC_MIPS_PLL_CPU, "mips0_cm", NULL, 1, 2), +}; + +static const struct eqc_match_data eqc_eyeq7h_mips0_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_mips0_clks), + .clks = eqc_eyeq7h_mips0_clks, +}; + +static const struct eqc_clock eqc_eyeq7h_mips1_clks[] = { + PLL_AINTP(EQ7HC_MIPS_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu1", "ref", 0x0), + + FF(EQ7HC_MIPS_DIV_CM, EQ7HC_MIPS_PLL_CPU, "mips1_cm", NULL, 1, 2), +}; + +static const struct eqc_match_data eqc_eyeq7h_mips1_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_mips1_clks), + .clks = eqc_eyeq7h_mips1_clks, +}; + +static const struct eqc_clock eqc_eyeq7h_mips2_clks[] = { + PLL_AINTP(EQ7HC_MIPS_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu2", "ref", 0x0), + + FF(EQ7HC_MIPS_DIV_CM, EQ7HC_MIPS_PLL_CPU, "mips2_cm", NULL, 1, 2), +}; + +static const struct eqc_match_data eqc_eyeq7h_mips2_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_mips2_clks), + .clks = eqc_eyeq7h_mips2_clks, +}; + +static const struct eqc_clock eqc_eyeq7h_periph_east_clks[] = { + PLL_AINTP(EQ7HC_PERIPH_EAST_PLL_PER, PARENT_BY_FWNAME, "pll-periph_east_per", "ref", 0x0), + + FF(EQ7HC_PERIPH_EAST_DIV_PER, EQ7HC_PERIPH_EAST_PLL_PER, "periph_e", NULL, 1, 10), +}; + +static const struct eqc_match_data eqc_eyeq7h_periph_east_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_periph_east_clks), + .clks = eqc_eyeq7h_periph_east_clks, + + .reset_auxdev_name = "reset_periph_east", +}; + +static const struct eqc_clock eqc_eyeq7h_periph_west_clks[] = { + PLL_AINTP(EQ7HC_PERIPH_WEST_PLL_PER, PARENT_BY_FWNAME, + "pll-periph_west_per", "ref_100p0", 0x0), + PLL_AINTP(EQ7HC_PERIPH_WEST_PLL_I2S, PARENT_BY_FWNAME, + "pll-periph_west_i2s", "ref_106p6", 0x4), + + FF(EQ7HC_PERIPH_WEST_DIV_PER, EQ7HC_PERIPH_WEST_PLL_PER, "periph_w", NULL, 1, 10), + FF(EQ7HC_PERIPH_WEST_DIV_I2S, EQ7HC_PERIPH_WEST_PLL_I2S, "periph_i2s_ser_w", NULL, 1, 100), +}; + +static const struct eqc_match_data eqc_eyeq7h_periph_west_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_periph_west_clks), + .clks = eqc_eyeq7h_periph_west_clks, + + .reset_auxdev_name = "reset_periph_west", +}; + +static const struct eqc_clock eqc_eyeq7h_south_clks[] = { + PLL_JFRACR(EQ7HC_SOUTH_PLL_100P0, PARENT_BY_FWNAME, "pll-100p0", "ref", 0x40), + + FF(EQ7HC_SOUTH_DIV_REF_100P0, EQ7HC_SOUTH_PLL_100P0, "ref_100p0", NULL, 1, 48), + + PLL_AINTP(EQ7HC_SOUTH_PLL_XSPI, EQ7HC_SOUTH_DIV_REF_100P0, "pll-xspi", NULL, 0x10), + PLL_AINTP(EQ7HC_SOUTH_PLL_VDIO, EQ7HC_SOUTH_DIV_REF_100P0, "pll-vdio", NULL, 0x18), + PLL_AINTP(EQ7HC_SOUTH_PLL_PER, EQ7HC_SOUTH_DIV_REF_100P0, "pll-per-s", NULL, 0x20), + + FF(EQ7HC_SOUTH_DIV_VDO_DSI_SYS, EQ7HC_SOUTH_PLL_100P0, "vdo_dsi_sys", NULL, 1, 9), + FF(EQ7HC_SOUTH_DIV_PMA_CMN_REF, EQ7HC_SOUTH_PLL_100P0, "pma_cmn_ref", NULL, 1, 48), + FF(EQ7HC_SOUTH_DIV_REF_UFS, EQ7HC_SOUTH_PLL_100P0, "ref_ufs", NULL, 1, 250), + FF(EQ7HC_SOUTH_DIV_XSPI_SYS, EQ7HC_SOUTH_PLL_XSPI, "xspi_sys", NULL, 1, 8), + FF(EQ7HC_SOUTH_DIV_XSPI_MBIST, EQ7HC_SOUTH_PLL_XSPI, "xspi_mbist", NULL, 1, 8), + FF(EQ7HC_SOUTH_DIV_NOC_S, EQ7HC_SOUTH_PLL_PER, "noc_s", NULL, 1, 2), + FF(EQ7HC_SOUTH_DIV_PCIE_SYS, EQ7HC_SOUTH_PLL_PER, "pcie_sys", NULL, 1, 4), + FF(EQ7HC_SOUTH_DIV_PCIE_SYS_MBIST, EQ7HC_SOUTH_PLL_PER, "pcie_sys_mbist", NULL, 1, 4), + FF(EQ7HC_SOUTH_DIV_PCIE_GBE_PHY, EQ7HC_SOUTH_PLL_PER, "pcie_gbe_phy_apb", NULL, 1, 16), + FF(EQ7HC_SOUTH_DIV_UFS_CORE, EQ7HC_SOUTH_PLL_PER, "ufs_core", NULL, 1, 8), + FF(EQ7HC_SOUTH_DIV_UFS_SMS, EQ7HC_SOUTH_PLL_PER, "ufs_sms", NULL, 1, 5), + FF(EQ7HC_SOUTH_DIV_UFS_ROM_SMS, EQ7HC_SOUTH_PLL_PER, "ufs_rom_sms", NULL, 1, 5), + FF(EQ7HC_SOUTH_DIV_ETH_SYS, EQ7HC_SOUTH_PLL_PER, "eth_sys", NULL, 1, 8), + FF(EQ7HC_SOUTH_DIV_ETH_MBIST, EQ7HC_SOUTH_PLL_PER, "eth_mbist", NULL, 1, 8), + FF(EQ7HC_SOUTH_DIV_CFG_S, EQ7HC_SOUTH_PLL_PER, "cfg_s", NULL, 1, 8), + FF(EQ7HC_SOUTH_DIV_TSU, EQ7HC_SOUTH_PLL_PER, "tsu", NULL, 1, 64), + FF(EQ7HC_SOUTH_DIV_VDIO, EQ7HC_SOUTH_PLL_VDIO, "vdio", NULL, 1, 4), + FF(EQ7HC_SOUTH_DIV_VDIO_CORE, EQ7HC_SOUTH_PLL_VDIO, "vdio_core", NULL, 1, 4), + FF(EQ7HC_SOUTH_DIV_VDIO_CORE_MBIST, EQ7HC_SOUTH_PLL_VDIO, "vdio_core_mbist", NULL, 1, 4), + FF(EQ7HC_SOUTH_DIV_VDO_CORE_MBIST, EQ7HC_SOUTH_PLL_VDIO, "vdo_core_mbist", NULL, 1, 4), + FF(EQ7HC_SOUTH_DIV_VDO_P, EQ7HC_SOUTH_PLL_VDIO, "vdo_p", NULL, 1, 40), + FF(EQ7HC_SOUTH_DIV_VDIO_CFG, EQ7HC_SOUTH_PLL_VDIO, "vdio_cfg", NULL, 1, 150), + FF(EQ7HC_SOUTH_DIV_VDIO_TXCLKESC, EQ7HC_SOUTH_PLL_VDIO, "vdio_txclkesc", NULL, 1, 8), +}; + +static const struct eqc_match_data eqc_eyeq7h_south_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_south_clks), + .clks = eqc_eyeq7h_south_clks, + + .reset_auxdev_name = "reset_south", +}; + +static const struct eqc_clock eqc_eyeq7h_west_clks[] = { + PLL_JFRACR(EQ7HC_WEST_PLL_106P6, PARENT_BY_FWNAME, "pll-106p6-w", "ref", 0x0), + + FF(EQ7HC_WEST_DIV_REF_106P6, EQ7HC_WEST_PLL_106P6, "ref_106p6_w", NULL, 1, 40), + + PLL_AINTP(EQ7HC_WEST_PLL_NOC, EQ7HC_WEST_DIV_REF_106P6, "pll-noc-w", NULL, 0x30), + PLL_AINTP(EQ7HC_WEST_PLL_GPU, PARENT_BY_FWNAME, "pll-gpu", "ref_100p0", 0x38), + PLL_AINTP(EQ7HC_WEST_PLL_SSI, PARENT_BY_FWNAME, "pll-ssi", "ref_100p0", 0x40), + + FF(EQ7HC_WEST_DIV_GPU, EQ7HC_WEST_PLL_GPU, "gpu", NULL, 1, 2), + FF(EQ7HC_WEST_DIV_GPU_MBIST, EQ7HC_WEST_PLL_GPU, "gpu_mbist", NULL, 1, 2), + FF(EQ7HC_WEST_DIV_LBITS, EQ7HC_WEST_PLL_GPU, "lbits_w", NULL, 1, 40), + FF(EQ7HC_WEST_DIV_MIPS_TIMER, EQ7HC_WEST_PLL_SSI, "mips_timer", NULL, 1, 24), + FF(EQ7HC_WEST_DIV_SSI_CORE, EQ7HC_WEST_PLL_SSI, "ssi_core", NULL, 1, 2), + FF(EQ7HC_WEST_DIV_SSI_CORE_MBIST, EQ7HC_WEST_PLL_SSI, "ssi_core_mbist", NULL, 1, 2), + FF(EQ7HC_WEST_DIV_SSI_ROM, EQ7HC_WEST_PLL_SSI, "ssi_rom", NULL, 1, 8), + FF(EQ7HC_WEST_DIV_SSI_ROM_MBIST, EQ7HC_WEST_PLL_SSI, "ssi_rom_mbist", NULL, 1, 8), + FF(EQ7HC_WEST_DIV_REF_DDR_PHY, EQ7HC_WEST_PLL_106P6, "ref_ddr_phy_w", NULL, 1, 2), + FF(EQ7HC_WEST_DIV_CORE, EQ7HC_WEST_PLL_NOC, "core_w", NULL, 1, 2), + FF(EQ7HC_WEST_DIV_CORE_MBIST, EQ7HC_WEST_PLL_NOC, "core_mbist_w", NULL, 1, 2), + FF(EQ7HC_WEST_DIV_CFG, EQ7HC_WEST_PLL_NOC, "cfg_w", NULL, 1, 4), + FF(EQ7HC_WEST_DIV_CAU, EQ7HC_WEST_PLL_NOC, "cau_w", NULL, 1, 8), + FF(EQ7HC_WEST_DIV_CAU_MBIST, EQ7HC_WEST_PLL_NOC, "cau_mbist_w", NULL, 1, 8), +}; + +static const struct eqc_match_data eqc_eyeq7h_west_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_west_clks), + .clks = eqc_eyeq7h_west_clks, + + .reset_auxdev_name = "reset_west", +}; + +static const struct eqc_clock eqc_eyeq7h_xnn0_clks[] = { + PLL_AINTP(EQ7HC_XNN_PLL_XNN0, PARENT_BY_FWNAME, "pll-xnn0-0", "ref_100p0", 0x400), + PLL_AINTP(EQ7HC_XNN_PLL_XNN1, PARENT_BY_FWNAME, "pll-xnn0-1", "ref_100p0", 0x404), + PLL_AINTP(EQ7HC_XNN_PLL_XNN2, PARENT_BY_FWNAME, "pll-xnn0-2", "ref_100p0", 0x408), + PLL_AINTP(EQ7HC_XNN_PLL_CLSTR, PARENT_BY_FWNAME, "pll-xnn0-clstr", "ref_106p6", 0x410), + + FF(EQ7HC_XNN_DIV_XNN0, EQ7HC_XNN_PLL_XNN0, "xnn0", NULL, 1, 2), + FF(EQ7HC_XNN_DIV_XNN1, EQ7HC_XNN_PLL_XNN1, "xnn1", NULL, 1, 2), + FF(EQ7HC_XNN_DIV_XNN2, EQ7HC_XNN_PLL_XNN2, "xnn2", NULL, 1, 2), + FF(EQ7HC_XNN_DIV_CLSTR, EQ7HC_XNN_PLL_CLSTR, "xnn0_clstr", NULL, 1, 2), + FF(EQ7HC_XNN_DIV_I2, EQ7HC_XNN_PLL_CLSTR, "xnn0_i2", NULL, 1, 4), + FF(EQ7HC_XNN_DIV_I2_SMS, EQ7HC_XNN_PLL_CLSTR, "xnn0_i2_sms", NULL, 1, 4), + FF(EQ7HC_XNN_DIV_CFG, EQ7HC_XNN_PLL_CLSTR, "xnn0_cfg", NULL, 1, 8), +}; + +static const struct eqc_match_data eqc_eyeq7h_xnn0_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_xnn0_clks), + .clks = eqc_eyeq7h_xnn0_clks, + + .reset_auxdev_name = "reset_xnn0", +}; + +static const struct eqc_clock eqc_eyeq7h_xnn1_clks[] = { + PLL_AINTP(EQ7HC_XNN_PLL_XNN0, PARENT_BY_FWNAME, "pll-xnn1-0", "ref_100p0", 0x400), + PLL_AINTP(EQ7HC_XNN_PLL_XNN1, PARENT_BY_FWNAME, "pll-xnn1-1", "ref_100p0", 0x404), + PLL_AINTP(EQ7HC_XNN_PLL_XNN2, PARENT_BY_FWNAME, "pll-xnn1-2", "ref_100p0", 0x408), + PLL_AINTP(EQ7HC_XNN_PLL_CLSTR, PARENT_BY_FWNAME, "pll-xnn1-clstr", "ref_106p6", 0x410), +}; + +static const struct eqc_match_data eqc_eyeq7h_xnn1_match_data = { + .clk_count = ARRAY_SIZE(eqc_eyeq7h_xnn1_clks), + .clks = eqc_eyeq7h_xnn1_clks, + + .reset_auxdev_name = "reset_xnn1", +}; + static const struct of_device_id eqc_match_table[] = { { .compatible = "mobileye,eyeq5-olb", .data = &eqc_eyeq5_match_data }, { .compatible = "mobileye,eyeq6l-olb", .data = &eqc_eyeq6l_match_data }, @@ -711,6 +1181,22 @@ static const struct of_device_id eqc_match_table[] = { { .compatible = "mobileye,eyeq6h-ddr0-olb", .data = &eqc_eyeq6h_ddr0_match_data }, { .compatible = "mobileye,eyeq6h-ddr1-olb", .data = &eqc_eyeq6h_ddr1_match_data }, { .compatible = "mobileye,eyeq6h-acc-olb", .data = &eqc_eyeq6h_acc_match_data }, + { .compatible = "mobileye,eyeq7h-acc0-olb", .data = &eqc_eyeq7h_acc0_match_data }, + { .compatible = "mobileye,eyeq7h-acc1-olb", .data = &eqc_eyeq7h_acc1_match_data }, + { .compatible = "mobileye,eyeq7h-ddr0-olb", .data = &eqc_eyeq7h_ddr0_match_data }, + { .compatible = "mobileye,eyeq7h-ddr1-olb", .data = &eqc_eyeq7h_ddr1_match_data }, + { .compatible = "mobileye,eyeq7h-east-olb", .data = &eqc_eyeq7h_east_match_data }, + { .compatible = "mobileye,eyeq7h-mips0-olb", .data = &eqc_eyeq7h_mips0_match_data }, + { .compatible = "mobileye,eyeq7h-mips1-olb", .data = &eqc_eyeq7h_mips1_match_data }, + { .compatible = "mobileye,eyeq7h-mips2-olb", .data = &eqc_eyeq7h_mips2_match_data }, + { .compatible = "mobileye,eyeq7h-periph-east-olb", + .data = &eqc_eyeq7h_periph_east_match_data }, + { .compatible = "mobileye,eyeq7h-periph-west-olb", + .data = &eqc_eyeq7h_periph_west_match_data }, + { .compatible = "mobileye,eyeq7h-south-olb", .data = &eqc_eyeq7h_south_match_data }, + { .compatible = "mobileye,eyeq7h-west-olb", .data = &eqc_eyeq7h_west_match_data }, + { .compatible = "mobileye,eyeq7h-xnn0-olb", .data = &eqc_eyeq7h_xnn0_match_data }, + { .compatible = "mobileye,eyeq7h-xnn1-olb", .data = &eqc_eyeq7h_xnn1_match_data }, {} }; @@ -725,38 +1211,28 @@ static struct platform_driver eqc_driver = { builtin_platform_driver(eqc_driver); /* Required early for GIC timer. */ -static const struct eqc_pll eqc_eyeq6h_central_early_plls[] = { - { .index = EQ6HC_CENTRAL_PLL_CPU, .name = "pll-cpu", .reg64 = 0x02C }, -}; +static const struct eqc_clock eqc_eyeq6h_central_early_clks[] = { + PLL_FRACG(EQ6HC_CENTRAL_PLL_CPU, PARENT_BY_FWNAME, "pll-cpu", "ref", 0x02C), -static const struct eqc_fixed_factor eqc_eyeq6h_central_early_fixed_factors[] = { - { EQ6HC_CENTRAL_CPU_OCC, "occ-cpu", 1, 1, EQ6HC_CENTRAL_PLL_CPU }, + FF(EQ6HC_CENTRAL_CPU_OCC, EQ6HC_CENTRAL_PLL_CPU, "occ-cpu", NULL, 1, 1), }; static const struct eqc_early_match_data eqc_eyeq6h_central_early_match_data __initconst = { - .early_pll_count = ARRAY_SIZE(eqc_eyeq6h_central_early_plls), - .early_plls = eqc_eyeq6h_central_early_plls, - - .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq6h_central_early_fixed_factors), - .early_fixed_factors = eqc_eyeq6h_central_early_fixed_factors, + .early_clk_count = ARRAY_SIZE(eqc_eyeq6h_central_early_clks), + .early_clks = eqc_eyeq6h_central_early_clks, }; /* Required early for UART. */ -static const struct eqc_pll eqc_eyeq6h_west_early_plls[] = { - { .index = EQ6HC_WEST_PLL_PER, .name = "pll-west", .reg64 = 0x074 }, -}; +static const struct eqc_clock eqc_eyeq6h_west_early_clks[] = { + PLL_FRACG(EQ6HC_WEST_PLL_PER, PARENT_BY_FWNAME, "pll-west", "ref", 0x074), -static const struct eqc_fixed_factor eqc_eyeq6h_west_early_fixed_factors[] = { - { EQ6HC_WEST_PER_OCC, "west-per-occ", 1, 10, EQ6HC_WEST_PLL_PER }, - { EQ6HC_WEST_PER_UART, "west-per-uart", 1, 1, EQ6HC_WEST_PER_OCC }, + FF(EQ6HC_WEST_PER_OCC, EQ6HC_WEST_PLL_PER, "west-per-occ", NULL, 1, 10), + FF(EQ6HC_WEST_PER_UART, EQ6HC_WEST_PER_OCC, "west-per-uart", NULL, 1, 1), }; static const struct eqc_early_match_data eqc_eyeq6h_west_early_match_data __initconst = { - .early_pll_count = ARRAY_SIZE(eqc_eyeq6h_west_early_plls), - .early_plls = eqc_eyeq6h_west_early_plls, - - .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq6h_west_early_fixed_factors), - .early_fixed_factors = eqc_eyeq6h_west_early_fixed_factors, + .early_clk_count = ARRAY_SIZE(eqc_eyeq6h_west_early_clks), + .early_clks = eqc_eyeq6h_west_early_clks, }; static void __init eqc_early_init(struct device_node *np, @@ -767,8 +1243,7 @@ static void __init eqc_early_init(struct device_node *np, void __iomem *base; int ret; - clk_count = early_data->early_pll_count + early_data->early_fixed_factor_count + - early_data->late_clk_count; + clk_count = early_data->early_clk_count + early_data->late_clk_count; cells = kzalloc_flex(*cells, hws, clk_count); if (!cells) { ret = -ENOMEM; @@ -794,44 +1269,15 @@ static void __init eqc_early_init(struct device_node *np, goto err; } - for (i = 0; i < early_data->early_pll_count; i++) { - const struct eqc_pll *pll = &early_data->early_plls[i]; - unsigned long mult, div, acc; - struct clk_hw *hw; - u32 r0, r1; - u64 val; + for (i = 0; i < early_data->early_clk_count; i++) { + const struct eqc_clock *clk = &early_data->early_clks[i]; - val = readq(base + pll->reg64); - r0 = val; - r1 = val >> 32; - - ret = eqc_pll_parse_registers(r0, r1, &mult, &div, &acc); + if (clk->probe) + ret = clk->probe(NULL, np, clk, base, cells); + else + ret = -EINVAL; if (ret) { - pr_err("failed parsing state of %s\n", pll->name); - goto err; - } - - hw = clk_hw_register_fixed_factor_with_accuracy_fwname(NULL, - np, pll->name, "ref", 0, mult, div, acc); - cells->hws[pll->index] = hw; - if (IS_ERR(hw)) { - pr_err("failed registering %s: %pe\n", pll->name, hw); - ret = PTR_ERR(hw); - goto err; - } - } - - for (i = 0; i < early_data->early_fixed_factor_count; i++) { - const struct eqc_fixed_factor *ff = &early_data->early_fixed_factors[i]; - struct clk_hw *parent_hw = cells->hws[ff->parent]; - struct clk_hw *hw; - - hw = clk_hw_register_fixed_factor_parent_hw(NULL, ff->name, - parent_hw, 0, ff->mult, ff->div); - cells->hws[ff->index] = hw; - if (IS_ERR(hw)) { - pr_err("failed registering %s: %pe\n", ff->name, hw); - ret = PTR_ERR(hw); + pr_err("failed registering %s\n", clk->name); goto err; } } @@ -857,12 +1303,12 @@ err: if (cells) { of_clk_del_provider(np); - for (i = 0; i < early_data->early_pll_count; i++) { - const struct eqc_pll *pll = &early_data->early_plls[i]; - struct clk_hw *hw = cells->hws[pll->index]; + for (i = 0; i < early_data->early_clk_count; i++) { + const struct eqc_clock *clk = &early_data->early_clks[i]; + struct clk_hw *hw = cells->hws[clk->index]; - if (!IS_ERR_OR_NULL(hw)) - clk_hw_unregister_fixed_factor(hw); + if (!IS_ERR_OR_NULL(hw) && clk->unregister) + clk->unregister(hw); } kfree(cells); diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 850e8b95f352..ae473e0af903 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -36,10 +36,14 @@ static int clk_factor_determine_rate(struct clk_hw *hw, struct clk_fixed_factor *fix = to_clk_fixed_factor(hw); if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { + struct clk_hw *parent_hw = clk_hw_get_parent(hw); unsigned long best_parent; + if (!parent_hw) + return -EINVAL; + best_parent = (req->rate / fix->mult) * fix->div; - req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); + req->best_parent_rate = clk_hw_round_rate(parent_hw, best_parent); } req->rate = (req->best_parent_rate / fix->div) * fix->mult; @@ -90,7 +94,7 @@ static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void * clk_hw_unregister(&fix->hw); } -static struct clk_hw * +struct clk_hw * __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, const char *name, const char *parent_name, const struct clk_hw *parent_hw, const struct clk_parent_data *pdata, @@ -124,13 +128,13 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, init.name = name; init.ops = &clk_fixed_factor_ops; init.flags = flags; - if (parent_name) - init.parent_names = &parent_name; - else if (parent_hw) - init.parent_hws = &parent_hw; + init.parent_names = parent_name ? &parent_name : NULL; + init.parent_hws = parent_hw ? &parent_hw : NULL; + init.parent_data = pdata; + if (parent_name || parent_hw || pdata) + init.num_parents = 1; else - init.parent_data = pdata; - init.num_parents = 1; + init.num_parents = 0; hw = &fix->hw; if (dev) @@ -148,6 +152,7 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, return hw; } +EXPORT_SYMBOL_GPL(__clk_hw_register_fixed_factor); /** * devm_clk_hw_register_fixed_factor_index - Register a fixed factor clock with @@ -173,52 +178,6 @@ struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev, } EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_index); -/** - * devm_clk_hw_register_fixed_factor_parent_hw - Register a fixed factor clock with - * pointer to parent clock - * @dev: device that is registering this clock - * @name: name of this clock - * @parent_hw: pointer to parent clk - * @flags: fixed factor flags - * @mult: multiplier - * @div: divider - * - * Return: Pointer to fixed factor clk_hw structure that was registered or - * an error pointer. - */ -struct clk_hw *devm_clk_hw_register_fixed_factor_parent_hw(struct device *dev, - const char *name, const struct clk_hw *parent_hw, - unsigned long flags, unsigned int mult, unsigned int div) -{ - const struct clk_parent_data pdata = { .index = -1 }; - - return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, parent_hw, - &pdata, flags, mult, div, 0, 0, true); -} -EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_parent_hw); - -struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev, - const char *name, const struct clk_hw *parent_hw, - unsigned long flags, unsigned int mult, unsigned int div) -{ - const struct clk_parent_data pdata = { .index = -1 }; - - return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, parent_hw, - &pdata, flags, mult, div, 0, 0, false); -} -EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor_parent_hw); - -struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, - const char *name, const char *parent_name, unsigned long flags, - unsigned int mult, unsigned int div) -{ - const struct clk_parent_data pdata = { .index = -1 }; - - return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, NULL, - &pdata, flags, mult, div, 0, 0, false); -} -EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor); - struct clk_hw *clk_hw_register_fixed_factor_fwname(struct device *dev, struct device_node *np, const char *name, const char *fw_name, unsigned long flags, unsigned int mult, unsigned int div) @@ -292,17 +251,6 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw) } EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor); -struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev, - const char *name, const char *parent_name, unsigned long flags, - unsigned int mult, unsigned int div) -{ - const struct clk_parent_data pdata = { .index = -1 }; - - return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, NULL, - &pdata, flags, mult, div, 0, 0, true); -} -EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor); - struct clk_hw *devm_clk_hw_register_fixed_factor_fwname(struct device *dev, struct device_node *np, const char *name, const char *fw_name, unsigned long flags, unsigned int mult, unsigned int div) diff --git a/drivers/clk/clk-k230.c b/drivers/clk/clk-k230.c index cfc437038e4e..f34a3e6d3bca 100644 --- a/drivers/clk/clk-k230.c +++ b/drivers/clk/clk-k230.c @@ -2227,6 +2227,7 @@ static int k230_clk_set_rate_mul(struct clk_hw *hw, unsigned long rate, guard(spinlock)(rate_self->lock); mul_reg = readl(rate_self->reg + clk->mul_reg_off); + mul_reg &= ~(rate_self->mul_mask << rate_self->mul_shift); mul_reg |= ((mul - 1) & rate_self->mul_mask) << (rate_self->mul_shift); mul_reg |= BIT(rate_self->write_enable_bit); writel(mul_reg, rate_self->reg + clk->mul_reg_off); @@ -2257,6 +2258,7 @@ static int k230_clk_set_rate_div(struct clk_hw *hw, unsigned long rate, guard(spinlock)(rate_self->lock); div_reg = readl(rate_self->reg + clk->div_reg_off); + div_reg &= ~(rate_self->div_mask << rate_self->div_shift); div_reg |= ((div - 1) & rate_self->div_mask) << (rate_self->div_shift); div_reg |= BIT(rate_self->write_enable_bit); writel(div_reg, rate_self->reg + clk->div_reg_off); @@ -2287,11 +2289,13 @@ static int k230_clk_set_rate_mul_div(struct clk_hw *hw, unsigned long rate, guard(spinlock)(rate_self->lock); div_reg = readl(rate_self->reg + clk->div_reg_off); + div_reg &= ~(rate_self->div_mask << rate_self->div_shift); div_reg |= ((div - 1) & rate_self->div_mask) << (rate_self->div_shift); div_reg |= BIT(rate_self->write_enable_bit); writel(div_reg, rate_self->reg + clk->div_reg_off); mul_reg = readl(rate_self->reg + clk->mul_reg_off); + mul_reg &= ~(rate_self->mul_mask << rate_self->mul_shift); mul_reg |= ((mul - 1) & rate_self->mul_mask) << (rate_self->mul_shift); mul_reg |= BIT(rate_self->write_enable_bit); writel(mul_reg, rate_self->reg + clk->mul_reg_off); diff --git a/drivers/clk/clk-lmk04832.c b/drivers/clk/clk-lmk04832.c index 9bf86caad829..f9a0684d2628 100644 --- a/drivers/clk/clk-lmk04832.c +++ b/drivers/clk/clk-lmk04832.c @@ -175,10 +175,6 @@ #define LMK04832_REG_RB_HOLDOVER 0x188 #define LMK04832_REG_SPI_LOCK 0x555 -enum lmk04832_device_types { - LMK04832, -}; - /** * struct lmk04832_device_info - Holds static device information that is * specific to the chip revision @@ -197,14 +193,12 @@ struct lmk04832_device_info { unsigned int vco1_range[2]; }; -static const struct lmk04832_device_info lmk04832_device_info[] = { - [LMK04832] = { - .pid = 0x63d1, /* WARNING PROD_ID is inverted in the datasheet */ - .maskrev = 0x70, - .num_channels = 14, - .vco0_range = { 2440, 2580 }, - .vco1_range = { 2945, 3255 }, - }, +static const struct lmk04832_device_info lmk04832_device_info = { + .pid = 0x63d1, /* WARNING PROD_ID is inverted in the datasheet */ + .maskrev = 0x70, + .num_channels = 14, + .vco0_range = { 2440, 2580 }, + .vco1_range = { 2945, 3255 }, }; enum lmk04832_rdbk_type { @@ -422,11 +416,10 @@ static unsigned long lmk04832_vco_recalc_rate(struct clk_hw *hw, */ static int lmk04832_check_vco_ranges(struct lmk04832 *lmk, unsigned long rate) { - struct spi_device *spi = to_spi_device(lmk->dev); const struct lmk04832_device_info *info; unsigned long mhz = rate / 1000000; - info = &lmk04832_device_info[spi_get_device_id(spi)->driver_data]; + info = &lmk04832_device_info; if (mhz >= info->vco0_range[0] && mhz <= info->vco0_range[1]) return LMK04832_VAL_VCO_MUX_VCO0; @@ -822,13 +815,6 @@ static int lmk04832_sclk_sync_sequence(struct lmk04832 *lmk) if (ret) return ret; - ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC, - LMK04832_BIT_SYNC_MODE, - FIELD_PREP(LMK04832_BIT_SYNC_MODE, - lmk->sync_mode)); - if (ret) - return ret; - /* * 9. (optional) if SCLKx_y_DIS_MODE was used to mute SYSREF outputs * during the SYNC event, restore SCLKx_y_DIS_MODE=0 for active state, @@ -843,7 +829,10 @@ static int lmk04832_sclk_sync_sequence(struct lmk04832 *lmk) * SYNC pulse to delay the output by some number of VCO counts). */ - return ret; + return regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC, + LMK04832_BIT_SYNC_MODE, + FIELD_PREP(LMK04832_BIT_SYNC_MODE, + lmk->sync_mode)); } static int lmk04832_sclk_is_enabled(struct clk_hw *hw) @@ -1405,7 +1394,7 @@ static int lmk04832_probe(struct spi_device *spi) int ret; int i; - info = &lmk04832_device_info[spi_get_device_id(spi)->driver_data]; + info = &lmk04832_device_info; lmk = devm_kzalloc(&spi->dev, sizeof(struct lmk04832), GFP_KERNEL); if (!lmk) @@ -1553,8 +1542,8 @@ static int lmk04832_probe(struct spi_device *spi) } static const struct spi_device_id lmk04832_id[] = { - { "lmk04832", LMK04832 }, - {} + { .name = "lmk04832" }, + { } }; MODULE_DEVICE_TABLE(spi, lmk04832_id); diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c index 9149ce4f702d..e6fde914c5ef 100644 --- a/drivers/clk/clk-max77686.c +++ b/drivers/clk/clk-max77686.c @@ -264,10 +264,10 @@ static int max77686_clk_probe(struct platform_device *pdev) } static const struct platform_device_id max77686_clk_id[] = { - { "max77686-clk", .driver_data = CHIP_MAX77686, }, - { "max77802-clk", .driver_data = CHIP_MAX77802, }, - { "max77620-clock", .driver_data = CHIP_MAX77620, }, - {}, + { .name = "max77686-clk", .driver_data = CHIP_MAX77686 }, + { .name = "max77802-clk", .driver_data = CHIP_MAX77802 }, + { .name = "max77620-clock", .driver_data = CHIP_MAX77620 }, + { } }; MODULE_DEVICE_TABLE(platform, max77686_clk_id); diff --git a/drivers/clk/clk-moxart.c b/drivers/clk/clk-moxart.c index 3786a0153ad1..40663ef3ef0a 100644 --- a/drivers/clk/clk-moxart.c +++ b/drivers/clk/clk-moxart.c @@ -17,7 +17,6 @@ static void __init moxart_of_pll_clk_init(struct device_node *node) { void __iomem *base; struct clk_hw *hw; - struct clk *ref_clk; unsigned int mul; const char *name = node->name; const char *parent_name; @@ -34,12 +33,6 @@ static void __init moxart_of_pll_clk_init(struct device_node *node) mul = readl(base + 0x30) >> 3 & 0x3f; iounmap(base); - ref_clk = of_clk_get(node, 0); - if (IS_ERR(ref_clk)) { - pr_err("%pOF: of_clk_get failed\n", node); - return; - } - hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1); if (IS_ERR(hw)) { pr_err("%pOF: failed to register clock\n", node); @@ -56,7 +49,6 @@ static void __init moxart_of_apb_clk_init(struct device_node *node) { void __iomem *base; struct clk_hw *hw; - struct clk *pll_clk; unsigned int div, val; unsigned int div_idx[] = { 2, 3, 4, 6, 8}; const char *name = node->name; @@ -78,12 +70,6 @@ static void __init moxart_of_apb_clk_init(struct device_node *node) val = 0; div = div_idx[val] * 2; - pll_clk = of_clk_get(node, 0); - if (IS_ERR(pll_clk)) { - pr_err("%pOF: of_clk_get failed\n", node); - return; - } - hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div); if (IS_ERR(hw)) { pr_err("%pOF: failed to register clock\n", node); diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c index 39049f62dbbb..fdbf8445ebc2 100644 --- a/drivers/clk/clk-palmas.c +++ b/drivers/clk/clk-palmas.c @@ -194,6 +194,13 @@ static void palmas_clks_get_clk_data(struct platform_device *pdev, cinfo->ext_control_pin = prop; } +static void palmas_clks_unprepare_ext_control(void *data) +{ + struct palmas_clock_info *cinfo = data; + + clk_unprepare(cinfo->hw.clk); +} + static int palmas_clks_init_configure(struct palmas_clock_info *cinfo) { int ret; @@ -214,13 +221,18 @@ static int palmas_clks_init_configure(struct palmas_clock_info *cinfo) return ret; } + ret = devm_add_action_or_reset(cinfo->dev, + palmas_clks_unprepare_ext_control, + cinfo); + if (ret) + return ret; + ret = palmas_ext_control_req_config(cinfo->palmas, cinfo->clk_desc->sleep_reqstr_id, cinfo->ext_control_pin, true); if (ret < 0) { dev_err(cinfo->dev, "Ext config for %s failed, %d\n", cinfo->clk_desc->clk_name, ret); - clk_unprepare(cinfo->hw.clk); return ret; } } @@ -230,7 +242,6 @@ static int palmas_clks_init_configure(struct palmas_clock_info *cinfo) static int palmas_clks_probe(struct platform_device *pdev) { struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); - struct device_node *node = pdev->dev.of_node; const struct palmas_clks_of_match_data *match_data; struct palmas_clock_info *cinfo; int ret; @@ -264,24 +275,19 @@ static int palmas_clks_probe(struct platform_device *pdev) return ret; } - ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &cinfo->hw); + ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get, + &cinfo->hw); if (ret < 0) dev_err(&pdev->dev, "Fail to add clock driver, %d\n", ret); return ret; } -static void palmas_clks_remove(struct platform_device *pdev) -{ - of_clk_del_provider(pdev->dev.of_node); -} - static struct platform_driver palmas_clks_driver = { .driver = { .name = "palmas-clk", .of_match_table = palmas_clks_of_match, }, .probe = palmas_clks_probe, - .remove = palmas_clks_remove, }; module_platform_driver(palmas_clks_driver); diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c index 2f6d80ee77cc..564550c80389 100644 --- a/drivers/clk/clk-renesas-pcie.c +++ b/drivers/clk/clk-renesas-pcie.c @@ -394,9 +394,9 @@ static const struct rs9_chip_info renesas_9fgv0841_info = { }; static const struct i2c_device_id rs9_id[] = { - { "9fgv0241", .driver_data = (kernel_ulong_t)&renesas_9fgv0241_info }, - { "9fgv0441", .driver_data = (kernel_ulong_t)&renesas_9fgv0441_info }, - { "9fgv0841", .driver_data = (kernel_ulong_t)&renesas_9fgv0841_info }, + { .name = "9fgv0241", .driver_data = (kernel_ulong_t)&renesas_9fgv0241_info }, + { .name = "9fgv0441", .driver_data = (kernel_ulong_t)&renesas_9fgv0441_info }, + { .name = "9fgv0841", .driver_data = (kernel_ulong_t)&renesas_9fgv0841_info }, { } }; MODULE_DEVICE_TABLE(i2c, rs9_id); diff --git a/drivers/clk/clk-rp1.c b/drivers/clk/clk-rp1.c index fd144755b879..0f7d9fd77481 100644 --- a/drivers/clk/clk-rp1.c +++ b/drivers/clk/clk-rp1.c @@ -1174,12 +1174,6 @@ static unsigned long rp1_varsrc_recalc_rate(struct clk_hw *hw, return clock->cached_rate; } -static int rp1_varsrc_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - return 0; -} - static const struct clk_ops rp1_pll_core_ops = { .is_prepared = rp1_pll_core_is_on, .prepare = rp1_pll_core_on, @@ -1227,7 +1221,7 @@ static const struct clk_ops rp1_clk_ops = { static const struct clk_ops rp1_varsrc_ops = { .set_rate = rp1_varsrc_set_rate, .recalc_rate = rp1_varsrc_recalc_rate, - .determine_rate = rp1_varsrc_determine_rate, + .determine_rate = clk_determine_rate_noop, }; static struct clk_hw *rp1_register_pll(struct rp1_clockman *clockman, diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index ff7ce12a5da6..fa5ac8f673f6 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -225,12 +225,12 @@ static void s2mps11_clk_remove(struct platform_device *pdev) } static const struct platform_device_id s2mps11_clk_id[] = { - { "s2mpg10-clk", S2MPG10}, - { "s2mps11-clk", S2MPS11X}, - { "s2mps13-clk", S2MPS13X}, - { "s2mps14-clk", S2MPS14X}, - { "s5m8767-clk", S5M8767X}, - { }, + { .name = "s2mpg10-clk", .driver_data = S2MPG10 }, + { .name = "s2mps11-clk", .driver_data = S2MPS11X }, + { .name = "s2mps13-clk", .driver_data = S2MPS13X }, + { .name = "s2mps14-clk", .driver_data = S2MPS14X }, + { .name = "s5m8767-clk", .driver_data = S5M8767X }, + { } }; MODULE_DEVICE_TABLE(platform, s2mps11_clk_id); diff --git a/drivers/clk/clk-scmi-oem.c b/drivers/clk/clk-scmi-oem.c new file mode 100644 index 000000000000..be11d359b4ec --- /dev/null +++ b/drivers/clk/clk-scmi-oem.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * The Vendor OEM extension for System Control and Power Interface (SCMI) + * Protocol based clock driver + * + * Copyright 2025 NXP + */ + +#include +#include +#include +#include + +#include "clk-scmi.h" + +#define SCMI_CLOCK_CFG_IMX_SSC 0x80 +#define SCMI_CLOCK_IMX_SS_PERCENTAGE_MASK GENMASK(7, 0) +#define SCMI_CLOCK_IMX_SS_MOD_FREQ_MASK GENMASK(23, 8) +#define SCMI_CLOCK_IMX_SS_ENABLE_MASK BIT(24) + +/* + * Selection is based on SCMI vendor_id/sub_vendor_id and optional machine + * compatible string, without involving impl_ver. impl_ver‑specific behavior + * should be considered a bug and handled via SCMI Quirk framework. + */ +struct scmi_clk_oem_info { + char *vendor_id; + char *sub_vendor_id; + char *compatible; + const void *data; +}; + +static int +scmi_clk_imx_set_spread_spectrum(struct clk_hw *hw, + const struct clk_spread_spectrum *ss_conf) +{ + struct scmi_clk *clk = to_scmi_clk(hw); + int ret; + u32 val; + + /* + * extConfigValue[7:0] - spread percentage (%) + * extConfigValue[23:8] - Modulation Frequency + * extConfigValue[24] - Enable/Disable + * extConfigValue[31:25] - Reserved + */ + val = FIELD_PREP(SCMI_CLOCK_IMX_SS_PERCENTAGE_MASK, ss_conf->spread_bp / 10000); + val |= FIELD_PREP(SCMI_CLOCK_IMX_SS_MOD_FREQ_MASK, ss_conf->modfreq_hz); + if (ss_conf->method != CLK_SPREAD_NO) + val |= SCMI_CLOCK_IMX_SS_ENABLE_MASK; + ret = scmi_proto_clk_ops->config_oem_set(clk->ph, clk->id, + SCMI_CLOCK_CFG_IMX_SSC, + val, false); + if (ret) + dev_warn(clk->dev, + "Failed to set spread spectrum(%u,%u,%u) for clock ID %d\n", + ss_conf->modfreq_hz, ss_conf->spread_bp, ss_conf->method, + clk->id); + + return ret; +} + +static int +scmi_clk_imx_query_oem_feats(const struct scmi_protocol_handle *ph, u32 id, + unsigned int *feats_key) +{ + int ret; + u32 val; + + ret = scmi_proto_clk_ops->config_oem_get(ph, id, + SCMI_CLOCK_CFG_IMX_SSC, + &val, NULL, false); + if (!ret) + *feats_key |= BIT(SCMI_CLK_EXT_OEM_SSC_SUPPORTED); + + return 0; +} + +static const struct scmi_clk_oem scmi_clk_oem_imx = { + .query_ext_oem_feats = scmi_clk_imx_query_oem_feats, + .set_spread_spectrum = scmi_clk_imx_set_spread_spectrum, +}; + +static const struct scmi_clk_oem_info info[] = { + { SCMI_IMX_VENDOR, SCMI_IMX_SUBVENDOR, NULL, &scmi_clk_oem_imx }, +}; + +int scmi_clk_oem_init(struct scmi_device *sdev) +{ + const struct scmi_handle *handle = sdev->handle; + int i, size = ARRAY_SIZE(info); + + for (i = 0; i < size; i++) { + if (strcmp(handle->version->vendor_id, info[i].vendor_id) || + strcmp(handle->version->sub_vendor_id, info[i].sub_vendor_id)) + continue; + if (info[i].compatible && + !of_machine_is_compatible(info[i].compatible)) + continue; + + break; + } + + if (i < size) + dev_set_drvdata(&sdev->dev, (void *)info[i].data); + + return 0; +} diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c index 7c562559ad8b..2dd50c5b4ea8 100644 --- a/drivers/clk/clk-scmi.c +++ b/drivers/clk/clk-scmi.c @@ -13,32 +13,9 @@ #include #include -#define NOT_ATOMIC false -#define ATOMIC true +#include "clk-scmi.h" -enum scmi_clk_feats { - SCMI_CLK_ATOMIC_SUPPORTED, - SCMI_CLK_STATE_CTRL_SUPPORTED, - SCMI_CLK_RATE_CTRL_SUPPORTED, - SCMI_CLK_PARENT_CTRL_SUPPORTED, - SCMI_CLK_DUTY_CYCLE_SUPPORTED, - SCMI_CLK_FEATS_COUNT -}; - -#define SCMI_MAX_CLK_OPS BIT(SCMI_CLK_FEATS_COUNT) - -static const struct scmi_clk_proto_ops *scmi_proto_clk_ops; - -struct scmi_clk { - u32 id; - struct device *dev; - struct clk_hw hw; - const struct scmi_clock_info *info; - const struct scmi_protocol_handle *ph; - struct clk_parent_data *parent_data; -}; - -#define to_scmi_clk(clk) container_of(clk, struct scmi_clk, hw) +const struct scmi_clk_proto_ops *scmi_proto_clk_ops; static unsigned long scmi_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) @@ -235,6 +212,7 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk, static const struct clk_ops * scmi_clk_ops_alloc(struct device *dev, unsigned long feats_key) { + struct scmi_clk_oem *oem_data = dev_get_drvdata(dev); struct clk_ops *ops; ops = devm_kzalloc(dev, sizeof(*ops), GFP_KERNEL); @@ -281,11 +259,15 @@ scmi_clk_ops_alloc(struct device *dev, unsigned long feats_key) ops->set_duty_cycle = scmi_clk_set_duty_cycle; } + if (oem_data && (feats_key & BIT(SCMI_CLK_EXT_OEM_SSC_SUPPORTED))) + ops->set_spread_spectrum = oem_data->set_spread_spectrum; + return ops; } /** * scmi_clk_ops_select() - Select a proper set of clock operations + * @sdev: pointer to the SCMI device * @sclk: A reference to an SCMI clock descriptor * @atomic_capable: A flag to indicate if atomic mode is supported by the * transport @@ -310,8 +292,8 @@ scmi_clk_ops_alloc(struct device *dev, unsigned long feats_key) * NULL otherwise. */ static const struct clk_ops * -scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable, - unsigned int atomic_threshold_us, +scmi_clk_ops_select(struct scmi_device *sdev, struct scmi_clk *sclk, + bool atomic_capable, unsigned int atomic_threshold_us, const struct clk_ops **clk_ops_db, size_t db_size) { int ret; @@ -319,6 +301,7 @@ scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable, const struct scmi_clock_info *ci = sclk->info; unsigned int feats_key = 0; const struct clk_ops *ops; + struct scmi_clk_oem *oem_data = dev_get_drvdata(&sdev->dev); /* * Note that when transport is atomic but SCMI protocol did not @@ -343,6 +326,9 @@ scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable, &val, NULL, false); if (!ret) feats_key |= BIT(SCMI_CLK_DUTY_CYCLE_SUPPORTED); + + if (oem_data && oem_data->query_ext_oem_feats) + oem_data->query_ext_oem_feats(sclk->ph, sclk->id, &feats_key); } if (WARN_ON(feats_key >= db_size)) @@ -400,6 +386,8 @@ static int scmi_clocks_probe(struct scmi_device *sdev) clk_data->num = count; hws = clk_data->hws; + scmi_clk_oem_init(sdev); + transport_is_atomic = handle->is_transport_atomic(handle, &atomic_threshold_us); @@ -431,7 +419,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev) * to avoid sharing the devm_ allocated clk_ops between multiple * SCMI clk driver instances. */ - scmi_ops = scmi_clk_ops_select(sclk, transport_is_atomic, + scmi_ops = scmi_clk_ops_select(sdev, sclk, transport_is_atomic, atomic_threshold_us, scmi_clk_ops_db, ARRAY_SIZE(scmi_clk_ops_db)); diff --git a/drivers/clk/clk-scmi.h b/drivers/clk/clk-scmi.h new file mode 100644 index 000000000000..d7f63f36c56d --- /dev/null +++ b/drivers/clk/clk-scmi.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2025 NXP + */ + +#ifndef __SCMI_CLK_H +#define __SCMI_CLK_H + +#include +#include +#include +#include + +#define NOT_ATOMIC false +#define ATOMIC true + +enum scmi_clk_feats { + SCMI_CLK_ATOMIC_SUPPORTED, + SCMI_CLK_STATE_CTRL_SUPPORTED, + SCMI_CLK_RATE_CTRL_SUPPORTED, + SCMI_CLK_PARENT_CTRL_SUPPORTED, + SCMI_CLK_DUTY_CYCLE_SUPPORTED, + SCMI_CLK_EXT_OEM_SSC_SUPPORTED, + SCMI_CLK_FEATS_COUNT +}; + +#define SCMI_MAX_CLK_OPS BIT(SCMI_CLK_FEATS_COUNT) + +struct scmi_clk { + u32 id; + struct device *dev; + struct clk_hw hw; + const struct scmi_clock_info *info; + const struct scmi_protocol_handle *ph; + struct clk_parent_data *parent_data; +}; + +#define to_scmi_clk(clk) container_of(clk, struct scmi_clk, hw) + +extern const struct scmi_clk_proto_ops *scmi_proto_clk_ops; + +struct scmi_clk_oem { + int (*query_ext_oem_feats)(const struct scmi_protocol_handle *ph, + u32 id, unsigned int *feats_key); + int (*set_spread_spectrum)(struct clk_hw *hw, + const struct clk_spread_spectrum *ss_conf); +}; + +int scmi_clk_oem_init(struct scmi_device *dev); + +#endif diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index 24cee7c9fda6..2328d2abf6d8 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -32,18 +32,6 @@ static unsigned long scpi_clk_recalc_rate(struct clk_hw *hw, return clk->scpi_ops->clk_get_val(clk->id); } -static int scpi_clk_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - /* - * We can't figure out what rate it will be, so just return the - * rate back to the caller. scpi_clk_recalc_rate() will be called - * after the rate is set and we'll know what rate the clock is - * running at then. - */ - return 0; -} - static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -54,7 +42,7 @@ static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops scpi_clk_ops = { .recalc_rate = scpi_clk_recalc_rate, - .determine_rate = scpi_clk_determine_rate, + .determine_rate = clk_determine_rate_noop, .set_rate = scpi_clk_set_rate, }; diff --git a/drivers/clk/clk-si514.c b/drivers/clk/clk-si514.c index f61590d70575..c0b433ad9372 100644 --- a/drivers/clk/clk-si514.c +++ b/drivers/clk/clk-si514.c @@ -379,7 +379,7 @@ static int si514_probe(struct i2c_client *client) } static const struct i2c_device_id si514_id[] = { - { "si514" }, + { .name = "si514" }, { } }; MODULE_DEVICE_TABLE(i2c, si514_id); diff --git a/drivers/clk/clk-si521xx.c b/drivers/clk/clk-si521xx.c index ceadc07bcb6d..e3fb8df712ef 100644 --- a/drivers/clk/clk-si521xx.c +++ b/drivers/clk/clk-si521xx.c @@ -364,9 +364,9 @@ static int __maybe_unused si521xx_resume(struct device *dev) } static const struct i2c_device_id si521xx_id[] = { - { "si52144", .driver_data = SI521XX_OE_MAP(0x5, 0xc0) }, - { "si52146", .driver_data = SI521XX_OE_MAP(0x15, 0xe0) }, - { "si52147", .driver_data = SI521XX_OE_MAP(0x17, 0xf8) }, + { .name = "si52144", .driver_data = SI521XX_OE_MAP(0x5, 0xc0) }, + { .name = "si52146", .driver_data = SI521XX_OE_MAP(0x15, 0xe0) }, + { .name = "si52147", .driver_data = SI521XX_OE_MAP(0x17, 0xf8) }, { } }; MODULE_DEVICE_TABLE(i2c, si521xx_id); diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 2499b771cd83..5311c23532b4 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -1825,11 +1825,11 @@ static void si5341_remove(struct i2c_client *client) } static const struct i2c_device_id si5341_id[] = { - { "si5340", 0 }, - { "si5341", 1 }, - { "si5342", 2 }, - { "si5344", 4 }, - { "si5345", 5 }, + { .name = "si5340" }, + { .name = "si5341" }, + { .name = "si5342" }, + { .name = "si5344" }, + { .name = "si5345" }, { } }; MODULE_DEVICE_TABLE(i2c, si5341_id); diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index e755db545e2e..20b0c3c48b86 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -1425,10 +1425,10 @@ si53351_of_clk_get(struct of_phandle_args *clkspec, void *data) #endif /* CONFIG_OF */ static const struct i2c_device_id si5351_i2c_ids[] = { - { "si5351a", SI5351_VARIANT_A }, - { "si5351a-msop", SI5351_VARIANT_A3 }, - { "si5351b", SI5351_VARIANT_B }, - { "si5351c", SI5351_VARIANT_C }, + { .name = "si5351a", .driver_data = SI5351_VARIANT_A }, + { .name = "si5351a-msop", .driver_data = SI5351_VARIANT_A3 }, + { .name = "si5351b", .driver_data = SI5351_VARIANT_B }, + { .name = "si5351c", .driver_data = SI5351_VARIANT_C }, { } }; MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids); diff --git a/drivers/clk/clk-si544.c b/drivers/clk/clk-si544.c index 09c06ecec1a5..9c520128e0a2 100644 --- a/drivers/clk/clk-si544.c +++ b/drivers/clk/clk-si544.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Driver for Silicon Labs Si544 Programmable Oscillator + * Driver for Silicon Labs Si544/Si549 Programmable Oscillator * Copyright (C) 2018 Topic Embedded Products * Author: Mike Looijmans */ @@ -40,7 +40,9 @@ #define SI544_MIN_FREQ 200000U /* Si544 Internal oscillator runs at 55.05 MHz */ -#define FXO 55050000U +#define SI544_XO_FREQ 55050000U +/* Si549 Internal oscilator runs at 152.60 MHz */ +#define SI549_XO_FREQ 152600000U /* VCO range is 10.8 .. 12.1 GHz, max depends on speed grade */ #define FVCO_MIN 10800000000ULL @@ -56,11 +58,16 @@ #define DELTA_M_FRAC_NUM 19 #define DELTA_M_FRAC_DEN 20000 +struct si544_clk_desc { + unsigned long max_freq; + unsigned long xo_freq; +}; + struct clk_si544 { struct clk_hw hw; struct regmap *regmap; struct i2c_client *i2c_client; - unsigned long max_freq; + const struct si544_clk_desc *chip_info; }; #define to_clk_si544(_hw) container_of(_hw, struct clk_si544, hw) @@ -79,6 +86,7 @@ struct clk_si544_muldiv { u16 hs_div; u8 ls_div_bits; s32 delta_m; + u32 xo_freq; }; /* Enables or disables the output driver */ @@ -145,6 +153,8 @@ static int si544_get_muldiv(struct clk_si544 *data, settings->delta_m = reg[0] << 8 | reg[1] << 16 | reg[2] << 24; settings->delta_m >>= 8; + settings->xo_freq = data->chip_info->xo_freq; + return 0; } @@ -193,7 +203,7 @@ static bool is_valid_frequency(const struct clk_si544 *data, if (frequency < SI544_MIN_FREQ) return false; - return frequency <= data->max_freq; + return frequency <= data->chip_info->max_freq; } /* Calculate divider settings for a given frequency */ @@ -201,6 +211,7 @@ static int si544_calc_muldiv(struct clk_si544_muldiv *settings, unsigned long frequency) { u64 vco; + u32 fxo = settings->xo_freq; u32 ls_freq; u32 tmp; u8 res; @@ -238,13 +249,13 @@ static int si544_calc_muldiv(struct clk_si544_muldiv *settings, vco = (u64)ls_freq * settings->hs_div; /* Calculate the integer part of the feedback divider */ - tmp = do_div(vco, FXO); + tmp = do_div(vco, fxo); settings->fb_div_int = vco; /* And the fractional bits using the remainder */ vco = (u64)tmp << 32; - vco += FXO / 2; /* Round to nearest multiple */ - do_div(vco, FXO); + vco += fxo / 2; /* Round to nearest multiple */ + do_div(vco, fxo); settings->fb_div_frac = vco; /* Reset the frequency adjustment */ @@ -258,15 +269,16 @@ static unsigned long si544_calc_center_rate( const struct clk_si544_muldiv *settings) { u32 d = settings->hs_div * BIT(settings->ls_div_bits); + u32 fxo = settings->xo_freq; u64 vco; /* Calculate VCO from the fractional part */ - vco = (u64)settings->fb_div_frac * FXO; - vco += (FXO / 2); + vco = (u64)settings->fb_div_frac * fxo; + vco += (fxo / 2); vco >>= 32; /* Add the integer part of the VCO frequency */ - vco += (u64)settings->fb_div_int * FXO; + vco += (u64)settings->fb_div_int * fxo; /* Apply divider to obtain the generated frequency */ do_div(vco, d); @@ -446,7 +458,7 @@ static int si544_probe(struct i2c_client *client) init.num_parents = 0; data->hw.init = &init; data->i2c_client = client; - data->max_freq = (uintptr_t)i2c_get_match_data(client); + data->chip_info = i2c_get_match_data(client); if (of_property_read_string(client->dev.of_node, "clock-output-names", &init.name)) @@ -478,18 +490,54 @@ static int si544_probe(struct i2c_client *client) return 0; } +static const struct si544_clk_desc clk_si544a_info = { + .xo_freq = SI544_XO_FREQ, + .max_freq = 1500000000, +}; + +static const struct si544_clk_desc clk_si544b_info = { + .xo_freq = SI544_XO_FREQ, + .max_freq = 800000000, +}; + +static const struct si544_clk_desc clk_si544c_info = { + .xo_freq = SI544_XO_FREQ, + .max_freq = 325000000, +}; + +static const struct si544_clk_desc clk_si549a_info = { + .xo_freq = SI549_XO_FREQ, + .max_freq = 1500000000, +}; + +static const struct si544_clk_desc clk_si549b_info = { + .xo_freq = SI549_XO_FREQ, + .max_freq = 800000000, +}; + +static const struct si544_clk_desc clk_si549c_info = { + .xo_freq = SI549_XO_FREQ, + .max_freq = 325000000, +}; + static const struct i2c_device_id si544_id[] = { - { "si544a", 1500000000 }, - { "si544b", 800000000 }, - { "si544c", 350000000 }, + { .name = "si544a", .driver_data = (kernel_ulong_t)&clk_si544a_info }, + { .name = "si544b", .driver_data = (kernel_ulong_t)&clk_si544b_info }, + { .name = "si544c", .driver_data = (kernel_ulong_t)&clk_si544c_info }, + { .name = "si549a", .driver_data = (kernel_ulong_t)&clk_si549a_info }, + { .name = "si549b", .driver_data = (kernel_ulong_t)&clk_si549b_info }, + { .name = "si549c", .driver_data = (kernel_ulong_t)&clk_si549c_info }, { } }; MODULE_DEVICE_TABLE(i2c, si544_id); static const struct of_device_id clk_si544_of_match[] = { - { .compatible = "silabs,si544a", .data = (void *)1500000000 }, - { .compatible = "silabs,si544b", .data = (void *)800000000 }, - { .compatible = "silabs,si544c", .data = (void *)350000000 }, + { .compatible = "silabs,si544a", .data = &clk_si544a_info }, + { .compatible = "silabs,si544b", .data = &clk_si544b_info }, + { .compatible = "silabs,si544c", .data = &clk_si544c_info }, + { .compatible = "silabs,si549a", .data = &clk_si549a_info }, + { .compatible = "silabs,si549b", .data = &clk_si549b_info }, + { .compatible = "silabs,si549c", .data = &clk_si549c_info }, { } }; MODULE_DEVICE_TABLE(of, clk_si544_of_match); diff --git a/drivers/clk/clk-si570.c b/drivers/clk/clk-si570.c index b0b1830dd430..3063e38c66da 100644 --- a/drivers/clk/clk-si570.c +++ b/drivers/clk/clk-si570.c @@ -503,10 +503,10 @@ static const struct clk_si570_info clk_si590_info = { }; static const struct i2c_device_id si570_id[] = { - { "si570", (kernel_ulong_t)&clk_si570_info }, - { "si571", (kernel_ulong_t)&clk_si570_info }, - { "si598", (kernel_ulong_t)&clk_si590_info }, - { "si599", (kernel_ulong_t)&clk_si590_info }, + { .name = "si570", .driver_data = (kernel_ulong_t)&clk_si570_info }, + { .name = "si571", .driver_data = (kernel_ulong_t)&clk_si570_info }, + { .name = "si598", .driver_data = (kernel_ulong_t)&clk_si590_info }, + { .name = "si599", .driver_data = (kernel_ulong_t)&clk_si590_info }, { } }; MODULE_DEVICE_TABLE(i2c, si570_id); diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index 913fcc5675f1..b51148920216 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -1310,14 +1310,14 @@ static const struct vc5_chip_info idt_5p49v6975_info = { }; static const struct i2c_device_id vc5_id[] = { - { "5p49v5923", .driver_data = (kernel_ulong_t)&idt_5p49v5923_info }, - { "5p49v5925", .driver_data = (kernel_ulong_t)&idt_5p49v5925_info }, - { "5p49v5933", .driver_data = (kernel_ulong_t)&idt_5p49v5933_info }, - { "5p49v5935", .driver_data = (kernel_ulong_t)&idt_5p49v5935_info }, - { "5p49v60", .driver_data = (kernel_ulong_t)&idt_5p49v60_info }, - { "5p49v6901", .driver_data = (kernel_ulong_t)&idt_5p49v6901_info }, - { "5p49v6965", .driver_data = (kernel_ulong_t)&idt_5p49v6965_info }, - { "5p49v6975", .driver_data = (kernel_ulong_t)&idt_5p49v6975_info }, + { .name = "5p49v5923", .driver_data = (kernel_ulong_t)&idt_5p49v5923_info }, + { .name = "5p49v5925", .driver_data = (kernel_ulong_t)&idt_5p49v5925_info }, + { .name = "5p49v5933", .driver_data = (kernel_ulong_t)&idt_5p49v5933_info }, + { .name = "5p49v5935", .driver_data = (kernel_ulong_t)&idt_5p49v5935_info }, + { .name = "5p49v60", .driver_data = (kernel_ulong_t)&idt_5p49v60_info }, + { .name = "5p49v6901", .driver_data = (kernel_ulong_t)&idt_5p49v6901_info }, + { .name = "5p49v6965", .driver_data = (kernel_ulong_t)&idt_5p49v6965_info }, + { .name = "5p49v6975", .driver_data = (kernel_ulong_t)&idt_5p49v6975_info }, { } }; MODULE_DEVICE_TABLE(i2c, vc5_id); diff --git a/drivers/clk/clk-versaclock7.c b/drivers/clk/clk-versaclock7.c index adcc603e3259..1340d2f512be 100644 --- a/drivers/clk/clk-versaclock7.c +++ b/drivers/clk/clk-versaclock7.c @@ -1197,7 +1197,7 @@ static int vc7_probe(struct i2c_client *client) if (ret) { dev_err_probe(&client->dev, ret, "unable to register output %d\n", i); - return ret; + goto err_clk; } switch (bank_src_map.type) { @@ -1288,8 +1288,8 @@ static const struct regmap_config vc7_regmap_config = { }; static const struct i2c_device_id vc7_i2c_id[] = { - { "rc21008a", .driver_data = (kernel_ulong_t)&vc7_rc21008a_info }, - {} + { .name = "rc21008a", .driver_data = (kernel_ulong_t)&vc7_rc21008a_info }, + { } }; MODULE_DEVICE_TABLE(i2c, vc7_i2c_id); diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 048adfa86a5d..fef87167a60b 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -63,6 +63,57 @@ struct clk_parent_map { int index; }; +/** + * struct clk_core - The internal state of a clk in the clk tree. + * @name: Unique name of the clk for identification. + * @ops: Pointer to hardware-specific operations for this clk. + * @hw: Pointer for traversing from a struct clk to its + * corresponding hardware-specific structure. + * @owner: Kernel module owning this clk (for reference counting). + * @dev: Device associated with this clk (optional) + * @rpm_node: Node for runtime power management list management. + * @of_node: Device tree node associated with this clk (if applicable) + * @parent: Pointer to the current parent in the clock tree. + * @parents: Array of possible parents (for muxes/selectable parents). + * @num_parents: Number of possible parents. + * @new_parent_index: Index of the new parent during parent change operations. + * @rate: Current cached clock rate (Hz). + * @req_rate: The last rate requested by a call to clk_set_rate(). It's + * initialized to clk_core->rate. It's also updated to + * clk_core->rate every time the clock is reparented, and + * when we're doing the orphan -> !orphan transition. + * @new_rate: New rate to be set during a rate change operation. + * @new_parent: Pointer to new parent during parent change. This is also + * used when a clk's rate is changed. + * @new_child: Pointer to new child during reparenting. This is also + * used when a clk's rate is changed. + * @flags: Clock property and capability flags. See + * `clk framework flags`. + * @orphan: True if this clk is currently orphaned. + * @rpm_enabled: True if runtime power management is enabled for this clk. + * @enable_count: Reference count of enables. + * @prepare_count: Reference count of prepares. + * @protect_count: Protection reference count against disable. + * @min_rate: Minimum supported clock rate (Hz). + * @max_rate: Maximum supported clock rate (Hz). + * @accuracy: Accuracy of the clock rate (parts per billion). + * @phase: Current phase (degrees). + * @duty: Current duty cycle configuration (as ratio: num/den). + * @children: All of the children of this clk. + * @child_node: Node for linking as a child in the parent's list. + * @hashtable_node: Node for hash table that allows fast clk lookup by name. + * @clks: All of the clk consumers registered. + * @notifier_count: Number of notifiers registered for this clk. + * @dentry: DebugFS entry for this clk. + * @debug_node: DebugFS node for this clk. + * @ref: Reference count for structure lifetime management. + * + * Managed by the clk framework. Clk providers and consumers do not interact + * with this structure directly. Instead, clk operations flow through the + * framework and the framework manipulates this structure to keep track of + * parent/child relationships, rate, enable state, etc. + * + */ struct clk_core { const char *name; const struct clk_ops *ops; @@ -882,6 +933,24 @@ int clk_hw_determine_rate_no_reparent(struct clk_hw *hw, } EXPORT_SYMBOL_GPL(clk_hw_determine_rate_no_reparent); +/** + * clk_determine_rate_noop - clk_ops::determine_rate noop implementation + * @hw: clk to determine rate on + * @req: rate request + * + * Noop determine rate for clocks where the rate rounding is handled by the + * firmware/hardware, or the clock is capable of any rate. The requested rate is + * passed through unchanged, and the actual rate will be learned via + * recalc_rate() after the rate is set. + * + * Returns: 0 always + */ +int clk_determine_rate_noop(struct clk_hw *hw, struct clk_rate_request *req) +{ + return 0; +} +EXPORT_SYMBOL_GPL(clk_determine_rate_noop); + /*** clk api ***/ static void clk_core_rate_unprotect(struct clk_core *core) @@ -1846,10 +1915,10 @@ static int __clk_notify(struct clk_core *core, unsigned long msg, } /** - * __clk_recalc_accuracies + * __clk_recalc_accuracies - recalculate all accuracies in the clk subtree * @core: first clk in the subtree * - * Walks the subtree of clks starting with clk and recalculates accuracies as + * Walks the subtree of clks starting with @core and recalculates accuracies as * it goes. Note that if a clk does not implement the .recalc_accuracy * callback then it is assumed that the clock will take on the accuracy of its * parent. @@ -1919,16 +1988,16 @@ static unsigned long clk_recalc(struct clk_core *core, } /** - * __clk_recalc_rates + * __clk_recalc_rates - recalculate all rates in the clk subtree * @core: first clk in the subtree * @update_req: Whether req_rate should be updated with the new rate * @msg: notification type (see include/linux/clk.h) * - * Walks the subtree of clks starting with clk and recalculates rates as it + * Walks the subtree of clks starting with @core and recalculates rates as it * goes. Note that if a clk does not implement the .recalc_rate callback then * it is assumed that the clock will take on the rate of its parent. * - * clk_recalc_rates also propagates the POST_RATE_CHANGE notification, + * __clk_recalc_rates also propagates the POST_RATE_CHANGE notification, * if necessary. */ static void __clk_recalc_rates(struct clk_core *core, bool update_req, @@ -2191,14 +2260,14 @@ static int __clk_set_parent(struct clk_core *core, struct clk_core *parent, } /** - * __clk_speculate_rates + * __clk_speculate_rates - speculate all rates in the clk subtree * @core: first clk in the subtree * @parent_rate: the "future" rate of clk's parent * - * Walks the subtree of clks starting with clk, speculating rates as it + * Walks the subtree of clks starting with @core, speculating rates as it * goes and firing off PRE_RATE_CHANGE notifications as necessary. * - * Unlike clk_recalc_rates, clk_speculate_rates exists only for sending + * Unlike __clk_recalc_rates, __clk_speculate_rates exists only for sending * pre-rate change notifications and returns early if no clks in the * subtree have subscribed to the notifications. Note that if a clk does not * implement the .recalc_rate callback then it is assumed that the clock will @@ -2774,6 +2843,33 @@ int clk_set_max_rate(struct clk *clk, unsigned long rate) } EXPORT_SYMBOL_GPL(clk_set_max_rate); +int clk_hw_set_spread_spectrum(struct clk_hw *hw, const struct clk_spread_spectrum *ss_conf) +{ + struct clk_core *core; + int ret; + + if (!hw) + return 0; + + core = hw->core; + + clk_prepare_lock(); + + ret = clk_pm_runtime_get(core); + if (ret) + goto fail; + + if (core->ops->set_spread_spectrum) + ret = core->ops->set_spread_spectrum(hw, ss_conf); + + clk_pm_runtime_put(core); + +fail: + clk_prepare_unlock(); + return ret; +} +EXPORT_SYMBOL_GPL(clk_hw_set_spread_spectrum); + /** * clk_get_parent - return the parent of a clk * @clk: the clk whose parent gets returned diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c index b1961daac5e2..1c5c8b7c1f3c 100644 --- a/drivers/clk/clk_test.c +++ b/drivers/clk/clk_test.c @@ -7,6 +7,7 @@ #include #include #include +#include /* Needed for clk_hw_get_clk() */ #include "clk.h" @@ -21,13 +22,14 @@ static const struct clk_ops empty_clk_ops = { }; -#define DUMMY_CLOCK_INIT_RATE (42 * 1000 * 1000) -#define DUMMY_CLOCK_RATE_1 (142 * 1000 * 1000) -#define DUMMY_CLOCK_RATE_2 (242 * 1000 * 1000) +#define DUMMY_CLOCK_INIT_RATE (42 * HZ_PER_MHZ) +#define DUMMY_CLOCK_RATE_1 (142 * HZ_PER_MHZ) +#define DUMMY_CLOCK_RATE_2 (242 * HZ_PER_MHZ) struct clk_dummy_context { struct clk_hw hw; unsigned long rate; + struct clk_spread_spectrum sscs; }; static unsigned long clk_dummy_recalc_rate(struct clk_hw *hw, @@ -83,6 +85,17 @@ static int clk_dummy_set_rate(struct clk_hw *hw, return 0; } +static int clk_dummy_set_spread_spectrum(struct clk_hw *hw, + const struct clk_spread_spectrum *ss_conf) +{ + struct clk_dummy_context *ctx = + container_of(hw, struct clk_dummy_context, hw); + + ctx->sscs = *ss_conf; + + return 0; +} + static int clk_dummy_single_set_parent(struct clk_hw *hw, u8 index) { if (index >= clk_hw_get_num_parents(hw)) @@ -100,18 +113,21 @@ static const struct clk_ops clk_dummy_rate_ops = { .recalc_rate = clk_dummy_recalc_rate, .determine_rate = clk_dummy_determine_rate, .set_rate = clk_dummy_set_rate, + .set_spread_spectrum = clk_dummy_set_spread_spectrum, }; static const struct clk_ops clk_dummy_maximize_rate_ops = { .recalc_rate = clk_dummy_recalc_rate, .determine_rate = clk_dummy_maximize_rate, .set_rate = clk_dummy_set_rate, + .set_spread_spectrum = clk_dummy_set_spread_spectrum, }; static const struct clk_ops clk_dummy_minimize_rate_ops = { .recalc_rate = clk_dummy_recalc_rate, .determine_rate = clk_dummy_minimize_rate, .set_rate = clk_dummy_set_rate, + .set_spread_spectrum = clk_dummy_set_spread_spectrum, }; static const struct clk_ops clk_dummy_single_parent_ops = { @@ -2232,7 +2248,7 @@ static void clk_leaf_mux_set_rate_parent_determine_rate_test_case_to_desc( const struct clk_leaf_mux_set_rate_parent_determine_rate_test_case *t, char *desc) { - strcpy(desc, t->desc); + strscpy(desc, t->desc, KUNIT_PARAM_DESC_SIZE); } static const struct clk_leaf_mux_set_rate_parent_determine_rate_test_case @@ -2644,7 +2660,7 @@ static void clk_register_clk_parent_data_test_case_to_desc( const struct clk_register_clk_parent_data_test_case *t, char *desc) { - strcpy(desc, t->desc); + strscpy(desc, t->desc, KUNIT_PARAM_DESC_SIZE); } static const struct clk_register_clk_parent_data_test_case @@ -3097,6 +3113,7 @@ struct clk_assigned_rates_context { * @overlay_end: Pointer to end of DT overlay to apply for test * @rate0: Initial rate of first clk * @rate1: Initial rate of second clk + * @sscs: Initial spread spectrum settings * @consumer_test: true if a consumer is being tested */ struct clk_assigned_rates_test_param { @@ -3105,6 +3122,7 @@ struct clk_assigned_rates_test_param { u8 *overlay_end; unsigned long rate0; unsigned long rate1; + struct clk_spread_spectrum sscs; bool consumer_test; }; @@ -3116,7 +3134,7 @@ static void clk_assigned_rates_register_clk(struct kunit *test, struct clk_dummy_context *ctx, struct device_node *np, const char *name, - unsigned long rate) + unsigned long rate, const struct clk_spread_spectrum *sscs) { struct clk_init_data init = { }; @@ -3124,6 +3142,7 @@ clk_assigned_rates_register_clk(struct kunit *test, init.ops = &clk_dummy_rate_ops; ctx->hw.init = &init; ctx->rate = rate; + ctx->sscs = *sscs; KUNIT_ASSERT_EQ(test, 0, of_clk_hw_register_kunit(test, np, &ctx->hw)); KUNIT_ASSERT_EQ(test, ctx->rate, rate); @@ -3167,14 +3186,16 @@ static int clk_assigned_rates_test_init(struct kunit *test) KUNIT_ASSERT_LT(test, clk_cells, 2); clk_assigned_rates_register_clk(test, &ctx->clk0, np, - "test_assigned_rate0", test_param->rate0); + "test_assigned_rate0", test_param->rate0, + &test_param->sscs); if (clk_cells == 0) { KUNIT_ASSERT_EQ(test, 0, of_clk_add_hw_provider_kunit(test, np, of_clk_hw_simple_get, &ctx->clk0.hw)); } else if (clk_cells == 1) { clk_assigned_rates_register_clk(test, &ctx->clk1, np, - "test_assigned_rate1", test_param->rate1); + "test_assigned_rate1", test_param->rate1, + &test_param->sscs); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, data = kunit_kzalloc(test, struct_size(data, hws, 2), GFP_KERNEL)); @@ -3403,6 +3424,182 @@ static struct kunit_suite clk_assigned_rates_suite = { .init = clk_assigned_rates_test_init, }; +OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_one); +OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_one_consumer); +OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_multiple); +OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_multiple_consumer); +OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_without); +OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_without_consumer); +OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_zero); +OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_zero_consumer); +OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_null); +OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_null_consumer); + +static void clk_assigned_sscs_assigns_one(struct kunit *test) +{ + struct clk_assigned_rates_context *ctx = test->priv; + + KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.modfreq_hz, ASSIGNED_SSCS_0_MODFREQ); + KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.spread_bp, ASSIGNED_SSCS_0_SPREAD); + KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.method, ASSIGNED_SSCS_0_METHOD); +} + +/* Test cases that assign sscs for one clk */ +static const struct clk_assigned_rates_test_param clk_assigned_sscs_assigns_one_test_params[] = { + { + /* + * Test that a single cell assigned-clock-sscs property + * assigns the sscs when the property is in the provider. + */ + .desc = "provider assigns", + TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_one), + }, + { + /* + * Test that a single cell assigned-clock-sscs property + * assigns the sscs when the property is in the consumer. + */ + .desc = "consumer assigns", + TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_one_consumer), + .consumer_test = true, + }, +}; +KUNIT_ARRAY_PARAM_DESC(clk_assigned_sscs_assigns_one, + clk_assigned_sscs_assigns_one_test_params, desc) + +static void clk_assigned_sscs_assigns_multiple(struct kunit *test) +{ + struct clk_assigned_rates_context *ctx = test->priv; + + KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.modfreq_hz, ASSIGNED_SSCS_0_MODFREQ); + KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.spread_bp, ASSIGNED_SSCS_0_SPREAD); + KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.method, ASSIGNED_SSCS_0_METHOD); + KUNIT_EXPECT_EQ(test, ctx->clk1.sscs.modfreq_hz, ASSIGNED_SSCS_1_MODFREQ); + KUNIT_EXPECT_EQ(test, ctx->clk1.sscs.spread_bp, ASSIGNED_SSCS_1_SPREAD); + KUNIT_EXPECT_EQ(test, ctx->clk1.sscs.method, ASSIGNED_SSCS_1_METHOD); +} + +/* Test cases that assign sscs for multiple clks */ +static const +struct clk_assigned_rates_test_param clk_assigned_sscs_assigns_multiple_test_params[] = { + { + /* + * Test that a multiple cell assigned-clock-sscs property + * assigns the sscs when the property is in the provider. + */ + .desc = "provider assigns", + TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_multiple), + }, + { + /* + * Test that a multiple cell assigned-clock-sscs property + * assigns the sscs when the property is in the consumer. + */ + .desc = "consumer assigns", + TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_multiple_consumer), + .consumer_test = true, + }, +}; +KUNIT_ARRAY_PARAM_DESC(clk_assigned_sscs_assigns_multiple, + clk_assigned_sscs_assigns_multiple_test_params, + desc) + +static void clk_assigned_sscs_skips(struct kunit *test) +{ + struct clk_assigned_rates_context *ctx = test->priv; + const struct clk_assigned_rates_test_param *test_param = test->param_value; + + KUNIT_EXPECT_NE(test, ctx->clk0.sscs.modfreq_hz, ASSIGNED_SSCS_0_MODFREQ); + KUNIT_EXPECT_NE(test, ctx->clk0.sscs.spread_bp, ASSIGNED_SSCS_0_SPREAD); + KUNIT_EXPECT_NE(test, ctx->clk0.sscs.method, ASSIGNED_SSCS_0_METHOD); + KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.modfreq_hz, test_param->sscs.modfreq_hz); + KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.spread_bp, test_param->sscs.spread_bp); + KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.method, test_param->sscs.method); +} + +/* Test cases that skip changing the sscs due to malformed DT */ +static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_params[] = { + { + /* + * Test that an assigned-clock-sscs property without an assigned-clocks + * property fails when the property is in the provider. + */ + .desc = "provider missing assigned-clocks", + TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_without), + .sscs = {50000, 60000, 3}, + }, + { + /* + * Test that an assigned-clock-sscs property without an assigned-clocks + * property fails when the property is in the consumer. + */ + .desc = "consumer missing assigned-clocks", + TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_without_consumer), + .sscs = {50000, 60000, 3}, + .consumer_test = true, + }, + { + /* + * Test that an assigned-clock-sscs property of zero doesn't + * set sscs when the property is in the provider. + */ + .desc = "provider assigned-clock-sscs of zero", + TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_zero), + .sscs = {50000, 60000, 3}, + }, + { + /* + * Test that an assigned-clock-sscs property of zero doesn't + * set sscs when the property is in the consumer. + */ + .desc = "consumer assigned-clock-sscs of zero", + TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_zero_consumer), + .sscs = {50000, 60000, 3}, + .consumer_test = true, + }, + { + /* + * Test that an assigned-clocks property with a null phandle + * doesn't set sscs when the property is in the provider. + */ + .desc = "provider assigned-clocks null phandle", + TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_null), + .sscs = {50000, 60000, 3}, + }, + { + /* + * Test that an assigned-clocks property with a null phandle + * doesn't set sscs when the property is in the consumer. + */ + .desc = "consumer assigned-clocks null phandle", + TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_null_consumer), + .sscs = {50000, 60000, 3}, + .consumer_test = true, + }, +}; +KUNIT_ARRAY_PARAM_DESC(clk_assigned_sscs_skips, + clk_assigned_sscs_skips_test_params, + desc) + +static struct kunit_case clk_assigned_sscs_test_cases[] = { + KUNIT_CASE_PARAM(clk_assigned_sscs_assigns_one, + clk_assigned_sscs_assigns_one_gen_params), + KUNIT_CASE_PARAM(clk_assigned_sscs_assigns_multiple, + clk_assigned_sscs_assigns_multiple_gen_params), + KUNIT_CASE_PARAM(clk_assigned_sscs_skips, + clk_assigned_sscs_skips_gen_params), + {} +}; + +/* + * Test suite for assigned-clock-sscs DT property. + */ +static struct kunit_suite clk_assigned_sscs_suite = { + .name = "clk_assigned_sscs", + .test_cases = clk_assigned_sscs_test_cases, + .init = clk_assigned_rates_test_init, +}; + static const struct clk_init_data clk_hw_get_dev_of_node_init_data = { .name = "clk_hw_get_dev_of_node", .ops = &empty_clk_ops, @@ -3544,6 +3741,7 @@ static struct kunit_suite clk_hw_get_dev_of_node_test_suite = { kunit_test_suites( &clk_assigned_rates_suite, + &clk_assigned_sscs_suite, &clk_hw_get_dev_of_node_test_suite, &clk_leaf_mux_set_rate_parent_test_suite, &clk_test_suite, diff --git a/drivers/clk/eswin/Kconfig b/drivers/clk/eswin/Kconfig index 0406ec499ec9..37857bd77335 100644 --- a/drivers/clk/eswin/Kconfig +++ b/drivers/clk/eswin/Kconfig @@ -13,3 +13,16 @@ config COMMON_CLK_EIC7700 SoC. The clock controller generates and supplies clocks to various peripherals within the SoC. Say yes here to support the clock controller on the EIC7700 SoC. + +config COMMON_CLK_EIC7700_HSP + tristate "EIC7700 HSP Clock Driver" + depends on ARCH_ESWIN || COMPILE_TEST + select AUXILIARY_BUS + select COMMON_CLK_EIC7700 + select RESET_EIC7700_HSP if RESET_CONTROLLER + select REGMAP_MMIO + help + This driver provides support for clock controller on ESWIN EIC7700 + HSP. The clock controller generates and supplies clocks to high + speed peripherals within the SoC. + Say yes here to support the clock controller on the EIC7700 HSP. diff --git a/drivers/clk/eswin/Makefile b/drivers/clk/eswin/Makefile index 4a7c2af82164..21a09a3396df 100644 --- a/drivers/clk/eswin/Makefile +++ b/drivers/clk/eswin/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_COMMON_CLK_ESWIN) += clk.o obj-$(CONFIG_COMMON_CLK_EIC7700) += clk-eic7700.o +obj-$(CONFIG_COMMON_CLK_EIC7700_HSP) += clk-eic7700-hsp.o diff --git a/drivers/clk/eswin/clk-eic7700-hsp.c b/drivers/clk/eswin/clk-eic7700-hsp.c new file mode 100644 index 000000000000..6ddb8fbd605e --- /dev/null +++ b/drivers/clk/eswin/clk-eic7700-hsp.c @@ -0,0 +1,345 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd.. + * All rights reserved. + * + * ESWIN EIC7700 HSP Clock Driver + * + * Authors: Xuyang Dong + */ + +#include +#include +#include +#include + +#include + +#include "common.h" + +#define EIC7700_HSP_SATA_REG 0x300 +#define EIC7700_HSP_MSHC0_REG 0x510 +#define EIC7700_HSP_MSHC1_REG 0x610 +#define EIC7700_HSP_MSHC2_REG 0x710 +#define EIC7700_HSP_USB0_REG 0x800 +#define EIC7700_HSP_USB0_REF_REG 0x83c +#define EIC7700_HSP_USB1_REG 0x900 +#define EIC7700_HSP_USB1_REF_REG 0x93c + +#define USB_REF_XTAL24M 0x2a +#define EIC7700_HSP_NR_CLKS (EIC7700_HSP_CLK_GATE_SATA + 1) + +struct eic7700_hsp_clk_gate { + struct clk_hw hw; + unsigned int id; + struct regmap *regmap; + unsigned int reg; + unsigned int ref_reg; + const char *name; + const struct clk_parent_data *parent_data; + unsigned long flags; + unsigned int offset; + unsigned int ref_offset; + u8 bit_idx; +}; + +static const struct regmap_config eic7700_hsp_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .max_register = 0x1ffc, + .reg_stride = 4, + .fast_io = true, + .use_raw_spinlock = true, +}; + +static inline struct eic7700_hsp_clk_gate *to_gate_clk(struct clk_hw *hw) +{ + return container_of(hw, struct eic7700_hsp_clk_gate, hw); +} + +#define EIC7700_HSP_GATE(_id, _name, _pdata, _flags, _offset, _idx, \ + _ref_offset) \ + { \ + .id = _id, \ + .name = _name, \ + .parent_data = _pdata, \ + .flags = _flags, \ + .offset = _offset, \ + .ref_offset = _ref_offset, \ + .bit_idx = _idx, \ + } + +static void hsp_clk_gate_endisable(struct clk_hw *hw, bool enable) +{ + struct eic7700_hsp_clk_gate *gate = to_gate_clk(hw); + + if (enable) { + /* + * Hardware bug: The USB reference clock must be 24MHz. + * The default register value after reset is invalid. + * Workaround: Rewrite the correct value before enabling + * the USB gate clock. + */ + regmap_update_bits(gate->regmap, gate->ref_reg, 0x3f, + USB_REF_XTAL24M); + } + regmap_assign_bits(gate->regmap, gate->reg, BIT(gate->bit_idx), enable); +} + +static int hsp_clk_gate_enable(struct clk_hw *hw) +{ + hsp_clk_gate_endisable(hw, true); + + return 0; +} + +static void hsp_clk_gate_disable(struct clk_hw *hw) +{ + hsp_clk_gate_endisable(hw, false); +} + +static int hsp_clk_gate_is_enabled(struct clk_hw *hw) +{ + struct eic7700_hsp_clk_gate *gate = to_gate_clk(hw); + unsigned int val; + int ret; + + ret = regmap_read(gate->regmap, gate->reg, &val); + if (ret != 0) + return ret; + + return !!(val & BIT(gate->bit_idx)); +} + +static const struct clk_ops hsp_clk_gate_ops = { + .enable = hsp_clk_gate_enable, + .disable = hsp_clk_gate_disable, + .is_enabled = hsp_clk_gate_is_enabled, +}; + +static struct clk_hw * +hsp_clk_register_gate(struct device *dev, unsigned int id, const char *name, + const struct clk_parent_data *parent_data, + unsigned long flags, struct regmap *regmap, + unsigned int reg, unsigned int ref_reg, u8 bit_idx) +{ + struct eic7700_hsp_clk_gate *gate; + struct clk_init_data init = {}; + struct clk_hw *hw; + int ret; + + gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &hsp_clk_gate_ops; + init.flags = flags; + init.parent_data = parent_data; + init.num_parents = 1; + + gate->id = id; + gate->regmap = regmap; + gate->reg = reg; + gate->ref_reg = ref_reg; + gate->bit_idx = bit_idx; + gate->hw.init = &init; + + hw = &gate->hw; + ret = devm_clk_hw_register(dev, hw); + if (ret) + hw = ERR_PTR(ret); + + return hw; +} + +static const struct clk_parent_data hsp_cfg[] = { + { .index = 0 } +}; + +static const struct clk_parent_data hsp_mmc[] = { + { .index = 1 } +}; + +static const struct clk_parent_data hsp_usb_sata[] = { + { .index = 2 } +}; + +static struct eswin_fixed_factor_clock eic7700_hsp_factor_clks[] = { + ESWIN_FACTOR(EIC7700_HSP_CLK_FAC_CFG_DIV2, "factor_hsp_cfg_div2", + hsp_cfg, 1, 2, 0), + ESWIN_FACTOR(EIC7700_HSP_CLK_FAC_CFG_DIV4, "factor_hsp_cfg_div4", + hsp_cfg, 1, 4, 0), + ESWIN_FACTOR(EIC7700_HSP_CLK_FAC_MMC_DIV10, "factor_hsp_mmc_div10", + hsp_mmc, 1, 10, 0), +}; + +static struct eswin_gate_clock eic7700_hsp_gate_clks[] = { + ESWIN_GATE(EIC7700_HSP_CLK_GATE_SATA, "gate_clk_hsp_sata", hsp_usb_sata, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + EIC7700_HSP_SATA_REG, 28, 0), + ESWIN_GATE(EIC7700_HSP_CLK_GATE_MSHC0_TMR, "gate_clk_hsp_mshc0_tmr", + hsp_mmc, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + EIC7700_HSP_MSHC0_REG, 8, 0), + ESWIN_GATE(EIC7700_HSP_CLK_GATE_MSHC1_TMR, "gate_clk_hsp_mshc1_tmr", + hsp_mmc, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + EIC7700_HSP_MSHC1_REG, 8, 0), + ESWIN_GATE(EIC7700_HSP_CLK_GATE_MSHC2_TMR, "gate_clk_hsp_mshc2_tmr", + hsp_mmc, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + EIC7700_HSP_MSHC2_REG, 8, 0), +}; + +static struct eic7700_hsp_clk_gate eic7700_hsp_spec_gate_clks[] = { + EIC7700_HSP_GATE(EIC7700_HSP_CLK_GATE_USB0, "gate_clk_hsp_usb0", + hsp_usb_sata, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + EIC7700_HSP_USB0_REG, 28, EIC7700_HSP_USB0_REF_REG), + EIC7700_HSP_GATE(EIC7700_HSP_CLK_GATE_USB1, "gate_clk_hsp_usb1", + hsp_usb_sata, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + EIC7700_HSP_USB1_REG, 28, EIC7700_HSP_USB1_REF_REG), +}; + +static const struct clk_parent_data mux_mmc_3mux1_p[] = { + { .fw_name = "cfg" }, + { .hw = &eic7700_hsp_factor_clks[0].hw }, + { .hw = &eic7700_hsp_factor_clks[1].hw }, +}; + +static const struct clk_parent_data mux_mmc_2mux1_p[] = { + { .fw_name = "mmc" }, + { .hw = &eic7700_hsp_factor_clks[2].hw }, +}; + +static u32 mux_mmc_3mux1_tbl[] = { 0x0, 0x1, 0x3 }; + +static struct eswin_mux_clock eic7700_hsp_mux_clks[] = { + ESWIN_MUX_TBL(EIC7700_HSP_CLK_MUX_EMMC_3MUX1, "mux_hsp_emmc_3mux1", + mux_mmc_3mux1_p, ARRAY_SIZE(mux_mmc_3mux1_p), + CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC0_REG, 16, 2, 0, + mux_mmc_3mux1_tbl), + ESWIN_MUX_TBL(EIC7700_HSP_CLK_MUX_SD0_3MUX1, "mux_hsp_sd0_3mux1", + mux_mmc_3mux1_p, ARRAY_SIZE(mux_mmc_3mux1_p), + CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC1_REG, 16, 2, 0, + mux_mmc_3mux1_tbl), + ESWIN_MUX_TBL(EIC7700_HSP_CLK_MUX_SD1_3MUX1, "mux_hsp_sd1_3mux1", + mux_mmc_3mux1_p, ARRAY_SIZE(mux_mmc_3mux1_p), + CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC2_REG, 16, 2, 0, + mux_mmc_3mux1_tbl), + ESWIN_MUX(EIC7700_HSP_CLK_MUX_EMMC_CQE_2MUX1, "mux_hsp_emmc_cqe_2mux1", + mux_mmc_2mux1_p, ARRAY_SIZE(mux_mmc_2mux1_p), + CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC0_REG, 0, 1, 0), + ESWIN_MUX(EIC7700_HSP_CLK_MUX_SD0_CQE_2MUX1, "mux_hsp_sd0_cqe_2mux1", + mux_mmc_2mux1_p, ARRAY_SIZE(mux_mmc_2mux1_p), + CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC1_REG, 0, 1, 0), + ESWIN_MUX(EIC7700_HSP_CLK_MUX_SD1_CQE_2MUX1, "mux_hsp_sd1_cqe_2mux1", + mux_mmc_2mux1_p, ARRAY_SIZE(mux_mmc_2mux1_p), + CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC2_REG, 0, 1, 0), +}; + +static struct eswin_clk_info eic7700_hsp_clks[] = { + ESWIN_GATE_TYPE(EIC7700_HSP_CLK_GATE_EMMC, "gate_clk_hsp_emmc", + EIC7700_HSP_CLK_MUX_EMMC_3MUX1, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + EIC7700_HSP_MSHC0_REG, 24, 0), + ESWIN_GATE_TYPE(EIC7700_HSP_CLK_GATE_SD0, "gate_clk_hsp_sd0", + EIC7700_HSP_CLK_MUX_SD0_3MUX1, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + EIC7700_HSP_MSHC1_REG, 24, 0), + ESWIN_GATE_TYPE(EIC7700_HSP_CLK_GATE_SD1, "gate_clk_hsp_sd1", + EIC7700_HSP_CLK_MUX_SD1_3MUX1, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + EIC7700_HSP_MSHC2_REG, 24, 0), +}; + +static int eic7700_hsp_clk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct auxiliary_device *adev; + struct eswin_clock_data *data; + struct regmap *regmap; + struct clk_hw *hw; + int i, ret; + + data = eswin_clk_init(pdev, EIC7700_HSP_NR_CLKS); + if (IS_ERR(data)) + return dev_err_probe(dev, PTR_ERR(data), + "failed to get clk data!\n"); + + regmap = devm_regmap_init_mmio(dev, data->base, + &eic7700_hsp_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "failed to get regmap!\n"); + + ret = eswin_clk_register_fixed_factor(dev, eic7700_hsp_factor_clks, + ARRAY_SIZE(eic7700_hsp_factor_clks), + data); + if (ret) + return dev_err_probe(dev, ret, + "failed to register fixed factor clock\n"); + + ret = eswin_clk_register_gate(dev, eic7700_hsp_gate_clks, + ARRAY_SIZE(eic7700_hsp_gate_clks), data); + if (ret) + return dev_err_probe(dev, ret, + "failed to register gate clock\n"); + + ret = eswin_clk_register_mux(dev, eic7700_hsp_mux_clks, + ARRAY_SIZE(eic7700_hsp_mux_clks), + data); + if (ret) + return dev_err_probe(dev, ret, + "failed to register mux clock\n"); + + ret = eswin_clk_register_clks(dev, eic7700_hsp_clks, + ARRAY_SIZE(eic7700_hsp_clks), data); + if (ret) + return dev_err_probe(dev, ret, + "failed to register clock\n"); + + for (i = 0; i < ARRAY_SIZE(eic7700_hsp_spec_gate_clks); i++) { + struct eic7700_hsp_clk_gate *gate; + + gate = &eic7700_hsp_spec_gate_clks[i]; + hw = hsp_clk_register_gate(dev, gate->id, gate->name, + gate->parent_data, gate->flags, + regmap, gate->offset, + gate->ref_offset, gate->bit_idx); + if (IS_ERR(hw)) + return dev_err_probe(dev, PTR_ERR(hw), + "failed to register gate clock\n"); + + data->clk_data.hws[gate->id] = hw; + } + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + &data->clk_data); + if (ret) + return dev_err_probe(dev, ret, "add clk provider failed\n"); + + adev = devm_auxiliary_device_create(dev, "hsp-reset", NULL); + if (!adev) + return dev_err_probe(dev, -ENODEV, + "register hsp-reset device failed\n"); + + return 0; +} + +static const struct of_device_id eic7700_hsp_clock_dt_ids[] = { + { .compatible = "eswin,eic7700-hspcrg", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, eic7700_hsp_clock_dt_ids); + +static struct platform_driver eic7700_hsp_clock_driver = { + .probe = eic7700_hsp_clk_probe, + .driver = { + .name = "eic7700-hsp-clock", + .of_match_table = eic7700_hsp_clock_dt_ids, + }, +}; + +module_platform_driver(eic7700_hsp_clock_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Xuyang Dong "); +MODULE_DESCRIPTION("ESWIN EIC7700 HSP clock controller driver"); diff --git a/drivers/clk/eswin/clk-eic7700.c b/drivers/clk/eswin/clk-eic7700.c index be81d74192da..43a47fe16ab1 100644 --- a/drivers/clk/eswin/clk-eic7700.c +++ b/drivers/clk/eswin/clk-eic7700.c @@ -791,7 +791,8 @@ static struct eswin_clk_info eic7700_clks[] = { EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE, CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_U84, 27, 0), ESWIN_GATE_TYPE(EIC7700_CLK_GATE_NOC_NSP_CLK, "gate_noc_nsp_clk", - EIC7700_CLK_DIV_NOC_NSP_DYNM, CLK_SET_RATE_PARENT, + EIC7700_CLK_DIV_NOC_NSP_DYNM, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, EIC7700_REG_OFFSET_NOC, 31, 0), ESWIN_GATE_TYPE(EIC7700_CLK_GATE_BOOTSPI, "gate_clk_bootspi", EIC7700_CLK_MUX_BOOTSPI_CLK_2MUX1_GFREE, diff --git a/drivers/clk/eswin/clk.c b/drivers/clk/eswin/clk.c index e09a52cc3587..79d1e4c5e637 100644 --- a/drivers/clk/eswin/clk.c +++ b/drivers/clk/eswin/clk.c @@ -204,7 +204,7 @@ int eswin_clk_register_pll(struct device *dev, struct eswin_pll_clock *clks, int nums, struct eswin_clock_data *data) { struct eswin_clk_pll *p_clk = NULL; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_hw *clk_hw; int i, ret; @@ -419,7 +419,7 @@ struct clk_hw *eswin_register_clkdiv(struct device *dev, unsigned int id, unsigned long priv_flag, spinlock_t *lock) { struct eswin_divider_clock *dclk; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_hw *clk_hw; int ret; diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig index c1ec75aa4ccd..e70bcfa9105b 100644 --- a/drivers/clk/hisilicon/Kconfig +++ b/drivers/clk/hisilicon/Kconfig @@ -1,8 +1,13 @@ # SPDX-License-Identifier: GPL-2.0-only +config COMMON_CLK_HISI + bool + default ARCH_HISI + config COMMON_CLK_HI3516CV300 tristate "HI3516CV300 Clock Driver" depends on ARCH_HISI || COMPILE_TEST select RESET_HISI + select COMMON_CLK_HISI default ARCH_HISI help Build the clock driver for hi3516cv300. @@ -11,6 +16,7 @@ config COMMON_CLK_HI3519 tristate "Hi3519 Clock Driver" depends on ARCH_HISI || COMPILE_TEST select RESET_HISI + select COMMON_CLK_HISI default ARCH_HISI help Build the clock driver for hi3519. @@ -19,6 +25,7 @@ config COMMON_CLK_HI3559A bool "Hi3559A Clock Driver" depends on ARCH_HISI || COMPILE_TEST select RESET_HISI + select COMMON_CLK_HISI default ARCH_HISI help Build the clock driver for hi3559a. @@ -26,6 +33,7 @@ config COMMON_CLK_HI3559A config COMMON_CLK_HI3660 bool "Hi3660 Clock Driver" depends on ARCH_HISI || COMPILE_TEST + select COMMON_CLK_HISI default ARCH_HISI help Build the clock driver for hi3660. @@ -33,6 +41,7 @@ config COMMON_CLK_HI3660 config COMMON_CLK_HI3670 bool "Hi3670 Clock Driver" depends on ARCH_HISI || COMPILE_TEST + select COMMON_CLK_HISI default ARCH_HISI help Build the clock driver for hi3670. @@ -41,6 +50,7 @@ config COMMON_CLK_HI3798CV200 tristate "Hi3798CV200 Clock Driver" depends on ARCH_HISI || COMPILE_TEST select RESET_HISI + select COMMON_CLK_HISI default ARCH_HISI help Build the clock driver for hi3798cv200. @@ -48,6 +58,7 @@ config COMMON_CLK_HI3798CV200 config COMMON_CLK_HI6220 bool "Hi6220 Clock Driver" depends on ARCH_HISI || COMPILE_TEST + select COMMON_CLK_HISI default ARCH_HISI help Build the Hisilicon Hi6220 clock driver based on the common clock framework. @@ -55,6 +66,7 @@ config COMMON_CLK_HI6220 config RESET_HISI bool "HiSilicon Reset Controller Driver" depends on ARCH_HISI || COMPILE_TEST + select COMMON_CLK_HISI select RESET_CONTROLLER help Build reset controller driver for HiSilicon device chipsets. @@ -63,6 +75,7 @@ config STUB_CLK_HI6220 bool "Hi6220 Stub Clock Driver" if EXPERT depends on (COMMON_CLK_HI6220 || COMPILE_TEST) depends on MAILBOX + select COMMON_CLK_HISI default COMMON_CLK_HI6220 help Build the Hisilicon Hi6220 stub clock driver. @@ -71,6 +84,7 @@ config STUB_CLK_HI3660 bool "Hi3660 Stub Clock Driver" if EXPERT depends on (COMMON_CLK_HI3660 || COMPILE_TEST) depends on MAILBOX + select COMMON_CLK_HISI default COMMON_CLK_HI3660 help Build the Hisilicon Hi3660 stub clock driver. diff --git a/drivers/clk/hisilicon/clk-hi3660-stub.c b/drivers/clk/hisilicon/clk-hi3660-stub.c index 7c8b00ee6019..d28118f4cfb8 100644 --- a/drivers/clk/hisilicon/clk-hi3660-stub.c +++ b/drivers/clk/hisilicon/clk-hi3660-stub.c @@ -67,16 +67,6 @@ static unsigned long hi3660_stub_clk_recalc_rate(struct clk_hw *hw, return stub_clk->rate; } -static int hi3660_stub_clk_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - /* - * LPM3 handles rate rounding so just return whatever - * rate is requested. - */ - return 0; -} - static int hi3660_stub_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -97,7 +87,7 @@ static int hi3660_stub_clk_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops hi3660_stub_clk_ops = { .recalc_rate = hi3660_stub_clk_recalc_rate, - .determine_rate = hi3660_stub_clk_determine_rate, + .determine_rate = clk_determine_rate_noop, .set_rate = hi3660_stub_clk_set_rate, }; @@ -124,7 +114,6 @@ static struct clk_hw *hi3660_stub_clk_hw_get(struct of_phandle_args *clkspec, static int hi3660_stub_clk_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct resource *res; unsigned int i; int ret; @@ -139,12 +128,9 @@ static int hi3660_stub_clk_probe(struct platform_device *pdev) if (IS_ERR(stub_clk_chan.mbox)) return PTR_ERR(stub_clk_chan.mbox); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EINVAL; - freq_reg = devm_ioremap(dev, res->start, resource_size(res)); - if (!freq_reg) - return -ENOMEM; + freq_reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(freq_reg)) + return PTR_ERR(freq_reg); freq_reg += HI3660_STUB_CLOCK_DATA; diff --git a/drivers/clk/hisilicon/reset.c b/drivers/clk/hisilicon/reset.c index 93cee17db8b1..c3b7daac9313 100644 --- a/drivers/clk/hisilicon/reset.c +++ b/drivers/clk/hisilicon/reset.c @@ -91,7 +91,7 @@ struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev) { struct hisi_reset_controller *rstc; - rstc = devm_kmalloc(&pdev->dev, sizeof(*rstc), GFP_KERNEL); + rstc = devm_kzalloc(&pdev->dev, sizeof(*rstc), GFP_KERNEL); if (!rstc) return NULL; diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 319af4deec01..89d442415a01 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -300,6 +300,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; + struct clk_hw *audio_pll_hws[2]; void __iomem *base; int ret; @@ -610,6 +611,11 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) imx_register_uart_clocks(); + /* Add debug interface for audio PLLs */ + audio_pll_hws[0] = hws[IMX8MM_AUDIO_PLL1]; + audio_pll_hws[1] = hws[IMX8MM_AUDIO_PLL2]; + imx_audio_pll_debug_init(audio_pll_hws, ARRAY_SIZE(audio_pll_hws)); + return 0; unregister_hws: diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c b/drivers/clk/imx/clk-imx8qxp-lpcg.c index 1dae3410ee99..f0cf6cf91899 100644 --- a/drivers/clk/imx/clk-imx8qxp-lpcg.c +++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c @@ -354,6 +354,7 @@ static const struct of_device_id imx8qxp_lpcg_match[] = { { .compatible = "fsl,imx8qxp-lpcg", NULL }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx8qxp_lpcg_match); static struct platform_driver imx8qxp_lpcg_clk_driver = { .driver = { diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c index 17302ee628b7..20a9dea5581e 100644 --- a/drivers/clk/imx/clk-imx8qxp.c +++ b/drivers/clk/imx/clk-imx8qxp.c @@ -337,6 +337,7 @@ static const struct of_device_id imx8qxp_match[] = { { .compatible = "fsl,imx8qm-clk", &imx_clk_scu_rsrc_imx8qm, }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx8qxp_match); static struct platform_driver imx8qxp_clk_driver = { .driver = { diff --git a/drivers/clk/imx/clk-imx95-blk-ctl.c b/drivers/clk/imx/clk-imx95-blk-ctl.c index 56bed4471995..bc6957299cec 100644 --- a/drivers/clk/imx/clk-imx95-blk-ctl.c +++ b/drivers/clk/imx/clk-imx95-blk-ctl.c @@ -44,6 +44,8 @@ struct imx95_blk_ctl_clk_dev_data { const char * const *parent_names; u32 num_parents; u32 reg; + u32 reg_init_msk; + u32 reg_init_val; u32 bit_idx; u32 bit_width; u32 clk_type; @@ -286,10 +288,22 @@ static const struct imx95_blk_ctl_dev_data netcmix_dev_data = { static const struct imx95_blk_ctl_clk_dev_data hsio_blk_ctl_clk_dev_data[] = { [0] = { .name = "hsio_blk_ctl_clk", + .parent_names = (const char *[]){ "func_out_en", }, + .num_parents = 1, + .reg = 0, + .reg_init_msk = GENMASK(10, 7), + .reg_init_val = GENMASK(10, 7), + .bit_idx = 6, + .bit_width = 1, + .type = CLK_GATE, + .flags = CLK_SET_RATE_PARENT, + }, + [1] = { + .name = "func_out_en", .parent_names = (const char *[]){ "hsio_pll", }, .num_parents = 1, .reg = 0, - .bit_idx = 6, + .bit_idx = 2, .bit_width = 1, .type = CLK_GATE, .flags = CLK_SET_RATE_PARENT, @@ -297,7 +311,7 @@ static const struct imx95_blk_ctl_clk_dev_data hsio_blk_ctl_clk_dev_data[] = { }; static const struct imx95_blk_ctl_dev_data hsio_blk_ctl_dev_data = { - .num_clks = 1, + .num_clks = ARRAY_SIZE(hsio_blk_ctl_clk_dev_data), .clk_dev_data = hsio_blk_ctl_clk_dev_data, .clk_reg_offset = 0, }; @@ -400,6 +414,9 @@ static int imx95_bc_probe(struct platform_device *pdev) const struct imx95_blk_ctl_clk_dev_data *data = &bc->pdata->clk_dev_data[i]; void __iomem *reg = base + data->reg; + if (data->reg_init_msk) + writel((readl(reg) & ~data->reg_init_msk) | data->reg_init_val, reg); + if (data->type == CLK_MUX) { hws[i] = clk_hw_register_mux(dev, data->name, data->parent_names, data->num_parents, data->flags, reg, diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 39600ee22be3..b6f1cc9f5700 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -8,11 +8,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include "clk.h" @@ -40,6 +42,8 @@ struct clk_pll14xx { enum imx_pll14xx_type type; const struct imx_pll14xx_rate_table *rate_table; int rate_count; + s16 delta_k; + spinlock_t lock; }; #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw) @@ -134,6 +138,7 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat u32 pll_div_ctl0, pll_div_ctl1; int mdiv, pdiv, sdiv, kdiv; long fout, rate_min, rate_max, dist, best = LONG_MAX; + unsigned long flags; const struct imx_pll14xx_rate_table *tt; /* @@ -161,11 +166,16 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat return; } + spin_lock_irqsave(&pll->lock, flags); + pll_div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); + pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); + + spin_unlock_irqrestore(&pll->lock, flags); + mdiv = FIELD_GET(MDIV_MASK, pll_div_ctl0); pdiv = FIELD_GET(PDIV_MASK, pll_div_ctl0); sdiv = FIELD_GET(SDIV_MASK, pll_div_ctl0); - pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); /* Then see if we can get the desired rate by only adjusting kdiv (glitch free) */ rate_min = pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, KDIV_MIN, prate); @@ -361,11 +371,14 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, { struct clk_pll14xx *pll = to_clk_pll14xx(hw); struct imx_pll14xx_rate_table rate; + unsigned long flags; u32 gnrl_ctl, div_ctl0; int ret; imx_pll14xx_calc_settings(pll, drate, prate, &rate); + spin_lock_irqsave(&pll->lock, flags); + div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); if (!clk_pll14xx_mp_change(&rate, div_ctl0)) { @@ -377,6 +390,8 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, writel_relaxed(FIELD_PREP(KDIV_MASK, rate.kdiv), pll->base + DIV_CTL1); + spin_unlock_irqrestore(&pll->lock, flags); + return 0; } @@ -396,6 +411,8 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, writel_relaxed(FIELD_PREP(KDIV_MASK, rate.kdiv), pll->base + DIV_CTL1); + spin_unlock_irqrestore(&pll->lock, flags); + /* * According to SPEC, t3 - t2 need to be greater than * 1us and 1/FREF, respectively. @@ -508,6 +525,8 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name, if (!pll) return ERR_PTR(-ENOMEM); + spin_lock_init(&pll->lock); + init.name = name; init.flags = pll_clk->flags; init.parent_names = &parent_name; @@ -551,3 +570,101 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name, return hw; } EXPORT_SYMBOL_GPL(imx_dev_clk_hw_pll14xx); + +/* + * Debugfs interface for Audio PLL runtime monitoring and control + * + * This interface allows dynamic adjustment of the Audio PLL + * K-divider for precise frequency tuning, particularly useful + * for audio applications. + * + * examples for the usage of the two interfaces: + * 1): Get the current PLL setting of dividers + * cat /sys/kernel/debug/audio_pll_monitor/audio_pll1/pll_parameter + * + * 2): Adjust the K-divider by a small delta_k + * echo 1 > /sys/kernel/debug/audio_pll_monitor/audio_pll1/delta_k; + */ +#ifdef CONFIG_DEBUG_FS +static int pll_delta_k_get(void *data, u64 *val) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(data); + *val = pll->delta_k; + return 0; +} + +static int pll_delta_k_set(void *data, u64 val) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(data); + unsigned long flags; + u32 div_ctl1; + s16 kdiv, delta_k; + + delta_k = (s16)clamp_t(s64, val, KDIV_MIN, KDIV_MAX); + + spin_lock_irqsave(&pll->lock, flags); + + pll->delta_k = delta_k; + + div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); + kdiv = (s16)FIELD_GET(KDIV_MASK, div_ctl1); + kdiv = (s16)clamp_t(s32, (s32)kdiv + delta_k, KDIV_MIN, KDIV_MAX); + writel_relaxed(FIELD_PREP(KDIV_MASK, kdiv), pll->base + DIV_CTL1); + + spin_unlock_irqrestore(&pll->lock, flags); + + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(delta_k_fops, pll_delta_k_get, pll_delta_k_set, "%lld\n"); + +static int pll_setting_show(struct seq_file *s, void *data) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(s->private); + unsigned long flags; + u32 div_ctl0, div_ctl1; + u32 mdiv, pdiv, sdiv, kdiv; + + spin_lock_irqsave(&pll->lock, flags); + + div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); + div_ctl1 = readl_relaxed(pll->base + DIV_CTL1); + + spin_unlock_irqrestore(&pll->lock, flags); + + mdiv = FIELD_GET(MDIV_MASK, div_ctl0); + pdiv = FIELD_GET(PDIV_MASK, div_ctl0); + sdiv = FIELD_GET(SDIV_MASK, div_ctl0); + kdiv = FIELD_GET(KDIV_MASK, div_ctl1); + + seq_printf(s, "Mdiv: 0x%x; Pdiv: 0x%x; Sdiv: 0x%x; Kdiv: 0x%x\n", + mdiv, pdiv, sdiv, kdiv); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(pll_setting); + +void imx_audio_pll_debug_init(struct clk_hw *hws[], unsigned int num_plls) +{ + struct dentry *rootdir, *audio_pll_dir; + const char *pll_name; + int i; + + rootdir = debugfs_create_dir("audio_pll_monitor", NULL); + + for (i = 0; i < num_plls; i++) { + if (!IS_ERR_OR_NULL(hws[i])) { + pll_name = clk_hw_get_name(hws[i]); + audio_pll_dir = debugfs_create_dir(pll_name, rootdir); + debugfs_create_file_unsafe("delta_k", 0600, audio_pll_dir, + hws[i], &delta_k_fops); + debugfs_create_file("pll_parameter", 0444, audio_pll_dir, + hws[i], &pll_setting_fops); + } + } +} +#else /* !CONFIG_DEBUG_FS */ +void imx_audio_pll_debug_init(struct clk_hw *hws[], unsigned int num_plls) +{ +} +#endif /* CONFIG_DEBUG_FS */ +EXPORT_SYMBOL_GPL(imx_audio_pll_debug_init); diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index 9b33df9967ec..44220e9c5c2a 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -262,23 +262,6 @@ static unsigned long clk_scu_recalc_rate(struct clk_hw *hw, return le32_to_cpu(msg.data.resp.rate); } -/* - * clk_scu_determine_rate - Returns the closest rate for a SCU clock - * @hw: clock to round rate for - * @req: clock rate request - * - * Returns 0 on success, a negative error on failure - */ -static int clk_scu_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - /* - * Assume we support all the requested rate and let the SCU firmware - * to handle the left work - */ - return 0; -} - static int clk_scu_atf_set_cpu_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -436,7 +419,7 @@ static void clk_scu_unprepare(struct clk_hw *hw) static const struct clk_ops clk_scu_ops = { .recalc_rate = clk_scu_recalc_rate, - .determine_rate = clk_scu_determine_rate, + .determine_rate = clk_determine_rate_noop, .set_rate = clk_scu_set_rate, .get_parent = clk_scu_get_parent, .set_parent = clk_scu_set_parent, @@ -446,7 +429,7 @@ static const struct clk_ops clk_scu_ops = { static const struct clk_ops clk_scu_cpu_ops = { .recalc_rate = clk_scu_recalc_rate, - .determine_rate = clk_scu_determine_rate, + .determine_rate = clk_determine_rate_noop, .set_rate = clk_scu_atf_set_cpu_rate, .prepare = clk_scu_prepare, .unprepare = clk_scu_unprepare, @@ -454,7 +437,7 @@ static const struct clk_ops clk_scu_cpu_ops = { static const struct clk_ops clk_scu_pi_ops = { .recalc_rate = clk_scu_recalc_rate, - .determine_rate = clk_scu_determine_rate, + .determine_rate = clk_determine_rate_noop, .set_rate = clk_scu_set_rate, }; @@ -475,7 +458,6 @@ struct clk_hw *__imx_clk_scu(struct device *dev, const char *name, clk->clk_type = clk_type; init.name = name; - init.ops = &clk_scu_ops; if (rsrc_id == IMX_SC_R_A35 || rsrc_id == IMX_SC_R_A53 || rsrc_id == IMX_SC_R_A72) init.ops = &clk_scu_cpu_ops; else if (rsrc_id == IMX_SC_R_PI_0_PLL) diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index aa5202f284f3..40bb41e353f9 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -487,4 +487,5 @@ struct clk_hw *imx_clk_gpr_mux(const char *name, const char *compatible, u32 reg, const char **parent_names, u8 num_parents, const u32 *mux_table, u32 mask); +void imx_audio_pll_debug_init(struct clk_hw *hws[], unsigned int num_plls); #endif diff --git a/drivers/clk/kunit_clk_assigned_rates.h b/drivers/clk/kunit_clk_assigned_rates.h index df2d84dcaa93..d7ae5ec2d25b 100644 --- a/drivers/clk/kunit_clk_assigned_rates.h +++ b/drivers/clk/kunit_clk_assigned_rates.h @@ -1,8 +1,18 @@ /* SPDX-License-Identifier: GPL-2.0 */ + +#include + #ifndef _KUNIT_CLK_ASSIGNED_RATES_H #define _KUNIT_CLK_ASSIGNED_RATES_H #define ASSIGNED_RATES_0_RATE 1600000 #define ASSIGNED_RATES_1_RATE 9700000 +#define ASSIGNED_SSCS_0_MODFREQ 10000 +#define ASSIGNED_SSCS_0_SPREAD 30000 +#define ASSIGNED_SSCS_0_METHOD CLK_SSC_CENTER_SPREAD +#define ASSIGNED_SSCS_1_MODFREQ 20000 +#define ASSIGNED_SSCS_1_SPREAD 40000 +#define ASSIGNED_SSCS_1_METHOD CLK_SSC_UP_SPREAD + #endif diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso index 389b4e2eb7f7..3a717dab2d00 100644 --- a/drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso +++ b/drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso @@ -12,5 +12,11 @@ <&clk 1>; assigned-clock-rates-u64 = /bits/ 64 , /bits/ 64 ; + assigned-clock-sscs = , + ; }; }; diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_multiple_consumer.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_multiple_consumer.dtso index 3e117fd59b7d..cbee7cbad068 100644 --- a/drivers/clk/kunit_clk_assigned_rates_u64_multiple_consumer.dtso +++ b/drivers/clk/kunit_clk_assigned_rates_u64_multiple_consumer.dtso @@ -16,5 +16,11 @@ <&clk 1>; assigned-clock-rates-u64 = /bits/ 64 , /bits/ 64 ; + assigned-clock-sscs = , + ; }; }; diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_one.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_one.dtso index 87041264e8f5..9b04d6927f08 100644 --- a/drivers/clk/kunit_clk_assigned_rates_u64_one.dtso +++ b/drivers/clk/kunit_clk_assigned_rates_u64_one.dtso @@ -10,5 +10,8 @@ #clock-cells = <0>; assigned-clocks = <&clk>; assigned-clock-rates-u64 = /bits/ 64 ; + assigned-clock-sscs = ; }; }; diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso index 3259c003aec0..4784d40520f4 100644 --- a/drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso +++ b/drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso @@ -14,5 +14,8 @@ compatible = "test,clk-consumer"; assigned-clocks = <&clk>; assigned-clock-rates-u64 = /bits/ 64 ; + assigned-clock-sscs = ; }; }; diff --git a/drivers/clk/kunit_clk_assigned_sscs_multiple.dtso b/drivers/clk/kunit_clk_assigned_sscs_multiple.dtso new file mode 100644 index 000000000000..e3472f95987c --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_sscs_multiple.dtso @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <1>; + assigned-clocks = <&clk 0>, + <&clk 1>; + assigned-clock-sscs = , + ; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_sscs_multiple_consumer.dtso b/drivers/clk/kunit_clk_assigned_sscs_multiple_consumer.dtso new file mode 100644 index 000000000000..6e8971bd272a --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_sscs_multiple_consumer.dtso @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <1>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clocks = <&clk 0>, + <&clk 1>; + assigned-clock-sscs = , + ; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_sscs_null.dtso b/drivers/clk/kunit_clk_assigned_sscs_null.dtso new file mode 100644 index 000000000000..43b2068c845d --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_sscs_null.dtso @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + assigned-clocks = <0>; + assigned-clock-sscs = ; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_sscs_null_consumer.dtso b/drivers/clk/kunit_clk_assigned_sscs_null_consumer.dtso new file mode 100644 index 000000000000..bda008f5aaa3 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_sscs_null_consumer.dtso @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clocks = <0>; + assigned-clock-sscs = ; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_sscs_one.dtso b/drivers/clk/kunit_clk_assigned_sscs_one.dtso new file mode 100644 index 000000000000..91f585b5d8c9 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_sscs_one.dtso @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + assigned-clocks = <&clk>; + assigned-clock-sscs = ; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_sscs_one_consumer.dtso b/drivers/clk/kunit_clk_assigned_sscs_one_consumer.dtso new file mode 100644 index 000000000000..0bc8a03c2041 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_sscs_one_consumer.dtso @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clocks = <&clk>; + assigned-clock-sscs = ; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_sscs_without.dtso b/drivers/clk/kunit_clk_assigned_sscs_without.dtso new file mode 100644 index 000000000000..08660846b55c --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_sscs_without.dtso @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + assigned-clock-sscs = ; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_sscs_without_consumer.dtso b/drivers/clk/kunit_clk_assigned_sscs_without_consumer.dtso new file mode 100644 index 000000000000..e1c089c6f0c0 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_sscs_without_consumer.dtso @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clock-sscs = ; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_sscs_zero.dtso b/drivers/clk/kunit_clk_assigned_sscs_zero.dtso new file mode 100644 index 000000000000..f39f4e754e53 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_sscs_zero.dtso @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + assigned-clocks = <&clk>; + assigned-clock-sscs = <0 0 0>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_sscs_zero_consumer.dtso b/drivers/clk/kunit_clk_assigned_sscs_zero_consumer.dtso new file mode 100644 index 000000000000..d6bd7dfada7e --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_sscs_zero_consumer.dtso @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clocks = <&clk>; + assigned-clock-sscs = <0 0 0>; + }; +}; diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 2c09fd729bab..b059d44577f1 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -537,6 +537,16 @@ config COMMON_CLK_MT8173_IMGSYS help This driver supports MediaTek MT8173 imgsys clocks. +config COMMON_CLK_MT8173_MFGTOP + tristate "Clock and power driver for MediaTek MT8173 mfgtop" + depends on COMMON_CLK_MT8173 + depends on PM + default COMMON_CLK_MT8173 + select PM_GENERIC_DOMAINS + select PM_GENERIC_DOMAINS_OF + help + This driver supports MediaTek MT8173 mfgtop clocks and power domain. + config COMMON_CLK_MT8173_MMSYS tristate "Clock driver for MediaTek MT8173 mmsys" depends on COMMON_CLK_MT8173 @@ -1006,6 +1016,7 @@ config COMMON_CLK_MT8196 tristate "Clock driver for MediaTek MT8196" depends on ARM64 || COMPILE_TEST select COMMON_CLK_MEDIATEK + select REGMAP_MMIO default ARCH_MEDIATEK help This driver supports MediaTek MT8196 basic clocks. diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index d8736a060dbd..892a54eeb281 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -82,6 +82,7 @@ obj-$(CONFIG_COMMON_CLK_MT8167_VDECSYS) += clk-mt8167-vdec.o obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173-apmixedsys.o clk-mt8173-infracfg.o \ clk-mt8173-pericfg.o clk-mt8173-topckgen.o obj-$(CONFIG_COMMON_CLK_MT8173_IMGSYS) += clk-mt8173-img.o +obj-$(CONFIG_COMMON_CLK_MT8173_MFGTOP) += clk-mt8173-mfgtop.o obj-$(CONFIG_COMMON_CLK_MT8173_MMSYS) += clk-mt8173-mm.o obj-$(CONFIG_COMMON_CLK_MT8173_VDECSYS) += clk-mt8173-vdecsys.o obj-$(CONFIG_COMMON_CLK_MT8173_VENCSYS) += clk-mt8173-vencsys.o diff --git a/drivers/clk/mediatek/clk-mt6735-apmixedsys.c b/drivers/clk/mediatek/clk-mt6735-apmixedsys.c index 9e30c089a209..b6eb6a581c31 100644 --- a/drivers/clk/mediatek/clk-mt6735-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt6735-apmixedsys.c @@ -102,9 +102,12 @@ static int clk_mt6735_apmixed_probe(struct platform_device *pdev) ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, clk_data); - if (ret) + if (ret) { dev_err(&pdev->dev, "Failed to register clock provider: %d\n", ret); + mtk_clk_unregister_plls(apmixedsys_plls, ARRAY_SIZE(apmixedsys_plls), + clk_data); + } return ret; } diff --git a/drivers/clk/mediatek/clk-mt6735-vdecsys.c b/drivers/clk/mediatek/clk-mt6735-vdecsys.c index 8817085fc1db..d53ebf92e878 100644 --- a/drivers/clk/mediatek/clk-mt6735-vdecsys.c +++ b/drivers/clk/mediatek/clk-mt6735-vdecsys.c @@ -63,6 +63,7 @@ static const struct of_device_id of_match_mt6735_vdecsys[] = { { .compatible = "mediatek,mt6735-vdecsys", .data = &vdecsys_clks }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, of_match_mt6735_vdecsys); static struct platform_driver clk_mt6735_vdecsys = { .probe = mtk_clk_simple_probe, diff --git a/drivers/clk/mediatek/clk-mt6735-vencsys.c b/drivers/clk/mediatek/clk-mt6735-vencsys.c index 8dec7f98492a..64ba9da9fd42 100644 --- a/drivers/clk/mediatek/clk-mt6735-vencsys.c +++ b/drivers/clk/mediatek/clk-mt6735-vencsys.c @@ -37,6 +37,7 @@ static const struct of_device_id of_match_mt6735_vencsys[] = { { .compatible = "mediatek,mt6735-vencsys", .data = &vencsys_clks }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, of_match_mt6735_vencsys); static struct platform_driver clk_mt6735_vencsys = { .probe = mtk_clk_simple_probe, diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c index 084e48a554c2..1d20e15608f7 100644 --- a/drivers/clk/mediatek/clk-mt8135.c +++ b/drivers/clk/mediatek/clk-mt8135.c @@ -409,6 +409,9 @@ static const struct mtk_gate_regs infra_cg_regs = { GATE_MTK_FLAGS(_id, _name, _parent, &infra_cg_regs, _shift, \ &mtk_clk_gate_ops_setclr, CLK_IS_CRITICAL) +#define GATE_ICG_INV(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &infra_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv) + static const struct mtk_gate infra_clks[] = { GATE_DUMMY(CLK_DUMMY, "infra_dummy"), GATE_ICG(CLK_INFRA_PMIC_WRAP, "pmic_wrap_ck", "axi_sel", 23), @@ -419,7 +422,7 @@ static const struct mtk_gate infra_clks[] = { GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "cpum_tck_in", 15), GATE_ICG_AO(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8), GATE_ICG(CLK_INFRA_MFGAXI, "mfgaxi_ck", "axi_sel", 7), - GATE_ICG(CLK_INFRA_DEVAPC, "devapc_ck", "axi_sel", 6), + GATE_ICG_INV(CLK_INFRA_DEVAPC, "devapc_ck", "axi_sel", 6), GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "aud_intbus_sel", 5), GATE_ICG(CLK_INFRA_MFG_BUS, "mfg_bus_ck", "axi_sel", 2), GATE_ICG(CLK_INFRA_SMI, "smi_ck", "smi_sel", 1), diff --git a/drivers/clk/mediatek/clk-mt8173-mfgtop.c b/drivers/clk/mediatek/clk-mt8173-mfgtop.c new file mode 100644 index 000000000000..5669ca9954dc --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8173-mfgtop.c @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 Google LLC + * Author: Chen-Yu Tsai + * + * Based on driver in downstream ChromeOS v5.15 kernel. + * + * Copyright (c) 2014 MediaTek Inc. + * Author: Chiawen Lee + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk-gate.h" +#include "clk-mtk.h" + +static const struct mtk_gate_regs mfg_cg_regs = { + .sta_ofs = 0x0000, + .clr_ofs = 0x0008, + .set_ofs = 0x0004, +}; + +#define GATE_MFG(_id, _name, _parent, _shift, _flags) \ + GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr, _flags) + +/* TODO: The block actually has dividers for the core and mem clocks. */ +static const struct mtk_gate mfg_clks[] = { + GATE_MFG(CLK_MFG_AXI, "mfg_axi", "axi_mfg_in_sel", 0, CLK_SET_RATE_PARENT), + GATE_MFG(CLK_MFG_MEM, "mfg_mem", "mem_mfg_in_sel", 1, CLK_SET_RATE_PARENT), + GATE_MFG(CLK_MFG_G3D, "mfg_g3d", "mfg_sel", 2, CLK_SET_RATE_PARENT), + GATE_MFG(CLK_MFG_26M, "mfg_26m", "clk26m", 3, 0), +}; + +struct mt8173_mfgtop_data { + struct clk_hw_onecell_data *clk_data; + struct regmap *regmap; + struct generic_pm_domain genpd; + struct of_phandle_args parent_pd, child_pd; + struct clk *clk_26m; +}; + +/* Delay count in clock cycles */ +#define MFG_ACTIVE_POWER_CON0 0x24 + #define RST_B_DELAY_CNT GENMASK(7, 0) /* pwr_rst_b de-assert delay during power-up */ + #define CLK_EN_DELAY_CNT GENMASK(15, 8) /* CLK_DIS deassert delay during power-up */ + #define CLK_DIS_DELAY_CNT GENMASK(23, 16) /* CLK_DIS assert delay during power-down */ + #define FORCE_ABORT BIT(30) /* write 1 to force abort a power event */ + #define ACTIVE_PWRCTL_EN BIT(31) /* enable ACTIVE_POWER */ + +#define MFG_ACTIVE_POWER_CON1 0x28 + #define PWR_ON_S_DELAY_CNT GENMASK(7, 0) /* pwr_on_s assert delay during power-up */ + #define ISO_DELAY_CNT GENMASK(15, 8) /* ISO assert delay during power-down */ + #define ISOOFF_DELAY_CNT GENMASK(23, 16) /* ISO de-assert delay during power-up */ + #define RST_DELAY_CNT GENMASK(31, 24) /* pwr_rsb_b assert delay during power-down */ + +static int clk_mt8173_mfgtop_power_on(struct generic_pm_domain *domain) +{ + struct mt8173_mfgtop_data *data = container_of(domain, struct mt8173_mfgtop_data, genpd); + int ret; + + /* drives internal power management */ + ret = clk_prepare_enable(data->clk_26m); + if (ret) + return ret; + + /* Power on/off delays for various signals */ + regmap_write(data->regmap, MFG_ACTIVE_POWER_CON0, + FIELD_PREP(RST_B_DELAY_CNT, 77) | + FIELD_PREP(CLK_EN_DELAY_CNT, 61) | + FIELD_PREP(CLK_DIS_DELAY_CNT, 60) | + FIELD_PREP(ACTIVE_PWRCTL_EN, 0)); + regmap_write(data->regmap, MFG_ACTIVE_POWER_CON1, + FIELD_PREP(PWR_ON_S_DELAY_CNT, 11) | + FIELD_PREP(ISO_DELAY_CNT, 68) | + FIELD_PREP(ISOOFF_DELAY_CNT, 69) | + FIELD_PREP(RST_DELAY_CNT, 77)); + + /* Magic numbers related to core switch sequence and delays */ + regmap_write(data->regmap, 0xe0, 0x7a710184); + regmap_write(data->regmap, 0xe4, 0x835f6856); + regmap_write(data->regmap, 0xe8, 0x002b0234); + regmap_write(data->regmap, 0xec, 0x80000000); + regmap_write(data->regmap, 0xa0, 0x08000000); + + return 0; +} + +static int clk_mt8173_mfgtop_power_off(struct generic_pm_domain *domain) +{ + struct mt8173_mfgtop_data *data = container_of(domain, struct mt8173_mfgtop_data, genpd); + + /* Magic numbers related to core switch sequence and delays */ + regmap_write(data->regmap, 0xec, 0); + + /* drives internal power management */ + clk_disable_unprepare(data->clk_26m); + + return 0; +} + +static int clk_mt8173_mfgtop_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct mt8173_mfgtop_data *data; + int ret; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + platform_set_drvdata(pdev, data); + + data->clk_data = mtk_devm_alloc_clk_data(dev, ARRAY_SIZE(mfg_clks)); + if (!data->clk_data) + return -ENOMEM; + + /* MTK clock gates also uses regmap */ + data->regmap = device_node_to_regmap(node); + if (IS_ERR(data->regmap)) + return dev_err_probe(dev, PTR_ERR(data->regmap), "Failed to get regmap\n"); + + data->child_pd.np = node; + data->child_pd.args_count = 0; + ret = of_parse_phandle_with_args(node, "power-domains", "#power-domain-cells", 0, + &data->parent_pd); + if (ret) + return dev_err_probe(dev, ret, "Failed to parse power domain\n"); + + devm_pm_runtime_enable(dev); + /* + * Do a pm_runtime_resume_and_get() to workaround a possible + * deadlock between clk_register() and the genpd framework. + */ + ret = pm_runtime_resume_and_get(dev); + if (ret) { + dev_err_probe(dev, ret, "Failed to runtime resume device\n"); + goto put_of_node; + } + + ret = mtk_clk_register_gates(dev, node, mfg_clks, ARRAY_SIZE(mfg_clks), + data->clk_data); + if (ret) { + dev_err_probe(dev, ret, "Failed to register clock gates\n"); + goto put_pm_runtime; + } + + data->clk_26m = clk_hw_get_clk(data->clk_data->hws[CLK_MFG_26M], "26m"); + if (IS_ERR(data->clk_26m)) { + ret = dev_err_probe(dev, PTR_ERR(data->clk_26m), "Failed to get 26 MHz clock\n"); + goto unregister_clks; + } + + ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, data->clk_data); + if (ret) { + dev_err_probe(dev, ret, "Failed to add clk OF provider\n"); + goto put_26m_clk; + } + + data->genpd.name = "mfg-top"; + data->genpd.power_on = clk_mt8173_mfgtop_power_on; + data->genpd.power_off = clk_mt8173_mfgtop_power_off; + ret = pm_genpd_init(&data->genpd, NULL, true); + if (ret) { + dev_err_probe(dev, ret, "Failed to add power domain\n"); + goto del_clk_provider; + } + + ret = of_genpd_add_provider_simple(node, &data->genpd); + if (ret) { + dev_err_probe(dev, ret, "Failed to add power domain OF provider\n"); + goto remove_pd; + } + + ret = of_genpd_add_subdomain(&data->parent_pd, &data->child_pd); + if (ret) { + dev_err_probe(dev, ret, "Failed to link PM domains\n"); + goto del_pd_provider; + } + + pm_runtime_put(dev); + return 0; + +del_pd_provider: + of_genpd_del_provider(node); +remove_pd: + pm_genpd_remove(&data->genpd); +del_clk_provider: + of_clk_del_provider(node); +put_26m_clk: + clk_put(data->clk_26m); +unregister_clks: + mtk_clk_unregister_gates(mfg_clks, ARRAY_SIZE(mfg_clks), data->clk_data); +put_pm_runtime: + pm_runtime_put_sync(dev); +put_of_node: + of_node_put(data->parent_pd.np); + return ret; +} + +static void clk_mt8173_mfgtop_remove(struct platform_device *pdev) +{ + struct mt8173_mfgtop_data *data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + + of_genpd_remove_subdomain(&data->parent_pd, &data->child_pd); + of_genpd_del_provider(node); + pm_genpd_remove(&data->genpd); + of_clk_del_provider(node); + clk_put(data->clk_26m); + mtk_clk_unregister_gates(mfg_clks, ARRAY_SIZE(mfg_clks), data->clk_data); + of_node_put(data->parent_pd.np); +} + +static const struct of_device_id of_match_clk_mt8173_mfgtop[] = { + { .compatible = "mediatek,mt8173-mfgtop" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8173_mfgtop); + +static struct platform_driver clk_mt8173_mfgtop_drv = { + .probe = clk_mt8173_mfgtop_probe, + .remove = clk_mt8173_mfgtop_remove, + .driver = { + .name = "clk-mt8173-mfgtop", + .of_match_table = of_match_clk_mt8173_mfgtop, + }, +}; +module_platform_driver(clk_mt8173_mfgtop_drv); + +MODULE_DESCRIPTION("MediaTek MT8173 mfgtop clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-vlpckgen.c b/drivers/clk/mediatek/clk-mt8196-vlpckgen.c index 7dcc164627c5..ee88dc4a231a 100644 --- a/drivers/clk/mediatek/clk-mt8196-vlpckgen.c +++ b/drivers/clk/mediatek/clk-mt8196-vlpckgen.c @@ -629,7 +629,6 @@ static const struct regmap_config vlpckgen_regmap_config = { .val_bits = 32, .reg_stride = 4, .max_register = 0x1000, - .fast_io = true, }; static int clk_mt8196_vlp_probe(struct platform_device *pdev) diff --git a/drivers/clk/mediatek/clk-pllfh.c b/drivers/clk/mediatek/clk-pllfh.c index aa95cd9197b3..6249fb87b1f5 100644 --- a/drivers/clk/mediatek/clk-pllfh.c +++ b/drivers/clk/mediatek/clk-pllfh.c @@ -197,12 +197,56 @@ static void mtk_clk_unregister_pllfh(struct clk_hw *hw) kfree(fh); } +static void mtk_clk_cleanup_pllfhs(void __iomem *iomem_base, + const struct mtk_pll_data *plls, int num_plls, + void __iomem *iomem_fhctl_base, + struct mtk_pllfh_data *pllfhs, int num_fhs, + struct clk_hw_onecell_data *clk_data) +{ + void __iomem *base = iomem_base; + void __iomem *fhctl_base = iomem_fhctl_base; + int i; + + for (i = num_plls - 1; i >= 0; i--) { + const struct mtk_pll_data *pll = &plls[i]; + struct mtk_pllfh_data *pllfh; + bool use_fhctl; + + if (IS_ERR_OR_NULL(clk_data->hws[pll->id])) + continue; + + pllfh = get_pllfh_by_id(pllfhs, num_fhs, pll->id); + use_fhctl = fhctl_is_supported_and_enabled(pllfh); + + if (!base) + base = mtk_clk_pll_get_base(clk_data->hws[pll->id], + pll); + + if (use_fhctl) { + if (!fhctl_base) + fhctl_base = pllfh->state.base; + mtk_clk_unregister_pllfh(clk_data->hws[pll->id]); + } else { + mtk_clk_unregister_pll(clk_data->hws[pll->id]); + } + + clk_data->hws[pll->id] = ERR_PTR(-ENOENT); + } + + if (fhctl_base) + iounmap(fhctl_base); + + if (base) + iounmap(base); +} + + int mtk_clk_register_pllfhs(struct device *dev, const struct mtk_pll_data *plls, int num_plls, struct mtk_pllfh_data *pllfhs, int num_fhs, struct clk_hw_onecell_data *clk_data) { - void __iomem *base; + void __iomem *base, *fhctl_base = NULL; int i; struct clk_hw *hw; @@ -238,24 +282,8 @@ int mtk_clk_register_pllfhs(struct device *dev, return 0; err: - while (--i >= 0) { - const struct mtk_pll_data *pll = &plls[i]; - struct mtk_pllfh_data *pllfh; - bool use_fhctl; - - pllfh = get_pllfh_by_id(pllfhs, num_fhs, pll->id); - use_fhctl = fhctl_is_supported_and_enabled(pllfh); - - if (use_fhctl) - mtk_clk_unregister_pllfh(clk_data->hws[pll->id]); - else - mtk_clk_unregister_pll(clk_data->hws[pll->id]); - - clk_data->hws[pll->id] = ERR_PTR(-ENOENT); - } - - iounmap(base); - + mtk_clk_cleanup_pllfhs(base, plls, i, fhctl_base, pllfhs, num_fhs, + clk_data); return PTR_ERR(hw); } EXPORT_SYMBOL_GPL(mtk_clk_register_pllfhs); @@ -264,38 +292,10 @@ void mtk_clk_unregister_pllfhs(const struct mtk_pll_data *plls, int num_plls, struct mtk_pllfh_data *pllfhs, int num_fhs, struct clk_hw_onecell_data *clk_data) { - void __iomem *base = NULL, *fhctl_base = NULL; - int i; - if (!clk_data) return; - for (i = num_plls; i > 0; i--) { - const struct mtk_pll_data *pll = &plls[i - 1]; - struct mtk_pllfh_data *pllfh; - bool use_fhctl; - - if (IS_ERR_OR_NULL(clk_data->hws[pll->id])) - continue; - - pllfh = get_pllfh_by_id(pllfhs, num_fhs, pll->id); - use_fhctl = fhctl_is_supported_and_enabled(pllfh); - - if (use_fhctl) { - fhctl_base = pllfh->state.base; - mtk_clk_unregister_pllfh(clk_data->hws[pll->id]); - } else { - base = mtk_clk_pll_get_base(clk_data->hws[pll->id], - pll); - mtk_clk_unregister_pll(clk_data->hws[pll->id]); - } - - clk_data->hws[pll->id] = ERR_PTR(-ENOENT); - } - - if (fhctl_base) - iounmap(fhctl_base); - - iounmap(base); + mtk_clk_cleanup_pllfhs(NULL, plls, num_plls, NULL, pllfhs, + num_fhs, clk_data); } EXPORT_SYMBOL_GPL(mtk_clk_unregister_pllfhs); diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index cf8cf3f9e4ee..d460514bb8a1 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -132,6 +132,33 @@ config COMMON_CLK_A1_PERIPHERALS device, A1 SoC Family. Say Y if you want A1 Peripherals clock controller to work. +config COMMON_CLK_A9_PERIPHERALS + tristate "Amlogic A9 SoC peripherals clock controller support" + depends on ARM64 || COMPILE_TEST + default ARCH_MESON + select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_CLKC_UTILS + select COMMON_CLK_MESON_DUALDIV + select COMMON_CLK_MESON_VID_PLL_DIV + imply COMMON_CLK_SCMI + help + Support for the peripherals clock controller on Amlogic A311Y3 based + device, AKA A9. Peripherals are required by most peripheral to operate. + Say Y if you want A9 peripherals clock controller to work. + +config COMMON_CLK_A9_AO + tristate "Amlogic A9 SoC AO clock controller support" + depends on ARM64 || COMPILE_TEST + default ARCH_MESON + select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_CLKC_UTILS + select COMMON_CLK_MESON_DUALDIV + imply COMMON_CLK_SCMI + help + Support for the AO clock controller on Amlogic A311Y3 based + device, AKA A9. + Say Y if you want A9 AO clock controller to work. + config COMMON_CLK_C3_PLL tristate "Amlogic C3 PLL clock controller" depends on ARM64 diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index c6719694a242..56b04254eb1a 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -19,6 +19,8 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o +obj-$(CONFIG_COMMON_CLK_A9_PERIPHERALS) += a9-peripherals.o +obj-$(CONFIG_COMMON_CLK_A9_AO) += a9-aoclk.o obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o diff --git a/drivers/clk/meson/a9-aoclk.c b/drivers/clk/meson/a9-aoclk.c new file mode 100644 index 000000000000..c82d4b1b5b44 --- /dev/null +++ b/drivers/clk/meson/a9-aoclk.c @@ -0,0 +1,489 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Copyright (C) 2026 Amlogic, Inc. All rights reserved + */ + +#include +#include +#include +#include +#include "clk-regmap.h" +#include "clk-dualdiv.h" +#include "meson-clkc-utils.h" + +#define AO_OSCIN_CTRL 0x00 +#define AO_SYS_CLK0 0x04 +#define AO_PWM_CLK_A_CTRL 0x1c +#define AO_PWM_CLK_B_CTRL 0x20 +#define AO_PWM_CLK_C_CTRL 0x24 +#define AO_PWM_CLK_D_CTRL 0x28 +#define AO_PWM_CLK_E_CTRL 0x2c +#define AO_PWM_CLK_F_CTRL 0x30 +#define AO_PWM_CLK_G_CTRL 0x34 +#define AO_CEC_CTRL0 0x38 +#define AO_CEC_CTRL1 0x3c +#define AO_RTC_BY_OSCIN_CTRL0 0x50 +#define AO_RTC_BY_OSCIN_CTRL1 0x54 + +#define A9_COMP_SEL(_name, _reg, _shift, _mask, _pdata) \ + MESON_COMP_SEL(a9_ao_, _name, _reg, _shift, _mask, _pdata, NULL, 0, 0) + +#define A9_COMP_DIV(_name, _reg, _shift, _width) \ + MESON_COMP_DIV(a9_ao_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT) + +#define A9_COMP_GATE(_name, _reg, _bit) \ + MESON_COMP_GATE(a9_ao_, _name, _reg, _bit, CLK_SET_RATE_PARENT) + +static struct clk_regmap a9_ao_xtal_in = { + .data = &(struct clk_regmap_gate_data){ + .offset = AO_OSCIN_CTRL, + .bit_idx = 3, + }, + .hw.init = &(struct clk_init_data) { + .name = "ao_xtal_in", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a9_ao_xtal = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_OSCIN_CTRL, + .mask = 0x1, + .shift = 0, + }, + .hw.init = &(struct clk_init_data){ + .name = "ao_xtal", + .ops = &clk_regmap_mux_ops, + /* ext_32k is from external PAD, do not automatically reparent */ + .parent_data = (const struct clk_parent_data []) { + { .hw = &a9_ao_xtal_in.hw }, + { .fw_name = "ext_32k", }, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap a9_ao_sys = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_OSCIN_CTRL, + .mask = 0x1, + .shift = 1, + }, + .hw.init = &(struct clk_init_data){ + .name = "ao_sys", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &a9_ao_xtal.hw }, + { .fw_name = "sys", }, + }, + .num_parents = 2, + }, +}; + +static const struct clk_parent_data a9_ao_pclk_parents = { .hw = &a9_ao_sys.hw }; + +#define A9_AO_PCLK(_name, _bit, _flags) \ + MESON_PCLK(a9_ao_sys_##_name, AO_SYS_CLK0, _bit, \ + &a9_ao_pclk_parents, _flags) + +/* + * A9 integrates a low-power microprocessor (Always-on CPU: AOCPU). Some AO sys + * clocks control the AOCPU modules. Mark the AOCPU-related clocks with + * CLK_IS_CRITICAL to avoid them being disabled and impacting AOCPU functionality. + * AOCPU-related clocks list: + * - clktree + * - rst_ctrl + * - pad + * - irq + * - pwrctrl + * - aocpu + * - sram + */ +static A9_AO_PCLK(i3c, 0, 0); +static A9_AO_PCLK(rtc_reg, 1, 0); +static A9_AO_PCLK(clktree, 2, CLK_IS_CRITICAL); +static A9_AO_PCLK(rst_ctrl, 3, CLK_IS_CRITICAL); +static A9_AO_PCLK(pad, 4, CLK_IS_CRITICAL); +static A9_AO_PCLK(rtc_dig, 5, 0); +static A9_AO_PCLK(irq, 6, CLK_IS_CRITICAL); +static A9_AO_PCLK(pwrctrl, 7, CLK_IS_CRITICAL); +static A9_AO_PCLK(pwm_a, 8, 0); +static A9_AO_PCLK(pwm_b, 9, 0); +static A9_AO_PCLK(pwm_c, 10, 0); +static A9_AO_PCLK(pwm_d, 11, 0); +static A9_AO_PCLK(pwm_e, 12, 0); +static A9_AO_PCLK(pwm_f, 13, 0); +static A9_AO_PCLK(pwm_g, 14, 0); +static A9_AO_PCLK(i2c_a, 15, 0); +static A9_AO_PCLK(i2c_b, 16, 0); +static A9_AO_PCLK(i2c_c, 17, 0); +static A9_AO_PCLK(i2c_d, 18, 0); +static A9_AO_PCLK(sed, 19, 0); +static A9_AO_PCLK(ir_ctrl, 20, 0); +static A9_AO_PCLK(uart_b, 21, 0); +static A9_AO_PCLK(uart_c, 22, 0); +static A9_AO_PCLK(uart_d, 23, 0); +static A9_AO_PCLK(uart_e, 24, 0); +static A9_AO_PCLK(spisg_0, 25, 0); +static A9_AO_PCLK(rtc_secure, 26, 0); +static A9_AO_PCLK(cec, 27, 0); +static A9_AO_PCLK(aocpu, 28, CLK_IS_CRITICAL); +static A9_AO_PCLK(sram, 29, CLK_IS_CRITICAL); +static A9_AO_PCLK(spisg_1, 30, 0); +static A9_AO_PCLK(spisg_2, 31, 0); + +static const struct clk_parent_data a9_ao_pwm_parents[] = { + { .hw = &a9_ao_xtal.hw }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", } +}; + +static A9_COMP_SEL(pwm_a, AO_PWM_CLK_A_CTRL, 9, 0x7, a9_ao_pwm_parents); +static A9_COMP_DIV(pwm_a, AO_PWM_CLK_A_CTRL, 0, 8); +static A9_COMP_GATE(pwm_a, AO_PWM_CLK_A_CTRL, 8); + +static A9_COMP_SEL(pwm_b, AO_PWM_CLK_B_CTRL, 9, 0x7, a9_ao_pwm_parents); +static A9_COMP_DIV(pwm_b, AO_PWM_CLK_B_CTRL, 0, 8); +static A9_COMP_GATE(pwm_b, AO_PWM_CLK_B_CTRL, 8); + +static A9_COMP_SEL(pwm_c, AO_PWM_CLK_C_CTRL, 9, 0x7, a9_ao_pwm_parents); +static A9_COMP_DIV(pwm_c, AO_PWM_CLK_C_CTRL, 0, 8); +static A9_COMP_GATE(pwm_c, AO_PWM_CLK_C_CTRL, 8); + +static A9_COMP_SEL(pwm_d, AO_PWM_CLK_D_CTRL, 9, 0x7, a9_ao_pwm_parents); +static A9_COMP_DIV(pwm_d, AO_PWM_CLK_D_CTRL, 0, 8); +static A9_COMP_GATE(pwm_d, AO_PWM_CLK_D_CTRL, 8); + +static A9_COMP_SEL(pwm_e, AO_PWM_CLK_E_CTRL, 9, 0x7, a9_ao_pwm_parents); +static A9_COMP_DIV(pwm_e, AO_PWM_CLK_E_CTRL, 0, 8); +static A9_COMP_GATE(pwm_e, AO_PWM_CLK_E_CTRL, 8); + +static A9_COMP_SEL(pwm_f, AO_PWM_CLK_F_CTRL, 9, 0x7, a9_ao_pwm_parents); +static A9_COMP_DIV(pwm_f, AO_PWM_CLK_F_CTRL, 0, 8); +static A9_COMP_GATE(pwm_f, AO_PWM_CLK_F_CTRL, 8); + +static A9_COMP_SEL(pwm_g, AO_PWM_CLK_G_CTRL, 9, 0x7, a9_ao_pwm_parents); +static A9_COMP_DIV(pwm_g, AO_PWM_CLK_G_CTRL, 0, 8); +static A9_COMP_GATE(pwm_g, AO_PWM_CLK_G_CTRL, 8); + +static struct clk_regmap a9_ao_rtc_dualdiv_in = { + .data = &(struct clk_regmap_gate_data){ + .offset = AO_RTC_BY_OSCIN_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "ao_rtc_dualdiv_in", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_ao_xtal.hw + }, + .num_parents = 1, + }, +}; + +static const struct meson_clk_dualdiv_param a9_ao_dualdiv_table[] = { + { 733, 732, 8, 11, 1 }, + { /* sentinel */ } +}; + +static struct clk_regmap a9_ao_rtc_dualdiv_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = AO_RTC_BY_OSCIN_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = AO_RTC_BY_OSCIN_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = AO_RTC_BY_OSCIN_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = AO_RTC_BY_OSCIN_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = AO_RTC_BY_OSCIN_CTRL0, + .shift = 28, + .width = 1, + }, + .table = a9_ao_dualdiv_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "a9_ao_rtc_dualdiv_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_ao_rtc_dualdiv_in.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a9_ao_rtc_dualdiv_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_RTC_BY_OSCIN_CTRL1, + .mask = 0x1, + .shift = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "ao_rtc_dualdiv_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_ao_rtc_dualdiv_div.hw, + &a9_ao_rtc_dualdiv_in.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_ao_rtc_dualdiv = { + .data = &(struct clk_regmap_gate_data){ + .offset = AO_RTC_BY_OSCIN_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "ao_rtc_dualdiv", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_ao_rtc_dualdiv_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_ao_rtc = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_RTC_BY_OSCIN_CTRL1, + .mask = 0x1, + .shift = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "ao_rtc", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_ao_xtal.hw, + &a9_ao_rtc_dualdiv.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_ao_cec_dualdiv_in = { + .data = &(struct clk_regmap_gate_data){ + .offset = AO_CEC_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "ao_cec_dualdiv_in", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_ao_xtal.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a9_ao_cec_dualdiv_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = AO_CEC_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = AO_CEC_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = AO_CEC_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = AO_CEC_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = AO_CEC_CTRL0, + .shift = 28, + .width = 1, + }, + .table = a9_ao_dualdiv_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "ao_cec_dualdiv_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_ao_cec_dualdiv_in.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a9_ao_cec_dualdiv_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_CEC_CTRL1, + .mask = 0x1, + .shift = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "ao_cec_dualdiv_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_ao_cec_dualdiv_div.hw, + &a9_ao_cec_dualdiv_in.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_ao_cec_dualdiv = { + .data = &(struct clk_regmap_gate_data){ + .offset = AO_CEC_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "ao_cec_dualdiv", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_ao_cec_dualdiv_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_ao_cec = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_CEC_CTRL1, + .mask = 0x1, + .shift = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "ao_cec", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_ao_cec_dualdiv.hw, + &a9_ao_rtc.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_hw *a9_ao_hw_clks[] = { + [CLKID_AO_XTAL_IN] = &a9_ao_xtal_in.hw, + [CLKID_AO_XTAL] = &a9_ao_xtal.hw, + [CLKID_AO_SYS] = &a9_ao_sys.hw, + [CLKID_AO_SYS_I3C] = &a9_ao_sys_i3c.hw, + [CLKID_AO_SYS_RTC_REG] = &a9_ao_sys_rtc_reg.hw, + [CLKID_AO_SYS_CLKTREE] = &a9_ao_sys_clktree.hw, + [CLKID_AO_SYS_RST_CTRL] = &a9_ao_sys_rst_ctrl.hw, + [CLKID_AO_SYS_PAD] = &a9_ao_sys_pad.hw, + [CLKID_AO_SYS_RTC_DIG] = &a9_ao_sys_rtc_dig.hw, + [CLKID_AO_SYS_IRQ] = &a9_ao_sys_irq.hw, + [CLKID_AO_SYS_PWRCTRL] = &a9_ao_sys_pwrctrl.hw, + [CLKID_AO_SYS_PWM_A] = &a9_ao_sys_pwm_a.hw, + [CLKID_AO_SYS_PWM_B] = &a9_ao_sys_pwm_b.hw, + [CLKID_AO_SYS_PWM_C] = &a9_ao_sys_pwm_c.hw, + [CLKID_AO_SYS_PWM_D] = &a9_ao_sys_pwm_d.hw, + [CLKID_AO_SYS_PWM_E] = &a9_ao_sys_pwm_e.hw, + [CLKID_AO_SYS_PWM_F] = &a9_ao_sys_pwm_f.hw, + [CLKID_AO_SYS_PWM_G] = &a9_ao_sys_pwm_g.hw, + [CLKID_AO_SYS_I2C_A] = &a9_ao_sys_i2c_a.hw, + [CLKID_AO_SYS_I2C_B] = &a9_ao_sys_i2c_b.hw, + [CLKID_AO_SYS_I2C_C] = &a9_ao_sys_i2c_c.hw, + [CLKID_AO_SYS_I2C_D] = &a9_ao_sys_i2c_d.hw, + [CLKID_AO_SYS_SED] = &a9_ao_sys_sed.hw, + [CLKID_AO_SYS_IR_CTRL] = &a9_ao_sys_ir_ctrl.hw, + [CLKID_AO_SYS_UART_B] = &a9_ao_sys_uart_b.hw, + [CLKID_AO_SYS_UART_C] = &a9_ao_sys_uart_c.hw, + [CLKID_AO_SYS_UART_D] = &a9_ao_sys_uart_d.hw, + [CLKID_AO_SYS_UART_E] = &a9_ao_sys_uart_e.hw, + [CLKID_AO_SYS_SPISG_0] = &a9_ao_sys_spisg_0.hw, + [CLKID_AO_SYS_RTC_SECURE] = &a9_ao_sys_rtc_secure.hw, + [CLKID_AO_SYS_CEC] = &a9_ao_sys_cec.hw, + [CLKID_AO_SYS_AOCPU] = &a9_ao_sys_aocpu.hw, + [CLKID_AO_SYS_SRAM] = &a9_ao_sys_sram.hw, + [CLKID_AO_SYS_SPISG_1] = &a9_ao_sys_spisg_1.hw, + [CLKID_AO_SYS_SPISG_2] = &a9_ao_sys_spisg_2.hw, + [CLKID_AO_PWM_A_SEL] = &a9_ao_pwm_a_sel.hw, + [CLKID_AO_PWM_A_DIV] = &a9_ao_pwm_a_div.hw, + [CLKID_AO_PWM_A] = &a9_ao_pwm_a.hw, + [CLKID_AO_PWM_B_SEL] = &a9_ao_pwm_b_sel.hw, + [CLKID_AO_PWM_B_DIV] = &a9_ao_pwm_b_div.hw, + [CLKID_AO_PWM_B] = &a9_ao_pwm_b.hw, + [CLKID_AO_PWM_C_SEL] = &a9_ao_pwm_c_sel.hw, + [CLKID_AO_PWM_C_DIV] = &a9_ao_pwm_c_div.hw, + [CLKID_AO_PWM_C] = &a9_ao_pwm_c.hw, + [CLKID_AO_PWM_D_SEL] = &a9_ao_pwm_d_sel.hw, + [CLKID_AO_PWM_D_DIV] = &a9_ao_pwm_d_div.hw, + [CLKID_AO_PWM_D] = &a9_ao_pwm_d.hw, + [CLKID_AO_PWM_E_SEL] = &a9_ao_pwm_e_sel.hw, + [CLKID_AO_PWM_E_DIV] = &a9_ao_pwm_e_div.hw, + [CLKID_AO_PWM_E] = &a9_ao_pwm_e.hw, + [CLKID_AO_PWM_F_SEL] = &a9_ao_pwm_f_sel.hw, + [CLKID_AO_PWM_F_DIV] = &a9_ao_pwm_f_div.hw, + [CLKID_AO_PWM_F] = &a9_ao_pwm_f.hw, + [CLKID_AO_PWM_G_SEL] = &a9_ao_pwm_g_sel.hw, + [CLKID_AO_PWM_G_DIV] = &a9_ao_pwm_g_div.hw, + [CLKID_AO_PWM_G] = &a9_ao_pwm_g.hw, + [CLKID_AO_RTC_DUALDIV_IN] = &a9_ao_rtc_dualdiv_in.hw, + [CLKID_AO_RTC_DUALDIV_DIV] = &a9_ao_rtc_dualdiv_div.hw, + [CLKID_AO_RTC_DUALDIV_SEL] = &a9_ao_rtc_dualdiv_sel.hw, + [CLKID_AO_RTC_DUALDIV] = &a9_ao_rtc_dualdiv.hw, + [CLKID_AO_RTC] = &a9_ao_rtc.hw, + [CLKID_AO_CEC_DUALDIV_IN] = &a9_ao_cec_dualdiv_in.hw, + [CLKID_AO_CEC_DUALDIV_DIV] = &a9_ao_cec_dualdiv_div.hw, + [CLKID_AO_CEC_DUALDIV_SEL] = &a9_ao_cec_dualdiv_sel.hw, + [CLKID_AO_CEC_DUALDIV] = &a9_ao_cec_dualdiv.hw, + [CLKID_AO_CEC] = &a9_ao_cec.hw, +}; + +static const struct meson_clkc_data a9_ao_clkc_data = { + .hw_clks = { + .hws = a9_ao_hw_clks, + .num = ARRAY_SIZE(a9_ao_hw_clks), + }, +}; + +static const struct of_device_id a9_ao_clkc_match_table[] = { + { + .compatible = "amlogic,a9-aoclkc", + .data = &a9_ao_clkc_data, + }, + { } +}; +MODULE_DEVICE_TABLE(of, a9_ao_clkc_match_table); + +static struct platform_driver a9_ao_clkc_driver = { + .probe = meson_clkc_mmio_probe, + .driver = { + .name = "a9-aoclkc", + .of_match_table = a9_ao_clkc_match_table, + }, +}; +module_platform_driver(a9_ao_clkc_driver); + +MODULE_DESCRIPTION("Amlogic A9 Always-ON Clock Controller driver"); +MODULE_AUTHOR("Jian Hu "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/a9-peripherals.c b/drivers/clk/meson/a9-peripherals.c new file mode 100644 index 000000000000..b77e35f48c1f --- /dev/null +++ b/drivers/clk/meson/a9-peripherals.c @@ -0,0 +1,2089 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Copyright (C) 2026 Amlogic, Inc. All rights reserved + */ + +#include +#include +#include +#include +#include "clk-regmap.h" +#include "clk-dualdiv.h" +#include "meson-clkc-utils.h" +#include "vid-pll-div.h" + +#define SYS_CLK_EN0_REG0 0x30 +#define SYS_CLK_EN0_REG1 0x34 +#define SYS_CLK_EN0_REG2 0x38 +#define SYS_CLK_EN0_REG3 0x3c +#define SD_EMMC_CLK_CTRL0 0x90 +#define SD_EMMC_CLK_CTRL1 0x94 +#define PWM_CLK_H_CTRL 0xbc +#define PWM_CLK_I_CTRL 0xc0 +#define PWM_CLK_J_CTRL 0xc4 +#define PWM_CLK_K_CTRL 0xc8 +#define PWM_CLK_L_CTRL 0xcc +#define PWM_CLK_M_CTRL 0xd0 +#define PWM_CLK_N_CTRL 0xd4 +#define SPISG_CLK_CTRL 0x100 +#define SPISG_CLK_CTRL1 0x104 +#define SAR_CLK_CTRL 0x150 +#define AMFC_CLK_CTRL 0x154 +#define NNA_CLK_CTRL 0x15c +#define USB_CLK_CTRL 0x160 +#define PCIE_TL_CLK_CTRL 0x164 +#define CMPR_CLK_CTRL 0x168 +#define DEWARP_CLK_CTRL 0x16c +#define SC_CLK_CTRL 0x170 +#define DPTX_CLK_CTRL 0x178 +#define ISP_CLK_CTRL 0x17c +#define CVE_CLK_CTRL 0x180 +#define PP_CLK_CTRL 0x184 +#define GLB_CLK_CTRL 0x188 +#define USB_CLK_CTRL0 0x18c +#define USB_CLK_CTRL1 0x190 +#define CAN_CLK_CTRL 0x194 +#define CAN_CLK_CTRL1 0x198 +#define I3C_CLK_CTRL 0x19c +#define TS_CLK_CTRL 0x1a0 +#define ETH_CLK_CTRL 0x1a4 +#define GEN_CLK_CTRL 0x1a8 +#define CLK12_24_CTRL 0x1ac +#define MALI_CLK_CTRL 0x200 +#define MALI_STACK_CLK_CTRL 0x204 +#define DSPA_CLK_CTRL 0x220 +#define HEVCF_CLK_CTRL 0x240 +#define HCODEC_CLK_CTRL 0x244 +#define VPU_CLK_CTRL 0x260 +#define VAPB_CLK_CTRL 0x268 +#define VPU_CLKB_CTRL 0x280 +#define HDMI_CLK_CTRL 0x284 +#define HTX_CLK_CTRL 0x28c +#define HTX_CLK_CTRL1 0x290 +#define HRX_CLK_CTRL 0x294 +#define HRX_CLK_CTRL1 0x298 +#define HRX_CLK_CTRL2 0x29c +#define HRX_CLK_CTRL3 0x2a0 +#define VID_LOCK_CLK_CTRL 0x2a4 +#define VDIN_MEAS_CLK_CTRL 0x2a8 +#define VID_PLL_CLK_DIV 0x2b0 +#define VID_CLK_CTRL 0x2c0 +#define VID_CLK_CTRL2 0x2c4 +#define VID_CLK_DIV 0x2c8 +#define VIID_CLK_DIV 0x2cc +#define VIID_CLK_CTRL 0x2d0 +#define MIPI_CSI_PHY_CLK_CTRL 0x2e0 +#define DSI_MEAS_CLK_CTRL 0x2f4 + +#define A9_COMP_SEL(_name, _reg, _shift, _mask, _pdata, _table) \ + MESON_COMP_SEL(a9_, _name, _reg, _shift, _mask, _pdata, _table, 0, 0) + +#define A9_COMP_DIV(_name, _reg, _shift, _width) \ + MESON_COMP_DIV(a9_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT) + +#define A9_COMP_GATE(_name, _reg, _bit, _iflags) \ + MESON_COMP_GATE(a9_, _name, _reg, _bit, CLK_SET_RATE_PARENT | (_iflags)) + +static const struct clk_parent_data a9_sys_pclk_parents = { .fw_name = "sys" }; + +#define A9_SYS_PCLK(_name, _reg, _bit) \ + MESON_PCLK(a9_##_name, _reg, _bit, &a9_sys_pclk_parents, 0) + +static A9_SYS_PCLK(sys_am_axi, SYS_CLK_EN0_REG0, 0); +static A9_SYS_PCLK(sys_dos, SYS_CLK_EN0_REG0, 1); +static A9_SYS_PCLK(sys_mipi_dsi0, SYS_CLK_EN0_REG0, 3); +static A9_SYS_PCLK(sys_eth_phy, SYS_CLK_EN0_REG0, 4); +static A9_SYS_PCLK(sys_amfc, SYS_CLK_EN0_REG0, 5); +static A9_SYS_PCLK(sys_mali, SYS_CLK_EN0_REG0, 6); +static A9_SYS_PCLK(sys_nna, SYS_CLK_EN0_REG0, 7); +static A9_SYS_PCLK(sys_eth_axi, SYS_CLK_EN0_REG0, 8); +static A9_SYS_PCLK(sys_dp_apb, SYS_CLK_EN0_REG0, 9); +static A9_SYS_PCLK(sys_edptx_apb, SYS_CLK_EN0_REG0, 10); +static A9_SYS_PCLK(sys_u3hsg, SYS_CLK_EN0_REG0, 11); +static A9_SYS_PCLK(sys_aucpu, SYS_CLK_EN0_REG0, 14); +static A9_SYS_PCLK(sys_glb, SYS_CLK_EN0_REG0, 15); +static A9_SYS_PCLK(sys_combo_dphy_apb, SYS_CLK_EN0_REG0, 17); +static A9_SYS_PCLK(sys_hdmirx_apb, SYS_CLK_EN0_REG0, 18); +static A9_SYS_PCLK(sys_hdmirx_pclk, SYS_CLK_EN0_REG0, 19); +static A9_SYS_PCLK(sys_mipi_dsi0_phy, SYS_CLK_EN0_REG0, 20); +static A9_SYS_PCLK(sys_can0, SYS_CLK_EN0_REG0, 21); +static A9_SYS_PCLK(sys_can1, SYS_CLK_EN0_REG0, 22); +static A9_SYS_PCLK(sys_sd_emmc_a, SYS_CLK_EN0_REG0, 24); +static A9_SYS_PCLK(sys_sd_emmc_b, SYS_CLK_EN0_REG0, 25); +static A9_SYS_PCLK(sys_sd_emmc_c, SYS_CLK_EN0_REG0, 26); +static A9_SYS_PCLK(sys_sc, SYS_CLK_EN0_REG0, 27); +static A9_SYS_PCLK(sys_acodec, SYS_CLK_EN0_REG0, 28); +static A9_SYS_PCLK(sys_mipi_isp, SYS_CLK_EN0_REG0, 29); +static A9_SYS_PCLK(sys_msr, SYS_CLK_EN0_REG0, 30); +static A9_SYS_PCLK(sys_audio, SYS_CLK_EN0_REG1, 0); +static A9_SYS_PCLK(sys_mipi_dsi1, SYS_CLK_EN0_REG1, 1); +static A9_SYS_PCLK(sys_mipi_dsi1_phy, SYS_CLK_EN0_REG1, 2); +static A9_SYS_PCLK(sys_eth, SYS_CLK_EN0_REG1, 3); +static A9_SYS_PCLK(sys_eth_1g_mac, SYS_CLK_EN0_REG1, 4); +static A9_SYS_PCLK(sys_uart_a, SYS_CLK_EN0_REG1, 5); +static A9_SYS_PCLK(sys_uart_f, SYS_CLK_EN0_REG1, 10); +static A9_SYS_PCLK(sys_ts_a55, SYS_CLK_EN0_REG1, 11); +static A9_SYS_PCLK(sys_eth_1g_axi, SYS_CLK_EN0_REG1, 12); +static A9_SYS_PCLK(sys_ts_dos, SYS_CLK_EN0_REG1, 13); +static A9_SYS_PCLK(sys_u3drd_b, SYS_CLK_EN0_REG1, 14); +static A9_SYS_PCLK(sys_ts_core, SYS_CLK_EN0_REG1, 15); +static A9_SYS_PCLK(sys_ts_pll, SYS_CLK_EN0_REG1, 16); +static A9_SYS_PCLK(sys_csi_dig_clkin, SYS_CLK_EN0_REG1, 18); +static A9_SYS_PCLK(sys_cve, SYS_CLK_EN0_REG1, 19); +static A9_SYS_PCLK(sys_ge2d, SYS_CLK_EN0_REG1, 20); +static A9_SYS_PCLK(sys_spisg, SYS_CLK_EN0_REG1, 21); +static A9_SYS_PCLK(sys_u2h, SYS_CLK_EN0_REG1, 23); +static A9_SYS_PCLK(sys_pcie_mac_a, SYS_CLK_EN0_REG1, 24); +static A9_SYS_PCLK(sys_u3drd_a, SYS_CLK_EN0_REG1, 25); +static A9_SYS_PCLK(sys_u2drd, SYS_CLK_EN0_REG1, 26); +static A9_SYS_PCLK(sys_pcie_phy, SYS_CLK_EN0_REG1, 27); +static A9_SYS_PCLK(sys_pcie_mac_b, SYS_CLK_EN0_REG1, 28); +static A9_SYS_PCLK(sys_periph, SYS_CLK_EN0_REG1, 29); +static A9_SYS_PCLK(sys_pio, SYS_CLK_EN0_REG2, 0); +static A9_SYS_PCLK(sys_i3c, SYS_CLK_EN0_REG2, 1); +static A9_SYS_PCLK(sys_i2c_m_e, SYS_CLK_EN0_REG2, 2); +static A9_SYS_PCLK(sys_i2c_m_f, SYS_CLK_EN0_REG2, 3); +static A9_SYS_PCLK(sys_hdmitx_apb, SYS_CLK_EN0_REG2, 4); +static A9_SYS_PCLK(sys_i2c_m_i, SYS_CLK_EN0_REG2, 5); +static A9_SYS_PCLK(sys_i2c_m_g, SYS_CLK_EN0_REG2, 6); +static A9_SYS_PCLK(sys_i2c_m_h, SYS_CLK_EN0_REG2, 7); +static A9_SYS_PCLK(sys_hdmi20_aes, SYS_CLK_EN0_REG2, 9); +static A9_SYS_PCLK(sys_csi2_host, SYS_CLK_EN0_REG2, 16); +static A9_SYS_PCLK(sys_csi2_adapt, SYS_CLK_EN0_REG2, 17); +static A9_SYS_PCLK(sys_dspa, SYS_CLK_EN0_REG2, 21); +static A9_SYS_PCLK(sys_pp_dma, SYS_CLK_EN0_REG2, 22); +static A9_SYS_PCLK(sys_pp_wrapper, SYS_CLK_EN0_REG2, 23); +static A9_SYS_PCLK(sys_vpu_intr, SYS_CLK_EN0_REG2, 25); +static A9_SYS_PCLK(sys_csi2_phy, SYS_CLK_EN0_REG2, 27); +static A9_SYS_PCLK(sys_saradc, SYS_CLK_EN0_REG2, 28); +static A9_SYS_PCLK(sys_pwm_j, SYS_CLK_EN0_REG2, 30); +static A9_SYS_PCLK(sys_pwm_i, SYS_CLK_EN0_REG2, 31); +static A9_SYS_PCLK(sys_pwm_h, SYS_CLK_EN0_REG3, 0); +static A9_SYS_PCLK(sys_pwm_n, SYS_CLK_EN0_REG3, 8); +static A9_SYS_PCLK(sys_pwm_m, SYS_CLK_EN0_REG3, 9); +static A9_SYS_PCLK(sys_pwm_l, SYS_CLK_EN0_REG3, 10); +static A9_SYS_PCLK(sys_pwm_k, SYS_CLK_EN0_REG3, 11); + +/* Channel 5 is unconnected. */ +static u32 a9_sd_emmc_parents_val_table[] = { 0, 1, 2, 3, 4, 6, 7 }; +static const struct clk_parent_data a9_sd_emmc_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv3", }, + { .fw_name = "hifi0", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "gp1", }, + { .fw_name = "gp0", } +}; + +static A9_COMP_SEL(sd_emmc_a, SD_EMMC_CLK_CTRL0, 9, 0x7, a9_sd_emmc_parents, + a9_sd_emmc_parents_val_table); +static A9_COMP_DIV(sd_emmc_a, SD_EMMC_CLK_CTRL0, 0, 7); +static A9_COMP_GATE(sd_emmc_a, SD_EMMC_CLK_CTRL0, 8, 0); + +static A9_COMP_SEL(sd_emmc_b, SD_EMMC_CLK_CTRL0, 25, 0x7, a9_sd_emmc_parents, + a9_sd_emmc_parents_val_table); +static A9_COMP_DIV(sd_emmc_b, SD_EMMC_CLK_CTRL0, 16, 7); +static A9_COMP_GATE(sd_emmc_b, SD_EMMC_CLK_CTRL0, 24, 0); + +static A9_COMP_SEL(sd_emmc_c, SD_EMMC_CLK_CTRL1, 9, 0x7, a9_sd_emmc_parents, + a9_sd_emmc_parents_val_table); +static A9_COMP_DIV(sd_emmc_c, SD_EMMC_CLK_CTRL1, 0, 7); +static A9_COMP_GATE(sd_emmc_c, SD_EMMC_CLK_CTRL1, 8, 0); + +static const struct clk_parent_data a9_pwm_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", } +}; + +static A9_COMP_SEL(pwm_h, PWM_CLK_H_CTRL, 9, 0x7, a9_pwm_parents, NULL); +static A9_COMP_DIV(pwm_h, PWM_CLK_H_CTRL, 0, 8); +static A9_COMP_GATE(pwm_h, PWM_CLK_H_CTRL, 8, 0); + +static A9_COMP_SEL(pwm_i, PWM_CLK_I_CTRL, 9, 0x7, a9_pwm_parents, NULL); +static A9_COMP_DIV(pwm_i, PWM_CLK_I_CTRL, 0, 8); +static A9_COMP_GATE(pwm_i, PWM_CLK_I_CTRL, 8, 0); + +static A9_COMP_SEL(pwm_j, PWM_CLK_J_CTRL, 9, 0x7, a9_pwm_parents, NULL); +static A9_COMP_DIV(pwm_j, PWM_CLK_J_CTRL, 0, 8); +static A9_COMP_GATE(pwm_j, PWM_CLK_J_CTRL, 8, 0); + +static A9_COMP_SEL(pwm_k, PWM_CLK_K_CTRL, 9, 0x7, a9_pwm_parents, NULL); +static A9_COMP_DIV(pwm_k, PWM_CLK_K_CTRL, 0, 8); +static A9_COMP_GATE(pwm_k, PWM_CLK_K_CTRL, 8, 0); + +static A9_COMP_SEL(pwm_l, PWM_CLK_L_CTRL, 9, 0x7, a9_pwm_parents, NULL); +static A9_COMP_DIV(pwm_l, PWM_CLK_L_CTRL, 0, 8); +static A9_COMP_GATE(pwm_l, PWM_CLK_L_CTRL, 8, 0); + +static A9_COMP_SEL(pwm_m, PWM_CLK_M_CTRL, 9, 0x7, a9_pwm_parents, NULL); +static A9_COMP_DIV(pwm_m, PWM_CLK_M_CTRL, 0, 8); +static A9_COMP_GATE(pwm_m, PWM_CLK_M_CTRL, 8, 0); + +static A9_COMP_SEL(pwm_n, PWM_CLK_N_CTRL, 9, 0x7, a9_pwm_parents, NULL); +static A9_COMP_DIV(pwm_n, PWM_CLK_N_CTRL, 0, 8); +static A9_COMP_GATE(pwm_n, PWM_CLK_N_CTRL, 8, 0); + +static const struct clk_parent_data a9_spisg_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "sys", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, + { .fw_name = "gp0", } +}; + +static A9_COMP_SEL(spisg0, SPISG_CLK_CTRL, 9, 0x7, a9_spisg_parents, NULL); +static A9_COMP_DIV(spisg0, SPISG_CLK_CTRL, 0, 6); +static A9_COMP_GATE(spisg0, SPISG_CLK_CTRL, 8, 0); + +static A9_COMP_SEL(spisg1, SPISG_CLK_CTRL, 25, 0x7, a9_spisg_parents, NULL); +static A9_COMP_DIV(spisg1, SPISG_CLK_CTRL, 16, 6); +static A9_COMP_GATE(spisg1, SPISG_CLK_CTRL, 24, 0); + +static A9_COMP_SEL(spisg2, SPISG_CLK_CTRL1, 9, 0x7, a9_spisg_parents, NULL); +static A9_COMP_DIV(spisg2, SPISG_CLK_CTRL1, 0, 6); +static A9_COMP_GATE(spisg2, SPISG_CLK_CTRL1, 8, 0); + +static const struct clk_parent_data a9_saradc_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "sys", } +}; + +static A9_COMP_SEL(saradc, SAR_CLK_CTRL, 9, 0x7, a9_saradc_parents, NULL); +static A9_COMP_DIV(saradc, SAR_CLK_CTRL, 0, 8); +static A9_COMP_GATE(saradc, SAR_CLK_CTRL, 8, 0); + +static const struct clk_parent_data a9_amfc_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "sys", }, + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", } +}; + +static A9_COMP_SEL(amfc, AMFC_CLK_CTRL, 9, 0x7, a9_amfc_parents, NULL); +static A9_COMP_DIV(amfc, AMFC_CLK_CTRL, 0, 6); +static A9_COMP_GATE(amfc, AMFC_CLK_CTRL, 8, 0); + +static const struct clk_parent_data a9_nna_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv2", }, + { .fw_name = "gp2", }, + { .fw_name = "hifi0", } +}; + +static A9_COMP_SEL(nna, NNA_CLK_CTRL, 9, 0x7, a9_nna_parents, NULL); +static A9_COMP_DIV(nna, NNA_CLK_CTRL, 0, 7); +static A9_COMP_GATE(nna, NNA_CLK_CTRL, 8, 0); + +/* Channel 5 and 6 are unconnected. */ +static u32 a9_usb_250m_parents_val_table[] = { 0, 1, 2, 3, 4, 7 }; +static const struct clk_parent_data a9_usb_250m_parents[] = { + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv7", }, + { .fw_name = "fdiv2p5", } +}; + +static A9_COMP_SEL(usb_250m, USB_CLK_CTRL, 9, 0x7, a9_usb_250m_parents, + a9_usb_250m_parents_val_table); +static A9_COMP_DIV(usb_250m, USB_CLK_CTRL, 0, 7); +static A9_COMP_GATE(usb_250m, USB_CLK_CTRL, 8, 0); + +static const struct clk_parent_data a9_usb_48m_pre_parents[] = { + { .fw_name = "gp0", }, + { .fw_name = "gp1", }, + { .fw_name = "gp2", }, + { .fw_name = "fdiv2", } +}; + +static A9_COMP_SEL(usb_48m_pre, USB_CLK_CTRL, 25, 0x3, a9_usb_48m_pre_parents, NULL); +static A9_COMP_DIV(usb_48m_pre, USB_CLK_CTRL, 16, 7); +static A9_COMP_GATE(usb_48m_pre, USB_CLK_CTRL, 24, 0); + +static const struct clk_parent_data a9_pcie_tl_parents[] = { + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "gp0", }, + { .fw_name = "sys", }, + { .fw_name = "xtal", } +}; + +static A9_COMP_SEL(pcie0_tl, PCIE_TL_CLK_CTRL, 9, 0x7, a9_pcie_tl_parents, NULL); +static A9_COMP_DIV(pcie0_tl, PCIE_TL_CLK_CTRL, 0, 7); +static A9_COMP_GATE(pcie0_tl, PCIE_TL_CLK_CTRL, 8, 0); + +static A9_COMP_SEL(pcie1_tl, PCIE_TL_CLK_CTRL, 25, 0x7, a9_pcie_tl_parents, NULL); +static A9_COMP_DIV(pcie1_tl, PCIE_TL_CLK_CTRL, 16, 7); +static A9_COMP_GATE(pcie1_tl, PCIE_TL_CLK_CTRL, 24, 0); + +static const struct clk_parent_data a9_cmpr_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, + { .fw_name = "hifi0", }, + { .fw_name = "gp1", } +}; + +static A9_COMP_SEL(cmpr, CMPR_CLK_CTRL, 25, 0x7, a9_cmpr_parents, NULL); +static A9_COMP_DIV(cmpr, CMPR_CLK_CTRL, 16, 7); +static A9_COMP_GATE(cmpr, CMPR_CLK_CTRL, 24, 0); + +static const struct clk_parent_data a9_dewarpa_parents[] = { + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, + { .fw_name = "gp0", }, + { .fw_name = "hifi0", }, + { .fw_name = "gp1", } +}; + +static A9_COMP_SEL(dewarpa, DEWARP_CLK_CTRL, 9, 0x7, a9_dewarpa_parents, NULL); +static A9_COMP_DIV(dewarpa, DEWARP_CLK_CTRL, 0, 7); +static A9_COMP_GATE(dewarpa, DEWARP_CLK_CTRL, 8, 0); + +static const struct clk_parent_data a9_sc_parents[] = { + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "xtal", } +}; + +static A9_COMP_SEL(sc_pre, SC_CLK_CTRL, 9, 0x7, a9_sc_parents, NULL); +static A9_COMP_DIV(sc_pre, SC_CLK_CTRL, 0, 8); +static A9_COMP_GATE(sc_pre, SC_CLK_CTRL, 8, 0); + +static struct clk_regmap a9_sc = { + .data = &(struct clk_regmap_div_data) { + .offset = SC_CLK_CTRL, + .shift = 16, + .width = 4, + }, + .hw.init = &(struct clk_init_data) { + .name = "sc", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_sc_pre.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data a9_dptx_apb2_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "sys", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", } +}; + +static A9_COMP_SEL(dptx_apb2, DPTX_CLK_CTRL, 9, 0x7, a9_dptx_apb2_parents, NULL); +static A9_COMP_DIV(dptx_apb2, DPTX_CLK_CTRL, 0, 7); +static A9_COMP_GATE(dptx_apb2, DPTX_CLK_CTRL, 8, 0); + +static const struct clk_parent_data a9_dptx_aud_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "sys", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", } +}; + +static A9_COMP_SEL(dptx_aud, DPTX_CLK_CTRL, 25, 0x7, a9_dptx_aud_parents, NULL); +static A9_COMP_DIV(dptx_aud, DPTX_CLK_CTRL, 16, 7); +static A9_COMP_GATE(dptx_aud, DPTX_CLK_CTRL, 24, 0); + +static const struct clk_parent_data a9_isp_parents[] = { + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "gp0", }, + { .fw_name = "hifi0", }, + { .fw_name = "fdiv2", }, + { .fw_name = "xtal", } +}; + +static A9_COMP_SEL(isp, ISP_CLK_CTRL, 9, 0x7, a9_isp_parents, NULL); +static A9_COMP_DIV(isp, ISP_CLK_CTRL, 0, 7); +static A9_COMP_GATE(isp, ISP_CLK_CTRL, 8, 0); + +static const struct clk_parent_data a9_cve_vge_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "hifi0", }, + { .fw_name = "fdiv5", }, + { .fw_name = "gp0", }, + { .fw_name = "rtc", } +}; + +static A9_COMP_SEL(cve, CVE_CLK_CTRL, 9, 0x7, a9_cve_vge_parents, NULL); +static A9_COMP_DIV(cve, CVE_CLK_CTRL, 0, 7); +static A9_COMP_GATE(cve, CVE_CLK_CTRL, 8, 0); + +static A9_COMP_SEL(vge, CVE_CLK_CTRL, 25, 0x7, a9_cve_vge_parents, NULL); +static A9_COMP_DIV(vge, CVE_CLK_CTRL, 16, 7); +static A9_COMP_GATE(vge, CVE_CLK_CTRL, 24, 0); + +static const struct clk_parent_data a9_pp_parents[] = { + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "gp0", }, + { .fw_name = "sys", }, + { .fw_name = "xtal", } +}; + +static A9_COMP_SEL(pp, PP_CLK_CTRL, 9, 0x7, a9_pp_parents, NULL); +static A9_COMP_DIV(pp, PP_CLK_CTRL, 0, 6); +static A9_COMP_GATE(pp, PP_CLK_CTRL, 8, 0); + +static const struct clk_parent_data a9_dspa_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "gp2", }, + { .fw_name = "fdiv4", }, + { .fw_name = "hifi0", }, + { .fw_name = "rtc", } +}; + +static A9_COMP_SEL(dspa_0, DSPA_CLK_CTRL, 9, 0x7, a9_dspa_parents, NULL); +static A9_COMP_DIV(dspa_0, DSPA_CLK_CTRL, 0, 7); +static A9_COMP_GATE(dspa_0, DSPA_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static A9_COMP_SEL(dspa_1, DSPA_CLK_CTRL, 25, 0x7, a9_dspa_parents, NULL); +static A9_COMP_DIV(dspa_1, DSPA_CLK_CTRL, 16, 7); +static A9_COMP_GATE(dspa_1, DSPA_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap a9_dspa = { + .data = &(struct clk_regmap_mux_data){ + .offset = DSPA_CLK_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspa", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_dspa_0.hw, + &a9_dspa_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* Channel 6 is unconnected. */ +static u32 a9_glb_parents_val_table[] = { 0, 1, 2, 3, 4, 5, 7 }; +static const struct clk_parent_data a9_glb_parents[] = { + { .fw_name = "xtal", }, + { .hw = &a9_dspa.hw }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .hw = &a9_isp.hw }, + { .fw_name = "rtc", } +}; + +static A9_COMP_SEL(glb, GLB_CLK_CTRL, 9, 0x7, a9_glb_parents, a9_glb_parents_val_table); +static A9_COMP_DIV(glb, GLB_CLK_CTRL, 0, 7); +static A9_COMP_GATE(glb, GLB_CLK_CTRL, 8, 0); + +static struct clk_regmap a9_usb_48m_dualdiv_in = { + .data = &(struct clk_regmap_gate_data) { + .offset = USB_CLK_CTRL, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "usb_48m_dualdiv_in", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_usb_48m_pre.hw + }, + .num_parents = 1, + }, +}; + +static const struct meson_clk_dualdiv_param a9_usb_48m_dualdiv_div_table[] = { + { 733, 732, 8, 11, 1 }, + { /* sentinel */ } +}; + +static struct clk_regmap a9_usb_48m_dualdiv_div = { + .data = &(struct meson_clk_dualdiv_data) { + .n1 = { + .reg_off = USB_CLK_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = USB_CLK_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = USB_CLK_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = USB_CLK_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = USB_CLK_CTRL0, + .shift = 28, + .width = 1, + }, + .table = a9_usb_48m_dualdiv_div_table, + }, + .hw.init = &(struct clk_init_data) { + .name = "usb_48m_dualdiv_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_usb_48m_dualdiv_in.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a9_usb_48m_dualdiv_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = USB_CLK_CTRL1, + .mask = 0x1, + .shift = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "usb_48m_dualdiv_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_usb_48m_dualdiv_in.hw, + &a9_usb_48m_dualdiv_div.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_usb_48m_dualdiv = { + .data = &(struct clk_regmap_gate_data) { + .offset = USB_CLK_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "usb_48m_dualdiv", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_usb_48m_dualdiv_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_usb_48m = { + .data = &(struct clk_regmap_mux_data) { + .offset = USB_CLK_CTRL1, + .mask = 0x3, + .shift = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "usb_48m", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_usb_48m_pre.hw, + &a9_usb_48m_dualdiv.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* Channel 2 is unconnected. */ +static u32 a9_can_pe_parents_val_table[] = { 0, 1, 3 }; +static const struct clk_parent_data a9_can_pe_parents[] = { + { .fw_name = "sys", }, + { .fw_name = "xtal", }, + { .fw_name = "fdiv5", } +}; + +static A9_COMP_SEL(can0_pe, CAN_CLK_CTRL, 9, 0x7, a9_can_pe_parents, a9_can_pe_parents_val_table); +static A9_COMP_DIV(can0_pe, CAN_CLK_CTRL, 0, 7); +static A9_COMP_GATE(can0_pe, CAN_CLK_CTRL, 8, 0); + +static A9_COMP_SEL(can1_pe, CAN_CLK_CTRL, 25, 0x7, a9_can_pe_parents, a9_can_pe_parents_val_table); +static A9_COMP_DIV(can1_pe, CAN_CLK_CTRL, 16, 7); +static A9_COMP_GATE(can1_pe, CAN_CLK_CTRL, 24, 0); + +static const struct clk_parent_data a9_can_filter_parents[] = { + { .fw_name = "sys", }, + { .fw_name = "xtal", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", } +}; + +static A9_COMP_SEL(can0_filter, CAN_CLK_CTRL1, 9, 0x7, a9_can_filter_parents, NULL); +static A9_COMP_DIV(can0_filter, CAN_CLK_CTRL1, 0, 7); +static A9_COMP_GATE(can0_filter, CAN_CLK_CTRL1, 8, 0); + +static A9_COMP_SEL(can1_filter, CAN_CLK_CTRL1, 25, 0x7, a9_can_filter_parents, NULL); +static A9_COMP_DIV(can1_filter, CAN_CLK_CTRL1, 16, 7); +static A9_COMP_GATE(can1_filter, CAN_CLK_CTRL1, 24, 0); + +static const struct clk_parent_data a9_i3c_parents[] = { + { .fw_name = "sys", }, + { .fw_name = "xtal", }, + { .fw_name = "fdiv5", } +}; + +static A9_COMP_SEL(i3c, I3C_CLK_CTRL, 9, 0x7, a9_i3c_parents, NULL); +static A9_COMP_DIV(i3c, I3C_CLK_CTRL, 0, 8); +static A9_COMP_GATE(i3c, I3C_CLK_CTRL, 8, 0); + +static struct clk_regmap a9_ts_div = { + .data = &(struct clk_regmap_div_data) { + .offset = TS_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "ts_div", + .ops = &clk_regmap_divider_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a9_ts = { + .data = &(struct clk_regmap_gate_data) { + .offset = TS_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "ts", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_ts_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor a9_eth_125m_div = { + .mult = 1, + .div = 8, + .hw.init = &(struct clk_init_data) { + .name = "eth_125m_div", + .ops = &clk_fixed_factor_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "fdiv2", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a9_eth_125m = { + .data = &(struct clk_regmap_gate_data) { + .offset = ETH_CLK_CTRL, + .bit_idx = 7, + }, + .hw.init = &(struct clk_init_data) { + .name = "eth_125m", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_eth_125m_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * Channel 1, 2, 3, 4, 5 and 6 are unconnected, + * Channel 7(ext_rmii) connects external PAD. Do not automatically reparent. + */ +static u32 a9_eth_rmii_parents_val_table[] = { 0, 7 }; +static const struct clk_parent_data a9_eth_rmii_parents[] = { + { .fw_name = "fdiv2", }, + { .fw_name = "ext_rmii", } +}; + +static struct clk_regmap a9_eth_rmii_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = ETH_CLK_CTRL, + .mask = 0x7, + .shift = 9, + .table = a9_eth_rmii_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "eth_rmii_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = a9_eth_rmii_parents, + .num_parents = ARRAY_SIZE(a9_eth_rmii_parents), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap a9_eth_rmii_div = { + .data = &(struct clk_regmap_div_data) { + .offset = ETH_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "eth_rmii_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_eth_rmii_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_eth_rmii = { + .data = &(struct clk_regmap_gate_data) { + .offset = ETH_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "eth_rmii", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_eth_rmii_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_vid_pll_div = { + .data = &(struct meson_vid_pll_div_data){ + .val = { + .reg_off = VID_PLL_CLK_DIV, + .shift = 0, + .width = 15, + }, + .sel = { + .reg_off = VID_PLL_CLK_DIV, + .shift = 16, + .width = 2, + }, + }, + .hw.init = &(struct clk_init_data) { + .name = "vid_pll_div", + .ops = &meson_vid_pll_div_ro_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "hdmiout2", } + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a9_vid_pll_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = VID_PLL_CLK_DIV, + .mask = 0x1, + .shift = 18, + }, + .hw.init = &(struct clk_init_data){ + .name = "vid_pll_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &a9_vid_pll_div.hw }, + { .fw_name = "hdmiout2", } + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_vid_pll = { + .data = &(struct clk_regmap_gate_data){ + .offset = VID_PLL_CLK_DIV, + .bit_idx = 19, + }, + .hw.init = &(struct clk_init_data) { + .name = "vid_pll", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_vid_pll_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * Channel 12 (msr_clk) is managed by the clock measurement module and is not part of the clock + * tree. It depends on the measurement source selected through the measurement control registers. + * + * Channel 10, 11, 13, 14 and 16 are unconnected. + */ +static u32 a9_gen_parents_val_table[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26}; +static const struct clk_parent_data a9_gen_parents[] = { + { .fw_name = "xtal" }, + { .fw_name = "rtc" }, + { .fw_name = "sysplldiv16" }, + { .fw_name = "ddr_test" }, + { .hw = &a9_vid_pll.hw }, + { .fw_name = "gp0" }, + { .fw_name = "hifi1" }, + { .fw_name = "hifi0" }, + { .fw_name = "gp1" }, + { .fw_name = "gp2" }, + { .fw_name = "dsudiv16" }, + { .fw_name = "cpudiv16" }, + { .fw_name = "a78div16" }, + { .fw_name = "fdiv2" }, + { .fw_name = "fdiv2p5" }, + { .fw_name = "fdiv3" }, + { .fw_name = "fdiv4" }, + { .fw_name = "fdiv5" }, + { .fw_name = "fdiv7" }, + { .fw_name = "mclk0" }, + { .fw_name = "mclk1" } +}; + +static A9_COMP_SEL(gen, GEN_CLK_CTRL, 12, 0x1f, a9_gen_parents, a9_gen_parents_val_table); +static A9_COMP_DIV(gen, GEN_CLK_CTRL, 0, 11); +static A9_COMP_GATE(gen, GEN_CLK_CTRL, 11, 0); + +static struct clk_regmap a9_24m_in = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLK12_24_CTRL, + .bit_idx = 11, + }, + .hw.init = &(struct clk_init_data) { + .name = "24m_in", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a9_12_24m = { + .data = &(struct clk_regmap_div_data) { + .offset = CLK12_24_CTRL, + .shift = 10, + .width = 1, + }, + .hw.init = &(struct clk_init_data) { + .name = "12_24m", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_24m_in.hw + }, + .num_parents = 1, + }, +}; + +static const struct clk_parent_data a9_mali_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "gp1", }, + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", } +}; + +static A9_COMP_SEL(mali_0, MALI_CLK_CTRL, 9, 0x7, a9_mali_parents, NULL); +static A9_COMP_DIV(mali_0, MALI_CLK_CTRL, 0, 7); +static A9_COMP_GATE(mali_0, MALI_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static A9_COMP_SEL(mali_1, MALI_CLK_CTRL, 25, 0x7, a9_mali_parents, NULL); +static A9_COMP_DIV(mali_1, MALI_CLK_CTRL, 16, 7); +static A9_COMP_GATE(mali_1, MALI_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap a9_mali = { + .data = &(struct clk_regmap_mux_data){ + .offset = MALI_CLK_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mali", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_mali_0.hw, + &a9_mali_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static A9_COMP_SEL(mali_stack_0, MALI_STACK_CLK_CTRL, 9, 0x7, a9_mali_parents, NULL); +static A9_COMP_DIV(mali_stack_0, MALI_STACK_CLK_CTRL, 0, 7); +static A9_COMP_GATE(mali_stack_0, MALI_STACK_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static A9_COMP_SEL(mali_stack_1, MALI_STACK_CLK_CTRL, 25, 0x7, a9_mali_parents, NULL); +static A9_COMP_DIV(mali_stack_1, MALI_STACK_CLK_CTRL, 16, 7); +static A9_COMP_GATE(mali_stack_1, MALI_STACK_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap a9_mali_stack = { + .data = &(struct clk_regmap_mux_data){ + .offset = MALI_STACK_CLK_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mali_stack", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_mali_stack_0.hw, + &a9_mali_stack_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data a9_hevcf_parents[] = { + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, + { .fw_name = "hifi0", }, + { .fw_name = "gp1", }, + { .fw_name = "xtal", } +}; + +static A9_COMP_SEL(hevcf_0, HEVCF_CLK_CTRL, 9, 0x7, a9_hevcf_parents, NULL); +static A9_COMP_DIV(hevcf_0, HEVCF_CLK_CTRL, 0, 7); +static A9_COMP_GATE(hevcf_0, HEVCF_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static A9_COMP_SEL(hevcf_1, HEVCF_CLK_CTRL, 25, 0x7, a9_hevcf_parents, NULL); +static A9_COMP_DIV(hevcf_1, HEVCF_CLK_CTRL, 16, 7); +static A9_COMP_GATE(hevcf_1, HEVCF_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap a9_hevcf = { + .data = &(struct clk_regmap_mux_data){ + .offset = HEVCF_CLK_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "hevcf", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_hevcf_0.hw, + &a9_hevcf_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data a9_hcodec_parents[] = { + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, + { .fw_name = "hifi0", }, + { .fw_name = "gp0", }, + { .fw_name = "xtal", } +}; + +static A9_COMP_SEL(hcodec_0, HCODEC_CLK_CTRL, 9, 0x7, a9_hcodec_parents, NULL); +static A9_COMP_DIV(hcodec_0, HCODEC_CLK_CTRL, 0, 7); +static A9_COMP_GATE(hcodec_0, HCODEC_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static A9_COMP_SEL(hcodec_1, HCODEC_CLK_CTRL, 25, 0x7, a9_hcodec_parents, NULL); +static A9_COMP_DIV(hcodec_1, HCODEC_CLK_CTRL, 16, 7); +static A9_COMP_GATE(hcodec_1, HCODEC_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap a9_hcodec = { + .data = &(struct clk_regmap_mux_data){ + .offset = HCODEC_CLK_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "hcodec", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_hcodec_0.hw, + &a9_hcodec_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data a9_vpu_parents[] = { + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "vid1", }, + { .fw_name = "fdiv2", }, + { .hw = &a9_vid_pll.hw }, + { .fw_name = "vid2", }, + { .fw_name = "gp1", } +}; + +static A9_COMP_SEL(vpu_0, VPU_CLK_CTRL, 9, 0x7, a9_vpu_parents, NULL); +static A9_COMP_DIV(vpu_0, VPU_CLK_CTRL, 0, 7); +static A9_COMP_GATE(vpu_0, VPU_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static A9_COMP_SEL(vpu_1, VPU_CLK_CTRL, 25, 0x7, a9_vpu_parents, NULL); +static A9_COMP_DIV(vpu_1, VPU_CLK_CTRL, 16, 7); +static A9_COMP_GATE(vpu_1, VPU_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap a9_vpu = { + .data = &(struct clk_regmap_mux_data){ + .offset = VPU_CLK_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_vpu_0.hw, + &a9_vpu_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data a9_vapb_parents[] = { + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, + { .fw_name = "fdiv2", }, + { .hw = &a9_vid_pll.hw }, + { .fw_name = "hifi0", }, + { .fw_name = "fdiv2p5", } +}; + +static A9_COMP_SEL(vapb_0, VAPB_CLK_CTRL, 9, 0x7, a9_vapb_parents, NULL); +static A9_COMP_DIV(vapb_0, VAPB_CLK_CTRL, 0, 7); +static A9_COMP_GATE(vapb_0, VAPB_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static A9_COMP_SEL(vapb_1, VAPB_CLK_CTRL, 25, 0x7, a9_vapb_parents, NULL); +static A9_COMP_DIV(vapb_1, VAPB_CLK_CTRL, 16, 7); +static A9_COMP_GATE(vapb_1, VAPB_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap a9_vapb = { + .data = &(struct clk_regmap_mux_data){ + .offset = VAPB_CLK_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_vapb_0.hw, + &a9_vapb_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_ge2d = { + .data = &(struct clk_regmap_gate_data) { + .offset = VAPB_CLK_CTRL, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "ge2d", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_vapb.hw, + }, + .num_parents = 1, + }, +}; + +static const struct clk_parent_data a9_vpu_clkb_tmp_parents[] = { + { .hw = &a9_vpu.hw }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", } +}; + +static A9_COMP_SEL(vpu_clkb_tmp, VPU_CLKB_CTRL, 25, 0x7, a9_vpu_clkb_tmp_parents, NULL); +static A9_COMP_DIV(vpu_clkb_tmp, VPU_CLKB_CTRL, 16, 4); +static A9_COMP_GATE(vpu_clkb_tmp, VPU_CLKB_CTRL, 24, 0); + +static struct clk_regmap a9_vpu_clkb_div = { + .data = &(struct clk_regmap_div_data) { + .offset = VPU_CLKB_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_clkb_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_vpu_clkb_tmp.hw, + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap a9_vpu_clkb = { + .data = &(struct clk_regmap_gate_data) { + .offset = VPU_CLKB_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_clkb", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_vpu_clkb_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data a9_hdmi_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", } +}; + +static A9_COMP_SEL(hdmitx_sys, HDMI_CLK_CTRL, 9, 0x7, a9_hdmi_parents, NULL); +static A9_COMP_DIV(hdmitx_sys, HDMI_CLK_CTRL, 0, 7); +static A9_COMP_GATE(hdmitx_sys, HDMI_CLK_CTRL, 8, 0); + +static A9_COMP_SEL(hdmitx_prif, HTX_CLK_CTRL, 9, 0x7, a9_hdmi_parents, NULL); +static A9_COMP_DIV(hdmitx_prif, HTX_CLK_CTRL, 0, 7); +static A9_COMP_GATE(hdmitx_prif, HTX_CLK_CTRL, 8, 0); + +static A9_COMP_SEL(hdmitx_200m, HTX_CLK_CTRL, 25, 0x7, a9_hdmi_parents, NULL); +static A9_COMP_DIV(hdmitx_200m, HTX_CLK_CTRL, 16, 7); +static A9_COMP_GATE(hdmitx_200m, HTX_CLK_CTRL, 24, 0); + +static A9_COMP_SEL(hdmitx_aud, HTX_CLK_CTRL1, 9, 0x7, a9_hdmi_parents, NULL); +static A9_COMP_DIV(hdmitx_aud, HTX_CLK_CTRL1, 0, 7); +static A9_COMP_GATE(hdmitx_aud, HTX_CLK_CTRL1, 8, 0); + +static A9_COMP_SEL(hdmirx_5m, HRX_CLK_CTRL, 9, 0x7, a9_hdmi_parents, NULL); +static A9_COMP_DIV(hdmirx_5m, HRX_CLK_CTRL, 0, 7); +static A9_COMP_GATE(hdmirx_5m, HRX_CLK_CTRL, 8, 0); + +static A9_COMP_SEL(hdmirx_2m, HRX_CLK_CTRL, 25, 0x7, a9_hdmi_parents, NULL); +static A9_COMP_DIV(hdmirx_2m, HRX_CLK_CTRL, 16, 7); +static A9_COMP_GATE(hdmirx_2m, HRX_CLK_CTRL, 24, 0); + +static A9_COMP_SEL(hdmirx_cfg, HRX_CLK_CTRL1, 9, 0x7, a9_hdmi_parents, NULL); +static A9_COMP_DIV(hdmirx_cfg, HRX_CLK_CTRL1, 0, 7); +static A9_COMP_GATE(hdmirx_cfg, HRX_CLK_CTRL1, 8, 0); + +static A9_COMP_SEL(hdmirx_hdcp2x, HRX_CLK_CTRL1, 25, 0x7, a9_hdmi_parents, NULL); +static A9_COMP_DIV(hdmirx_hdcp2x, HRX_CLK_CTRL1, 16, 7); +static A9_COMP_GATE(hdmirx_hdcp2x, HRX_CLK_CTRL1, 24, 0); + +static A9_COMP_SEL(hdmirx_acr_ref, HRX_CLK_CTRL2, 25, 0x7, a9_hdmi_parents, NULL); +static A9_COMP_DIV(hdmirx_acr_ref, HRX_CLK_CTRL2, 16, 7); +static A9_COMP_GATE(hdmirx_acr_ref, HRX_CLK_CTRL2, 24, 0); + +static A9_COMP_SEL(hdmirx_meter, HRX_CLK_CTRL3, 9, 0x7, a9_hdmi_parents, NULL); +static A9_COMP_DIV(hdmirx_meter, HRX_CLK_CTRL3, 0, 7); +static A9_COMP_GATE(hdmirx_meter, HRX_CLK_CTRL3, 8, 0); + +static struct clk_regmap a9_vid_pll_vclk = { + .data = &(struct clk_regmap_mux_data){ + .offset = HDMI_CLK_CTRL, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "vid_pll_vclk", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &a9_vid_pll.hw }, + { .fw_name = "hdmipix", } + }, + .num_parents = 2, + }, +}; + +static const struct clk_parent_data a9_vclk_parents[] = { + { .hw = &a9_vid_pll_vclk.hw }, + { .fw_name = "pix0", }, + { .fw_name = "vid1", }, + { .fw_name = "pix1", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "vid2", } +}; + +static struct clk_regmap a9_vclk0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = VID_CLK_CTRL, + .mask = 0x7, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "vclk0_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = a9_vclk_parents, + .num_parents = ARRAY_SIZE(a9_vclk_parents), + }, +}; + +static struct clk_regmap a9_vclk0_in = { + .data = &(struct clk_regmap_gate_data){ + .offset = VID_CLK_DIV, + .bit_idx = 16, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk0_in", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &a9_vclk0_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_vclk0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = VID_CLK_DIV, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "vclk0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_vclk0_in.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_vclk0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = VID_CLK_CTRL, + .bit_idx = 19, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &a9_vclk0_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +#define A9_VCLK_GATE(_name, _reg, _bit, _parent) \ +struct clk_regmap a9_##_name##_en = { \ + .data = &(struct clk_regmap_gate_data) { \ + .offset = (_reg), \ + .bit_idx = (_bit), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name "_en", \ + .ops = &clk_regmap_gate_ops, \ + .parent_hws = (const struct clk_hw *[]) { \ + &(_parent).hw \ + }, \ + .num_parents = 1, \ + .flags = CLK_SET_RATE_PARENT, \ + }, \ +} + +#define A9_VCLK_DIV(_name, _div) \ +struct clk_fixed_factor a9_##_name = { \ + .mult = 1, \ + .div = (_div), \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_fixed_factor_ops, \ + .parent_hws = (const struct clk_hw *[]) { \ + &a9_##_name##_en.hw \ + }, \ + .num_parents = 1, \ + .flags = CLK_SET_RATE_PARENT, \ + }, \ +} + +static A9_VCLK_GATE(vclk0_div1, VID_CLK_CTRL, 0, a9_vclk0); +static A9_VCLK_GATE(vclk0_div2, VID_CLK_CTRL, 1, a9_vclk0); +static A9_VCLK_DIV(vclk0_div2, 2); +static A9_VCLK_GATE(vclk0_div4, VID_CLK_CTRL, 2, a9_vclk0); +static A9_VCLK_DIV(vclk0_div4, 4); +static A9_VCLK_GATE(vclk0_div6, VID_CLK_CTRL, 3, a9_vclk0); +static A9_VCLK_DIV(vclk0_div6, 6); +static A9_VCLK_GATE(vclk0_div12, VID_CLK_CTRL, 4, a9_vclk0); +static A9_VCLK_DIV(vclk0_div12, 12); + +static struct clk_regmap a9_vclk1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = VIID_CLK_CTRL, + .mask = 0x7, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "vclk1_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = a9_vclk_parents, + .num_parents = ARRAY_SIZE(a9_vclk_parents), + }, +}; + +static struct clk_regmap a9_vclk1_in = { + .data = &(struct clk_regmap_gate_data){ + .offset = VIID_CLK_DIV, + .bit_idx = 16, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk1_in", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &a9_vclk1_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_vclk1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = VIID_CLK_DIV, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "vclk1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_vclk1_in.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_vclk1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = VIID_CLK_CTRL, + .bit_idx = 19, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &a9_vclk1_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static A9_VCLK_GATE(vclk1_div1, VIID_CLK_CTRL, 0, a9_vclk1); +static A9_VCLK_GATE(vclk1_div2, VIID_CLK_CTRL, 1, a9_vclk1); +static A9_VCLK_DIV(vclk1_div2, 2); +static A9_VCLK_GATE(vclk1_div4, VIID_CLK_CTRL, 2, a9_vclk1); +static A9_VCLK_DIV(vclk1_div4, 4); +static A9_VCLK_GATE(vclk1_div6, VIID_CLK_CTRL, 3, a9_vclk1); +static A9_VCLK_DIV(vclk1_div6, 6); +static A9_VCLK_GATE(vclk1_div12, VIID_CLK_CTRL, 4, a9_vclk1); +static A9_VCLK_DIV(vclk1_div12, 12); + +/* Channel 5, 6 and 7 are unconnected */ +static u32 a9_vid_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_hw *a9_vid_parents[] = { + &a9_vclk0_div1_en.hw, + &a9_vclk0_div2.hw, + &a9_vclk0_div4.hw, + &a9_vclk0_div6.hw, + &a9_vclk0_div12.hw, + &a9_vclk1_div1_en.hw, + &a9_vclk1_div2.hw, + &a9_vclk1_div4.hw, + &a9_vclk1_div6.hw, + &a9_vclk1_div12.hw +}; + +static struct clk_regmap a9_encoder0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = VIID_CLK_DIV, + .mask = 0xf, + .shift = 12, + .table = a9_vid_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "encoder0_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = a9_vid_parents, + .num_parents = ARRAY_SIZE(a9_vid_parents), + }, +}; + +static struct clk_regmap a9_encoder0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = VID_CLK_CTRL2, + .bit_idx = 10, + }, + .hw.init = &(struct clk_init_data) { + .name = "encoder0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_encoder0_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_encoder1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = VIID_CLK_DIV, + .mask = 0xf, + .shift = 8, + .table = a9_vid_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "encoder1_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = a9_vid_parents, + .num_parents = ARRAY_SIZE(a9_vid_parents), + }, +}; + +static struct clk_regmap a9_encoder1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = VID_CLK_CTRL2, + .bit_idx = 11, + }, + .hw.init = &(struct clk_init_data) { + .name = "encoder1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_encoder1_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data a9_vid_lock_parents[] = { + { .fw_name = "xtal", }, + { .hw = &a9_encoder0.hw }, + { .hw = &a9_encoder1.hw } +}; + +static A9_COMP_SEL(vid_lock, VID_LOCK_CLK_CTRL, 9, 0x7, a9_vid_lock_parents, NULL); +static A9_COMP_DIV(vid_lock, VID_LOCK_CLK_CTRL, 0, 7); +static A9_COMP_GATE(vid_lock, VID_LOCK_CLK_CTRL, 8, 0); + +static const struct clk_parent_data a9_vdin_meas_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", } +}; + +static A9_COMP_SEL(vdin_meas, VDIN_MEAS_CLK_CTRL, 9, 0x7, a9_vdin_meas_parents, NULL); +static A9_COMP_DIV(vdin_meas, VDIN_MEAS_CLK_CTRL, 0, 7); +static A9_COMP_GATE(vdin_meas, VDIN_MEAS_CLK_CTRL, 8, 0); + +static struct clk_regmap a9_vdac_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = VIID_CLK_DIV, + .mask = 0xf, + .shift = 28, + .table = a9_vid_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdac_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = a9_vid_parents, + .num_parents = ARRAY_SIZE(a9_vid_parents), + }, +}; + +static struct clk_regmap a9_vdac = { + .data = &(struct clk_regmap_gate_data){ + .offset = VID_CLK_CTRL2, + .bit_idx = 4, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdac", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_vdac_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_hdmitx0_pixel_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HDMI_CLK_CTRL, + .mask = 0xf, + .shift = 16, + .table = a9_vid_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmitx0_pixel_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = a9_vid_parents, + .num_parents = ARRAY_SIZE(a9_vid_parents), + }, +}; + +static struct clk_regmap a9_hdmitx0_pixel = { + .data = &(struct clk_regmap_gate_data){ + .offset = VID_CLK_CTRL2, + .bit_idx = 5, + }, + .hw.init = &(struct clk_init_data) { + .name = "hdmitx0_pixel", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_hdmitx0_pixel_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_hdmitx0_fe_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HDMI_CLK_CTRL, + .mask = 0xf, + .shift = 20, + .table = a9_vid_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmitx0_fe_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = a9_vid_parents, + .num_parents = ARRAY_SIZE(a9_vid_parents), + }, +}; + +static struct clk_regmap a9_hdmitx0_fe = { + .data = &(struct clk_regmap_gate_data){ + .offset = VID_CLK_CTRL2, + .bit_idx = 9, + }, + .hw.init = &(struct clk_init_data) { + .name = "hdmitx0_fe", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_hdmitx0_fe_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_hdmitx1_pixel_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HDMI_CLK_CTRL, + .mask = 0xf, + .shift = 24, + .table = a9_vid_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmitx1_pixel_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = a9_vid_parents, + .num_parents = ARRAY_SIZE(a9_vid_parents), + }, +}; + +static struct clk_regmap a9_hdmitx1_pixel = { + .data = &(struct clk_regmap_gate_data){ + .offset = VID_CLK_CTRL2, + .bit_idx = 12, + }, + .hw.init = &(struct clk_init_data) { + .name = "hdmitx1_pixel", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_hdmitx1_pixel_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap a9_hdmitx1_fe_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HDMI_CLK_CTRL, + .mask = 0xf, + .shift = 28, + .table = a9_vid_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmitx1_fe_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = a9_vid_parents, + .num_parents = ARRAY_SIZE(a9_vid_parents), + }, +}; + +static struct clk_regmap a9_hdmitx1_fe = { + .data = &(struct clk_regmap_gate_data){ + .offset = VID_CLK_CTRL2, + .bit_idx = 13, + }, + .hw.init = &(struct clk_init_data) { + .name = "hdmitx1_fe", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &a9_hdmitx1_fe_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data a9_csi_phy_parents[] = { + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "gp0", }, + { .fw_name = "hifi0", }, + { .fw_name = "fdiv2", }, + { .fw_name = "xtal", } +}; + +static A9_COMP_SEL(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 9, 0x7, a9_csi_phy_parents, NULL); +static A9_COMP_DIV(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 0, 7); +static A9_COMP_GATE(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 8, 0); + +static const struct clk_parent_data a9_dsi_meas_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .hw = &a9_vid_pll.hw }, + { .fw_name = "gp0", }, + { .fw_name = "vid1", }, + { .fw_name = "vid2", } +}; + +static A9_COMP_SEL(dsi0_meas, DSI_MEAS_CLK_CTRL, 9, 0x7, a9_dsi_meas_parents, NULL); +static A9_COMP_DIV(dsi0_meas, DSI_MEAS_CLK_CTRL, 0, 7); +static A9_COMP_GATE(dsi0_meas, DSI_MEAS_CLK_CTRL, 8, 0); + +static A9_COMP_SEL(dsi1_meas, DSI_MEAS_CLK_CTRL, 25, 0x7, a9_dsi_meas_parents, NULL); +static A9_COMP_DIV(dsi1_meas, DSI_MEAS_CLK_CTRL, 16, 7); +static A9_COMP_GATE(dsi1_meas, DSI_MEAS_CLK_CTRL, 24, 0); + +static struct clk_hw *a9_peripherals_hw_clks[] = { + [CLKID_SYS_AM_AXI] = &a9_sys_am_axi.hw, + [CLKID_SYS_DOS] = &a9_sys_dos.hw, + [CLKID_SYS_MIPI_DSI0] = &a9_sys_mipi_dsi0.hw, + [CLKID_SYS_ETH_PHY] = &a9_sys_eth_phy.hw, + [CLKID_SYS_AMFC] = &a9_sys_amfc.hw, + [CLKID_SYS_MALI] = &a9_sys_mali.hw, + [CLKID_SYS_NNA] = &a9_sys_nna.hw, + [CLKID_SYS_ETH_AXI] = &a9_sys_eth_axi.hw, + [CLKID_SYS_DP_APB] = &a9_sys_dp_apb.hw, + [CLKID_SYS_EDPTX_APB] = &a9_sys_edptx_apb.hw, + [CLKID_SYS_U3HSG] = &a9_sys_u3hsg.hw, + [CLKID_SYS_AUCPU] = &a9_sys_aucpu.hw, + [CLKID_SYS_GLB] = &a9_sys_glb.hw, + [CLKID_SYS_COMBO_DPHY_APB] = &a9_sys_combo_dphy_apb.hw, + [CLKID_SYS_HDMIRX_APB] = &a9_sys_hdmirx_apb.hw, + [CLKID_SYS_HDMIRX_PCLK] = &a9_sys_hdmirx_pclk.hw, + [CLKID_SYS_MIPI_DSI0_PHY] = &a9_sys_mipi_dsi0_phy.hw, + [CLKID_SYS_CAN0] = &a9_sys_can0.hw, + [CLKID_SYS_CAN1] = &a9_sys_can1.hw, + [CLKID_SYS_SD_EMMC_A] = &a9_sys_sd_emmc_a.hw, + [CLKID_SYS_SD_EMMC_B] = &a9_sys_sd_emmc_b.hw, + [CLKID_SYS_SD_EMMC_C] = &a9_sys_sd_emmc_c.hw, + [CLKID_SYS_SC] = &a9_sys_sc.hw, + [CLKID_SYS_ACODEC] = &a9_sys_acodec.hw, + [CLKID_SYS_MIPI_ISP] = &a9_sys_mipi_isp.hw, + [CLKID_SYS_MSR] = &a9_sys_msr.hw, + [CLKID_SYS_AUDIO] = &a9_sys_audio.hw, + [CLKID_SYS_MIPI_DSI1] = &a9_sys_mipi_dsi1.hw, + [CLKID_SYS_MIPI_DSI1_PHY] = &a9_sys_mipi_dsi1_phy.hw, + [CLKID_SYS_ETH] = &a9_sys_eth.hw, + [CLKID_SYS_ETH_1G_MAC] = &a9_sys_eth_1g_mac.hw, + [CLKID_SYS_UART_A] = &a9_sys_uart_a.hw, + [CLKID_SYS_UART_F] = &a9_sys_uart_f.hw, + [CLKID_SYS_TS_A55] = &a9_sys_ts_a55.hw, + [CLKID_SYS_ETH_1G_AXI] = &a9_sys_eth_1g_axi.hw, + [CLKID_SYS_TS_DOS] = &a9_sys_ts_dos.hw, + [CLKID_SYS_U3DRD_B] = &a9_sys_u3drd_b.hw, + [CLKID_SYS_TS_CORE] = &a9_sys_ts_core.hw, + [CLKID_SYS_TS_PLL] = &a9_sys_ts_pll.hw, + [CLKID_SYS_CSI_DIG_CLKIN] = &a9_sys_csi_dig_clkin.hw, + [CLKID_SYS_CVE] = &a9_sys_cve.hw, + [CLKID_SYS_GE2D] = &a9_sys_ge2d.hw, + [CLKID_SYS_SPISG] = &a9_sys_spisg.hw, + [CLKID_SYS_U2H] = &a9_sys_u2h.hw, + [CLKID_SYS_PCIE_MAC_A] = &a9_sys_pcie_mac_a.hw, + [CLKID_SYS_U3DRD_A] = &a9_sys_u3drd_a.hw, + [CLKID_SYS_U2DRD] = &a9_sys_u2drd.hw, + [CLKID_SYS_PCIE_PHY] = &a9_sys_pcie_phy.hw, + [CLKID_SYS_PCIE_MAC_B] = &a9_sys_pcie_mac_b.hw, + [CLKID_SYS_PERIPH] = &a9_sys_periph.hw, + [CLKID_SYS_PIO] = &a9_sys_pio.hw, + [CLKID_SYS_I3C] = &a9_sys_i3c.hw, + [CLKID_SYS_I2C_M_E] = &a9_sys_i2c_m_e.hw, + [CLKID_SYS_I2C_M_F] = &a9_sys_i2c_m_f.hw, + [CLKID_SYS_HDMITX_APB] = &a9_sys_hdmitx_apb.hw, + [CLKID_SYS_I2C_M_I] = &a9_sys_i2c_m_i.hw, + [CLKID_SYS_I2C_M_G] = &a9_sys_i2c_m_g.hw, + [CLKID_SYS_I2C_M_H] = &a9_sys_i2c_m_h.hw, + [CLKID_SYS_HDMI20_AES] = &a9_sys_hdmi20_aes.hw, + [CLKID_SYS_CSI2_HOST] = &a9_sys_csi2_host.hw, + [CLKID_SYS_CSI2_ADAPT] = &a9_sys_csi2_adapt.hw, + [CLKID_SYS_DSPA] = &a9_sys_dspa.hw, + [CLKID_SYS_PP_DMA] = &a9_sys_pp_dma.hw, + [CLKID_SYS_PP_WRAPPER] = &a9_sys_pp_wrapper.hw, + [CLKID_SYS_VPU_INTR] = &a9_sys_vpu_intr.hw, + [CLKID_SYS_CSI2_PHY] = &a9_sys_csi2_phy.hw, + [CLKID_SYS_SARADC] = &a9_sys_saradc.hw, + [CLKID_SYS_PWM_J] = &a9_sys_pwm_j.hw, + [CLKID_SYS_PWM_I] = &a9_sys_pwm_i.hw, + [CLKID_SYS_PWM_H] = &a9_sys_pwm_h.hw, + [CLKID_SYS_PWM_N] = &a9_sys_pwm_n.hw, + [CLKID_SYS_PWM_M] = &a9_sys_pwm_m.hw, + [CLKID_SYS_PWM_L] = &a9_sys_pwm_l.hw, + [CLKID_SYS_PWM_K] = &a9_sys_pwm_k.hw, + [CLKID_SD_EMMC_A_SEL] = &a9_sd_emmc_a_sel.hw, + [CLKID_SD_EMMC_A_DIV] = &a9_sd_emmc_a_div.hw, + [CLKID_SD_EMMC_A] = &a9_sd_emmc_a.hw, + [CLKID_SD_EMMC_B_SEL] = &a9_sd_emmc_b_sel.hw, + [CLKID_SD_EMMC_B_DIV] = &a9_sd_emmc_b_div.hw, + [CLKID_SD_EMMC_B] = &a9_sd_emmc_b.hw, + [CLKID_SD_EMMC_C_SEL] = &a9_sd_emmc_c_sel.hw, + [CLKID_SD_EMMC_C_DIV] = &a9_sd_emmc_c_div.hw, + [CLKID_SD_EMMC_C] = &a9_sd_emmc_c.hw, + [CLKID_PWM_H_SEL] = &a9_pwm_h_sel.hw, + [CLKID_PWM_H_DIV] = &a9_pwm_h_div.hw, + [CLKID_PWM_H] = &a9_pwm_h.hw, + [CLKID_PWM_I_SEL] = &a9_pwm_i_sel.hw, + [CLKID_PWM_I_DIV] = &a9_pwm_i_div.hw, + [CLKID_PWM_I] = &a9_pwm_i.hw, + [CLKID_PWM_J_SEL] = &a9_pwm_j_sel.hw, + [CLKID_PWM_J_DIV] = &a9_pwm_j_div.hw, + [CLKID_PWM_J] = &a9_pwm_j.hw, + [CLKID_PWM_K_SEL] = &a9_pwm_k_sel.hw, + [CLKID_PWM_K_DIV] = &a9_pwm_k_div.hw, + [CLKID_PWM_K] = &a9_pwm_k.hw, + [CLKID_PWM_L_SEL] = &a9_pwm_l_sel.hw, + [CLKID_PWM_L_DIV] = &a9_pwm_l_div.hw, + [CLKID_PWM_L] = &a9_pwm_l.hw, + [CLKID_PWM_M_SEL] = &a9_pwm_m_sel.hw, + [CLKID_PWM_M_DIV] = &a9_pwm_m_div.hw, + [CLKID_PWM_M] = &a9_pwm_m.hw, + [CLKID_PWM_N_SEL] = &a9_pwm_n_sel.hw, + [CLKID_PWM_N_DIV] = &a9_pwm_n_div.hw, + [CLKID_PWM_N] = &a9_pwm_n.hw, + [CLKID_SPISG0_SEL] = &a9_spisg0_sel.hw, + [CLKID_SPISG0_DIV] = &a9_spisg0_div.hw, + [CLKID_SPISG0] = &a9_spisg0.hw, + [CLKID_SPISG1_SEL] = &a9_spisg1_sel.hw, + [CLKID_SPISG1_DIV] = &a9_spisg1_div.hw, + [CLKID_SPISG1] = &a9_spisg1.hw, + [CLKID_SPISG2_SEL] = &a9_spisg2_sel.hw, + [CLKID_SPISG2_DIV] = &a9_spisg2_div.hw, + [CLKID_SPISG2] = &a9_spisg2.hw, + [CLKID_SARADC_SEL] = &a9_saradc_sel.hw, + [CLKID_SARADC_DIV] = &a9_saradc_div.hw, + [CLKID_SARADC] = &a9_saradc.hw, + [CLKID_AMFC_SEL] = &a9_amfc_sel.hw, + [CLKID_AMFC_DIV] = &a9_amfc_div.hw, + [CLKID_AMFC] = &a9_amfc.hw, + [CLKID_NNA_SEL] = &a9_nna_sel.hw, + [CLKID_NNA_DIV] = &a9_nna_div.hw, + [CLKID_NNA] = &a9_nna.hw, + [CLKID_USB_250M_SEL] = &a9_usb_250m_sel.hw, + [CLKID_USB_250M_DIV] = &a9_usb_250m_div.hw, + [CLKID_USB_250M] = &a9_usb_250m.hw, + [CLKID_USB_48M_PRE_SEL] = &a9_usb_48m_pre_sel.hw, + [CLKID_USB_48M_PRE_DIV] = &a9_usb_48m_pre_div.hw, + [CLKID_USB_48M_PRE] = &a9_usb_48m_pre.hw, + [CLKID_PCIE0_TL_SEL] = &a9_pcie0_tl_sel.hw, + [CLKID_PCIE0_TL_DIV] = &a9_pcie0_tl_div.hw, + [CLKID_PCIE0_TL] = &a9_pcie0_tl.hw, + [CLKID_PCIE1_TL_SEL] = &a9_pcie1_tl_sel.hw, + [CLKID_PCIE1_TL_DIV] = &a9_pcie1_tl_div.hw, + [CLKID_PCIE1_TL] = &a9_pcie1_tl.hw, + [CLKID_CMPR_SEL] = &a9_cmpr_sel.hw, + [CLKID_CMPR_DIV] = &a9_cmpr_div.hw, + [CLKID_CMPR] = &a9_cmpr.hw, + [CLKID_DEWARPA_SEL] = &a9_dewarpa_sel.hw, + [CLKID_DEWARPA_DIV] = &a9_dewarpa_div.hw, + [CLKID_DEWARPA] = &a9_dewarpa.hw, + [CLKID_SC_PRE_SEL] = &a9_sc_pre_sel.hw, + [CLKID_SC_PRE_DIV] = &a9_sc_pre_div.hw, + [CLKID_SC_PRE] = &a9_sc_pre.hw, + [CLKID_SC] = &a9_sc.hw, + [CLKID_DPTX_APB2_SEL] = &a9_dptx_apb2_sel.hw, + [CLKID_DPTX_APB2_DIV] = &a9_dptx_apb2_div.hw, + [CLKID_DPTX_APB2] = &a9_dptx_apb2.hw, + [CLKID_DPTX_AUD_SEL] = &a9_dptx_aud_sel.hw, + [CLKID_DPTX_AUD_DIV] = &a9_dptx_aud_div.hw, + [CLKID_DPTX_AUD] = &a9_dptx_aud.hw, + [CLKID_ISP_SEL] = &a9_isp_sel.hw, + [CLKID_ISP_DIV] = &a9_isp_div.hw, + [CLKID_ISP] = &a9_isp.hw, + [CLKID_CVE_SEL] = &a9_cve_sel.hw, + [CLKID_CVE_DIV] = &a9_cve_div.hw, + [CLKID_CVE] = &a9_cve.hw, + [CLKID_VGE_SEL] = &a9_vge_sel.hw, + [CLKID_VGE_DIV] = &a9_vge_div.hw, + [CLKID_VGE] = &a9_vge.hw, + [CLKID_PP_SEL] = &a9_pp_sel.hw, + [CLKID_PP_DIV] = &a9_pp_div.hw, + [CLKID_PP] = &a9_pp.hw, + [CLKID_GLB_SEL] = &a9_glb_sel.hw, + [CLKID_GLB_DIV] = &a9_glb_div.hw, + [CLKID_GLB] = &a9_glb.hw, + [CLKID_USB_48M_DUALDIV_IN] = &a9_usb_48m_dualdiv_in.hw, + [CLKID_USB_48M_DUALDIV_DIV] = &a9_usb_48m_dualdiv_div.hw, + [CLKID_USB_48M_DUALDIV_SEL] = &a9_usb_48m_dualdiv_sel.hw, + [CLKID_USB_48M_DUALDIV] = &a9_usb_48m_dualdiv.hw, + [CLKID_USB_48M] = &a9_usb_48m.hw, + [CLKID_CAN0_PE_SEL] = &a9_can0_pe_sel.hw, + [CLKID_CAN0_PE_DIV] = &a9_can0_pe_div.hw, + [CLKID_CAN0_PE] = &a9_can0_pe.hw, + [CLKID_CAN1_PE_SEL] = &a9_can1_pe_sel.hw, + [CLKID_CAN1_PE_DIV] = &a9_can1_pe_div.hw, + [CLKID_CAN1_PE] = &a9_can1_pe.hw, + [CLKID_CAN0_FILTER_SEL] = &a9_can0_filter_sel.hw, + [CLKID_CAN0_FILTER_DIV] = &a9_can0_filter_div.hw, + [CLKID_CAN0_FILTER] = &a9_can0_filter.hw, + [CLKID_CAN1_FILTER_SEL] = &a9_can1_filter_sel.hw, + [CLKID_CAN1_FILTER_DIV] = &a9_can1_filter_div.hw, + [CLKID_CAN1_FILTER] = &a9_can1_filter.hw, + [CLKID_I3C_SEL] = &a9_i3c_sel.hw, + [CLKID_I3C_DIV] = &a9_i3c_div.hw, + [CLKID_I3C] = &a9_i3c.hw, + [CLKID_TS_DIV] = &a9_ts_div.hw, + [CLKID_TS] = &a9_ts.hw, + [CLKID_ETH_125M_DIV] = &a9_eth_125m_div.hw, + [CLKID_ETH_125M] = &a9_eth_125m.hw, + [CLKID_ETH_RMII_SEL] = &a9_eth_rmii_sel.hw, + [CLKID_ETH_RMII_DIV] = &a9_eth_rmii_div.hw, + [CLKID_ETH_RMII] = &a9_eth_rmii.hw, + [CLKID_GEN_SEL] = &a9_gen_sel.hw, + [CLKID_GEN_DIV] = &a9_gen_div.hw, + [CLKID_GEN] = &a9_gen.hw, + [CLKID_CLK24M_IN] = &a9_24m_in.hw, + [CLKID_CLK12_24M] = &a9_12_24m.hw, + [CLKID_MALI_0_SEL] = &a9_mali_0_sel.hw, + [CLKID_MALI_0_DIV] = &a9_mali_0_div.hw, + [CLKID_MALI_0] = &a9_mali_0.hw, + [CLKID_MALI_1_SEL] = &a9_mali_1_sel.hw, + [CLKID_MALI_1_DIV] = &a9_mali_1_div.hw, + [CLKID_MALI_1] = &a9_mali_1.hw, + [CLKID_MALI] = &a9_mali.hw, + [CLKID_MALI_STACK_0_SEL] = &a9_mali_stack_0_sel.hw, + [CLKID_MALI_STACK_0_DIV] = &a9_mali_stack_0_div.hw, + [CLKID_MALI_STACK_0] = &a9_mali_stack_0.hw, + [CLKID_MALI_STACK_1_SEL] = &a9_mali_stack_1_sel.hw, + [CLKID_MALI_STACK_1_DIV] = &a9_mali_stack_1_div.hw, + [CLKID_MALI_STACK_1] = &a9_mali_stack_1.hw, + [CLKID_MALI_STACK] = &a9_mali_stack.hw, + [CLKID_DSPA_0_SEL] = &a9_dspa_0_sel.hw, + [CLKID_DSPA_0_DIV] = &a9_dspa_0_div.hw, + [CLKID_DSPA_0] = &a9_dspa_0.hw, + [CLKID_DSPA_1_SEL] = &a9_dspa_1_sel.hw, + [CLKID_DSPA_1_DIV] = &a9_dspa_1_div.hw, + [CLKID_DSPA_1] = &a9_dspa_1.hw, + [CLKID_DSPA] = &a9_dspa.hw, + [CLKID_HEVCF_0_SEL] = &a9_hevcf_0_sel.hw, + [CLKID_HEVCF_0_DIV] = &a9_hevcf_0_div.hw, + [CLKID_HEVCF_0] = &a9_hevcf_0.hw, + [CLKID_HEVCF_1_SEL] = &a9_hevcf_1_sel.hw, + [CLKID_HEVCF_1_DIV] = &a9_hevcf_1_div.hw, + [CLKID_HEVCF_1] = &a9_hevcf_1.hw, + [CLKID_HEVCF] = &a9_hevcf.hw, + [CLKID_HCODEC_0_SEL] = &a9_hcodec_0_sel.hw, + [CLKID_HCODEC_0_DIV] = &a9_hcodec_0_div.hw, + [CLKID_HCODEC_0] = &a9_hcodec_0.hw, + [CLKID_HCODEC_1_SEL] = &a9_hcodec_1_sel.hw, + [CLKID_HCODEC_1_DIV] = &a9_hcodec_1_div.hw, + [CLKID_HCODEC_1] = &a9_hcodec_1.hw, + [CLKID_HCODEC] = &a9_hcodec.hw, + [CLKID_VPU_0_SEL] = &a9_vpu_0_sel.hw, + [CLKID_VPU_0_DIV] = &a9_vpu_0_div.hw, + [CLKID_VPU_0] = &a9_vpu_0.hw, + [CLKID_VPU_1_SEL] = &a9_vpu_1_sel.hw, + [CLKID_VPU_1_DIV] = &a9_vpu_1_div.hw, + [CLKID_VPU_1] = &a9_vpu_1.hw, + [CLKID_VPU] = &a9_vpu.hw, + [CLKID_VAPB_0_SEL] = &a9_vapb_0_sel.hw, + [CLKID_VAPB_0_DIV] = &a9_vapb_0_div.hw, + [CLKID_VAPB_0] = &a9_vapb_0.hw, + [CLKID_VAPB_1_SEL] = &a9_vapb_1_sel.hw, + [CLKID_VAPB_1_DIV] = &a9_vapb_1_div.hw, + [CLKID_VAPB_1] = &a9_vapb_1.hw, + [CLKID_VAPB] = &a9_vapb.hw, + [CLKID_GE2D] = &a9_ge2d.hw, + [CLKID_VPU_CLKB_TMP_SEL] = &a9_vpu_clkb_tmp_sel.hw, + [CLKID_VPU_CLKB_TMP_DIV] = &a9_vpu_clkb_tmp_div.hw, + [CLKID_VPU_CLKB_TMP] = &a9_vpu_clkb_tmp.hw, + [CLKID_VPU_CLKB_DIV] = &a9_vpu_clkb_div.hw, + [CLKID_VPU_CLKB] = &a9_vpu_clkb.hw, + [CLKID_HDMITX_SYS_SEL] = &a9_hdmitx_sys_sel.hw, + [CLKID_HDMITX_SYS_DIV] = &a9_hdmitx_sys_div.hw, + [CLKID_HDMITX_SYS] = &a9_hdmitx_sys.hw, + [CLKID_HDMITX_PRIF_SEL] = &a9_hdmitx_prif_sel.hw, + [CLKID_HDMITX_PRIF_DIV] = &a9_hdmitx_prif_div.hw, + [CLKID_HDMITX_PRIF] = &a9_hdmitx_prif.hw, + [CLKID_HDMITX_200M_SEL] = &a9_hdmitx_200m_sel.hw, + [CLKID_HDMITX_200M_DIV] = &a9_hdmitx_200m_div.hw, + [CLKID_HDMITX_200M] = &a9_hdmitx_200m.hw, + [CLKID_HDMITX_AUD_SEL] = &a9_hdmitx_aud_sel.hw, + [CLKID_HDMITX_AUD_DIV] = &a9_hdmitx_aud_div.hw, + [CLKID_HDMITX_AUD] = &a9_hdmitx_aud.hw, + [CLKID_HDMIRX_5M_SEL] = &a9_hdmirx_5m_sel.hw, + [CLKID_HDMIRX_5M_DIV] = &a9_hdmirx_5m_div.hw, + [CLKID_HDMIRX_5M] = &a9_hdmirx_5m.hw, + [CLKID_HDMIRX_2M_SEL] = &a9_hdmirx_2m_sel.hw, + [CLKID_HDMIRX_2M_DIV] = &a9_hdmirx_2m_div.hw, + [CLKID_HDMIRX_2M] = &a9_hdmirx_2m.hw, + [CLKID_HDMIRX_CFG_SEL] = &a9_hdmirx_cfg_sel.hw, + [CLKID_HDMIRX_CFG_DIV] = &a9_hdmirx_cfg_div.hw, + [CLKID_HDMIRX_CFG] = &a9_hdmirx_cfg.hw, + [CLKID_HDMIRX_HDCP2X_SEL] = &a9_hdmirx_hdcp2x_sel.hw, + [CLKID_HDMIRX_HDCP2X_DIV] = &a9_hdmirx_hdcp2x_div.hw, + [CLKID_HDMIRX_HDCP2X] = &a9_hdmirx_hdcp2x.hw, + [CLKID_HDMIRX_ACR_REF_SEL] = &a9_hdmirx_acr_ref_sel.hw, + [CLKID_HDMIRX_ACR_REF_DIV] = &a9_hdmirx_acr_ref_div.hw, + [CLKID_HDMIRX_ACR_REF] = &a9_hdmirx_acr_ref.hw, + [CLKID_HDMIRX_METER_SEL] = &a9_hdmirx_meter_sel.hw, + [CLKID_HDMIRX_METER_DIV] = &a9_hdmirx_meter_div.hw, + [CLKID_HDMIRX_METER] = &a9_hdmirx_meter.hw, + [CLKID_VID_LOCK_SEL] = &a9_vid_lock_sel.hw, + [CLKID_VID_LOCK_DIV] = &a9_vid_lock_div.hw, + [CLKID_VID_LOCK] = &a9_vid_lock.hw, + [CLKID_VDIN_MEAS_SEL] = &a9_vdin_meas_sel.hw, + [CLKID_VDIN_MEAS_DIV] = &a9_vdin_meas_div.hw, + [CLKID_VDIN_MEAS] = &a9_vdin_meas.hw, + [CLKID_VID_PLL_DIV] = &a9_vid_pll_div.hw, + [CLKID_VID_PLL_SEL] = &a9_vid_pll_sel.hw, + [CLKID_VID_PLL] = &a9_vid_pll.hw, + [CLKID_VID_PLL_VCLK] = &a9_vid_pll_vclk.hw, + [CLKID_VCLK0_SEL] = &a9_vclk0_sel.hw, + [CLKID_VCLK0_IN] = &a9_vclk0_in.hw, + [CLKID_VCLK0_DIV] = &a9_vclk0_div.hw, + [CLKID_VCLK0] = &a9_vclk0.hw, + [CLKID_VCLK0_DIV1_EN] = &a9_vclk0_div1_en.hw, + [CLKID_VCLK0_DIV2_EN] = &a9_vclk0_div2_en.hw, + [CLKID_VCLK0_DIV2] = &a9_vclk0_div2.hw, + [CLKID_VCLK0_DIV4_EN] = &a9_vclk0_div4_en.hw, + [CLKID_VCLK0_DIV4] = &a9_vclk0_div4.hw, + [CLKID_VCLK0_DIV6_EN] = &a9_vclk0_div6_en.hw, + [CLKID_VCLK0_DIV6] = &a9_vclk0_div6.hw, + [CLKID_VCLK0_DIV12_EN] = &a9_vclk0_div12_en.hw, + [CLKID_VCLK0_DIV12] = &a9_vclk0_div12.hw, + [CLKID_VCLK1_SEL] = &a9_vclk1_sel.hw, + [CLKID_VCLK1_IN] = &a9_vclk1_in.hw, + [CLKID_VCLK1_DIV] = &a9_vclk1_div.hw, + [CLKID_VCLK1] = &a9_vclk1.hw, + [CLKID_VCLK1_DIV1_EN] = &a9_vclk1_div1_en.hw, + [CLKID_VCLK1_DIV2_EN] = &a9_vclk1_div2_en.hw, + [CLKID_VCLK1_DIV2] = &a9_vclk1_div2.hw, + [CLKID_VCLK1_DIV4_EN] = &a9_vclk1_div4_en.hw, + [CLKID_VCLK1_DIV4] = &a9_vclk1_div4.hw, + [CLKID_VCLK1_DIV6_EN] = &a9_vclk1_div6_en.hw, + [CLKID_VCLK1_DIV6] = &a9_vclk1_div6.hw, + [CLKID_VCLK1_DIV12_EN] = &a9_vclk1_div12_en.hw, + [CLKID_VCLK1_DIV12] = &a9_vclk1_div12.hw, + [CLKID_VDAC_SEL] = &a9_vdac_sel.hw, + [CLKID_VDAC] = &a9_vdac.hw, + [CLKID_ENCODER0_SEL] = &a9_encoder0_sel.hw, + [CLKID_ENCODER0] = &a9_encoder0.hw, + [CLKID_ENCODER1_SEL] = &a9_encoder1_sel.hw, + [CLKID_ENCODER1] = &a9_encoder1.hw, + [CLKID_HDMITX0_PIXEL_SEL] = &a9_hdmitx0_pixel_sel.hw, + [CLKID_HDMITX0_PIXEL] = &a9_hdmitx0_pixel.hw, + [CLKID_HDMITX0_FE_SEL] = &a9_hdmitx0_fe_sel.hw, + [CLKID_HDMITX0_FE] = &a9_hdmitx0_fe.hw, + [CLKID_HDMITX1_PIXEL_SEL] = &a9_hdmitx1_pixel_sel.hw, + [CLKID_HDMITX1_PIXEL] = &a9_hdmitx1_pixel.hw, + [CLKID_HDMITX1_FE_SEL] = &a9_hdmitx1_fe_sel.hw, + [CLKID_HDMITX1_FE] = &a9_hdmitx1_fe.hw, + [CLKID_CSI_PHY_SEL] = &a9_csi_phy_sel.hw, + [CLKID_CSI_PHY_DIV] = &a9_csi_phy_div.hw, + [CLKID_CSI_PHY] = &a9_csi_phy.hw, + [CLKID_DSI0_MEAS_SEL] = &a9_dsi0_meas_sel.hw, + [CLKID_DSI0_MEAS_DIV] = &a9_dsi0_meas_div.hw, + [CLKID_DSI0_MEAS] = &a9_dsi0_meas.hw, + [CLKID_DSI1_MEAS_SEL] = &a9_dsi1_meas_sel.hw, + [CLKID_DSI1_MEAS_DIV] = &a9_dsi1_meas_div.hw, + [CLKID_DSI1_MEAS] = &a9_dsi1_meas.hw, +}; + +static const struct meson_clkc_data a9_peripherals_clkc_data = { + .hw_clks = { + .hws = a9_peripherals_hw_clks, + .num = ARRAY_SIZE(a9_peripherals_hw_clks), + }, +}; + +static const struct of_device_id a9_peripherals_clkc_match_table[] = { + { + .compatible = "amlogic,a9-peripherals-clkc", + .data = &a9_peripherals_clkc_data, + }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, a9_peripherals_clkc_match_table); + +static struct platform_driver a9_peripherals_clkc_driver = { + .probe = meson_clkc_mmio_probe, + .driver = { + .name = "a9-peripherals-clkc", + .of_match_table = a9_peripherals_clkc_match_table, + }, +}; +module_platform_driver(a9_peripherals_clkc_driver); + +MODULE_DESCRIPTION("Amlogic A9 Peripherals Clock Controller driver"); +MODULE_AUTHOR("Jian Hu "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 39af7b1868e3..7a7b104182ff 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -1393,7 +1393,7 @@ static struct clk_regmap gxbb_32k_clk_sel = { .name = "32k_clk_sel", .ops = &clk_regmap_mux_ops, .parent_data = gxbb_32k_clk_parents, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gxbb_32k_clk_parents), .flags = CLK_SET_RATE_PARENT, }, }; diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c index ee58304913ef..7f044775aea8 100644 --- a/drivers/clk/microchip/clk-mpfs.c +++ b/drivers/clk/microchip/clk-mpfs.c @@ -285,7 +285,7 @@ static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned mask = clk_div_mask(cfg->width) << cfg->shift; val = divider_setting << cfg->shift; - regmap_update_bits(cfg->map, cfg->map_offset, val, mask); + regmap_update_bits(cfg->map, cfg->map_offset, mask, val); return 0; } diff --git a/drivers/clk/mmp/clk-pxa1908-apbc.c b/drivers/clk/mmp/clk-pxa1908-apbc.c index 438ece4f047d..16c1f13bca1f 100644 --- a/drivers/clk/mmp/clk-pxa1908-apbc.c +++ b/drivers/clk/mmp/clk-pxa1908-apbc.c @@ -114,7 +114,7 @@ static void pxa1908_clk_reset_init(struct device_node *np, cells[i].bits = BIT(2); cells[i].flags = 0; cells[i].lock = apbc_gate_clks[i].lock; - }; + } mmp_clk_reset_register(np, cells, nr_cells); } diff --git a/drivers/clk/mmp/clk-pxa1908-apbcp.c b/drivers/clk/mmp/clk-pxa1908-apbcp.c index 1aa476103553..4e646e8b7440 100644 --- a/drivers/clk/mmp/clk-pxa1908-apbcp.c +++ b/drivers/clk/mmp/clk-pxa1908-apbcp.c @@ -61,7 +61,7 @@ static void pxa1908_clk_reset_init(struct device_node *np, cells[i].bits = BIT(2); cells[i].flags = 0; cells[i].lock = apbcp_gate_clks[i].lock; - }; + } mmp_clk_reset_register(np, cells, nr_cells); } diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index 26d52ecaac50..24196e288fe2 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c @@ -153,7 +153,7 @@ static int clk_cpu_on_set_rate(struct clk_hw *hwclk, unsigned long rate, static int clk_cpu_set_rate(struct clk_hw *hwclk, unsigned long rate, unsigned long parent_rate) { - if (__clk_is_enabled(hwclk->clk)) + if (clk_hw_is_enabled(hwclk)) return clk_cpu_on_set_rate(hwclk, rate, parent_rate); else return clk_cpu_off_set_rate(hwclk, rate, parent_rate); diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c index ed061d82fb65..f4f62b241193 100644 --- a/drivers/clk/mvebu/kirkwood.c +++ b/drivers/clk/mvebu/kirkwood.c @@ -253,8 +253,8 @@ struct clk_muxing_soc_desc { struct clk_muxing_ctrl { spinlock_t *lock; - struct clk **muxes; int num_muxes; + struct clk *muxes[] __counted_by(num_muxes); }; static const char *powersave_parents[] = { @@ -297,21 +297,18 @@ static void __init kirkwood_clk_muxing_setup(struct device_node *np, if (WARN_ON(!base)) return; - ctrl = kzalloc_obj(*ctrl); - if (WARN_ON(!ctrl)) - goto ctrl_out; - - /* lock must already be initialized */ - ctrl->lock = &ctrl_gating_lock; - /* Count, allocate, and register clock muxes */ for (n = 0; desc[n].name;) n++; + ctrl = kzalloc_flex(*ctrl, muxes, n); + if (WARN_ON(!ctrl)) + goto ctrl_out; + ctrl->num_muxes = n; - ctrl->muxes = kzalloc_objs(struct clk *, ctrl->num_muxes); - if (WARN_ON(!ctrl->muxes)) - goto muxes_out; + + /* lock must already be initialized */ + ctrl->lock = &ctrl_gating_lock; for (n = 0; n < ctrl->num_muxes; n++) { ctrl->muxes[n] = clk_register_mux(NULL, desc[n].name, @@ -324,8 +321,6 @@ static void __init kirkwood_clk_muxing_setup(struct device_node *np, of_clk_add_provider(np, clk_muxing_get_src, ctrl); return; -muxes_out: - kfree(ctrl); ctrl_out: iounmap(base); } diff --git a/drivers/clk/nuvoton/clk-ma35d1-pll.c b/drivers/clk/nuvoton/clk-ma35d1-pll.c index 4620acfe47e8..c7c0dc91a012 100644 --- a/drivers/clk/nuvoton/clk-ma35d1-pll.c +++ b/drivers/clk/nuvoton/clk-ma35d1-pll.c @@ -48,7 +48,7 @@ #define PLL_CTL1_PD BIT(0) #define PLL_CTL1_BP BIT(1) #define PLL_CTL1_OUTDIV GENMASK(6, 4) -#define PLL_CTL1_FRAC GENMASK(31, 24) +#define PLL_CTL1_FRAC GENMASK(31, 8) #define PLL_CTL2_SLOPE GENMASK(23, 0) #define INDIV_MIN 1 @@ -92,7 +92,7 @@ static unsigned long ma35d1_calc_smic_pll_freq(u32 pll0_ctl0, p = FIELD_GET(SPLL0_CTL0_OUTDIV, pll0_ctl0); outdiv = 1 << p; pll_freq = (u64)parent_rate * n; - div_u64(pll_freq, m * outdiv); + pll_freq = div_u64(pll_freq, m * outdiv); return pll_freq; } @@ -110,12 +110,12 @@ static unsigned long ma35d1_calc_pll_freq(u8 mode, u32 *reg_ctl, unsigned long p if (mode == PLL_MODE_INT) { pll_freq = (u64)parent_rate * n; - div_u64(pll_freq, m * p); + pll_freq = div_u64(pll_freq, m * p); } else { x = FIELD_GET(PLL_CTL1_FRAC, reg_ctl[1]); - /* 2 decimal places floating to integer (ex. 1.23 to 123) */ - n = n * 100 + ((x * 100) / FIELD_MAX(PLL_CTL1_FRAC)); - pll_freq = div_u64(parent_rate * n, 100 * m * p); + /* convert 24-bit fraction to 3 decimal digits, rounding to closest */ + n = n * 1000 + DIV_ROUND_CLOSEST_ULL((u64)x * 1000, 1ULL << 24); + pll_freq = div_u64((u64)parent_rate * n, 1000 * m * p); } return pll_freq; } @@ -255,32 +255,32 @@ static int ma35d1_clk_pll_determine_rate(struct clk_hw *hw, if (req->best_parent_rate < PLL_FREF_MIN_FREQ || req->best_parent_rate > PLL_FREF_MAX_FREQ) return -EINVAL; - ret = ma35d1_pll_find_closest(pll, req->rate, req->best_parent_rate, - reg_ctl, &pll_freq); - if (ret < 0) - return ret; - switch (pll->id) { case CAPLL: - reg_ctl[0] = readl_relaxed(pll->ctl0_base); - pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], req->best_parent_rate); - req->rate = pll_freq; - - return 0; case DDRPLL: + /* Read-only PLLs: return current rate */ + reg_ctl[0] = readl_relaxed(pll->ctl0_base); + if (pll->id == CAPLL) { + pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], req->best_parent_rate); + } else { + reg_ctl[1] = readl_relaxed(pll->ctl1_base); + pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, req->best_parent_rate); + } + req->rate = pll_freq; + return 0; case APLL: case EPLL: case VPLL: - reg_ctl[0] = readl_relaxed(pll->ctl0_base); - reg_ctl[1] = readl_relaxed(pll->ctl1_base); - pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, req->best_parent_rate); + /* Configurable PLLs: find closest achievable rate */ + ret = ma35d1_pll_find_closest(pll, req->rate, req->best_parent_rate, + reg_ctl, &pll_freq); + if (ret < 0) + return ret; req->rate = pll_freq; - return 0; } req->rate = 0; - return 0; } diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 7d84c2f1d911..d1fc9bf87126 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -23,6 +23,7 @@ config CLK_ELIZA_DISPCC tristate "Eliza Display Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_ELIZA_GCC + default m if ARCH_QCOM help Support for the display clock controllers on Eliza SoCs. Say Y if you want to support display devices and functionality such as @@ -32,6 +33,7 @@ config CLK_ELIZA_GCC tristate "Eliza Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on Eliza devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -41,35 +43,61 @@ config CLK_ELIZA_TCSRCC tristate "Eliza TCSR Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default m if ARCH_QCOM help Support for the TCSR clock controller on Eliza devices. Say Y if you want to use peripheral devices such as USB/PCIe/UFS. +config CLK_GLYMUR_CAMCC + tristate "Glymur Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_GLYMUR_GCC + default m if ARCH_QCOM + help + Support for the camera clock controller on Qualcomm Technologies, Inc + Glymur devices. + Say Y if you want to support camera devices and functionality such as + capturing pictures. + config CLK_GLYMUR_DISPCC tristate "Glymur Display Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_GLYMUR_GCC + default m if ARCH_QCOM help Support for the display clock controllers on Qualcomm Technologies, Inc. Glymur devices. Say Y if you want to support display devices and functionality such as splash screen. +config CLK_GLYMUR_EVACC + tristate "Glymur EVA Clock Controller" + depends on ARM64 || COMPILE_TEST + default m if ARCH_QCOM + select CLK_GLYMUR_GCC + default m if ARCH_QCOM + help + Support for the Enhanced Video Analytics (EVA) clock controller on + Qualcomm Technologies, Inc. Glymur devices. + Say Y if you want to support EVA devices and functionality such as + vision processing. + config CLK_GLYMUR_GCC tristate "Glymur Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on Glymur devices. Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDCC, etc. config CLK_GLYMUR_GPUCC - tristate "GLYMUR Graphics Clock Controller" + tristate "Glymur Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_GLYMUR_GCC help - Support for the graphics clock controller on GLYMUR devices. + Support for the graphics clock controller on Glymur devices. Say Y if you want to support graphics controller devices and functionality such as 3D graphics. @@ -77,6 +105,7 @@ config CLK_GLYMUR_TCSRCC tristate "Glymur TCSR Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default m if ARCH_QCOM help Support for the TCSR clock controller on Glymur devices. Say Y if you want to use peripheral devices such as USB/PCIe/EDP. @@ -85,6 +114,7 @@ config CLK_GLYMUR_VIDEOCC tristate "Glymur Video Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_GLYMUR_GCC + default m if ARCH_QCOM help Support for the video clock controller on Glymur devices. Say Y if you want to support video devices and functionality such as @@ -94,6 +124,7 @@ config CLK_KAANAPALI_CAMCC tristate "Kaanapali Camera Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_KAANAPALI_GCC + default m if ARCH_QCOM help Support for the camera clock controller on Qualcomm Technologies, Inc Kaanapali devices. @@ -104,6 +135,7 @@ config CLK_KAANAPALI_DISPCC tristate "Kaanapali Display Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_KAANAPALI_GCC + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc Kaanapali devices. @@ -114,6 +146,7 @@ config CLK_KAANAPALI_GCC tristate "Kaanapali Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on Kaanapali devices. Say Y if you want to use peripheral devices such as UART, @@ -123,6 +156,7 @@ config CLK_KAANAPALI_GPUCC tristate "Kaanapali Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_KAANAPALI_GCC + default m if ARCH_QCOM help Support for the graphics clock controller on Kaanapali devices. Say Y if you want to support graphics controller devices and @@ -132,6 +166,7 @@ config CLK_KAANAPALI_TCSRCC tristate "Kaanapali TCSR Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default m if ARCH_QCOM help Support for the TCSR clock controller on Kaanapali devices. Say Y if you want to use peripheral devices such as PCIe, USB, UFS. @@ -140,25 +175,80 @@ config CLK_KAANAPALI_VIDEOCC tristate "Kaanapali Video Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_KAANAPALI_GCC + default m if ARCH_QCOM help Support for the video clock controller on Kaanapali devices. Say Y if you want to support video devices and functionality such as video encode/decode. +config CLK_NORD_DISPCC + tristate "Nord Display Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_NORD_GCC + default m if ARCH_QCOM + help + Support for the display clock controllers on Qualcomm Technologies, Inc + Nord devices. There are two display clock controllers on Nord SoC. + Say Y if you want to support display devices and functionality such as + splash screen. + +config CLK_MAILI_VIDEOCC + tristate "Maili Video Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_HAWI_GCC + default m if ARCH_QCOM + help + Support for the video clock controller on Maili devices. + Say Y if you want to support video devices and functionality such as + video encode/decode. + config CLK_NORD_GCC tristate "Nord Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on Nord devices. Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, SD/UFS, PCIe etc. The clock controller is a combination of GCC, SE_GCC, NE_GCC and NW_GCC. +config CLK_SHIKRA_AUDIOCORECC + tristate "Shikra Audio Core Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_SHIKRA_GCC + default m if ARCH_QCOM + help + Support for the Audio Core clock controller on Qualcomm Shikra devices. + Say Y if you want to use AudioCoreCC clocks required to support audio + devices and it's functionality. + +config CLK_SHIKRA_GCC + tristate "Shikra Global Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + default ARCH_QCOM + help + Support for the global clock controller on Shikra devices. + Say Y if you want to use multimedia devices or peripheral + devices such as Camera, Video, UART, SPI, I2C, USB, SD/eMMC etc. + +config CLK_NORD_GPUCC + tristate "Nord Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_NORD_GCC + default m if ARCH_QCOM + help + Support for the graphics clock controllers on Nord devices. There are two + graphics clock controllers on Nord SoC. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config CLK_X1E80100_CAMCC tristate "X1E80100 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_X1E80100_GCC + default m if ARCH_QCOM help Support for the camera clock controller on X1E80100 devices. Say Y if you want to support camera devices and camera functionality. @@ -167,6 +257,7 @@ config CLK_X1E80100_DISPCC tristate "X1E80100 Display Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_X1E80100_GCC + default m if ARCH_QCOM help Support for the two display clock controllers on Qualcomm Technologies, Inc. X1E80100 devices. @@ -177,6 +268,7 @@ config CLK_X1E80100_GCC tristate "X1E80100 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on Qualcomm Technologies, Inc X1E80100 devices. @@ -187,6 +279,7 @@ config CLK_X1E80100_GPUCC tristate "X1E80100 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_X1E80100_GCC + default m if ARCH_QCOM help Support for the graphics clock controller on X1E80100 devices. Say Y if you want to support graphics controller devices and @@ -196,6 +289,7 @@ config CLK_X1E80100_TCSRCC tristate "X1E80100 TCSR Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the TCSR clock controller on X1E80100 devices. Say Y if you want to use peripheral devices such as SD/UFS. @@ -215,6 +309,7 @@ config CLK_X1P42100_GPUCC tristate "X1P42100 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_X1E80100_GCC + default m if ARCH_QCOM help Support for the graphics clock controller on X1P42100 devices. Say Y if you want to support graphics controller devices and @@ -235,6 +330,7 @@ config CLK_QCM2290_GPUCC tristate "QCM2290 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select QCM_GCC_2290 + default m if ARCH_QCOM help Support for the graphics clock controller on QCM2290 devices. Say Y if you want to support graphics controller devices and @@ -242,6 +338,7 @@ config CLK_QCM2290_GPUCC config QCOM_A53PLL tristate "MSM8916 A53 PLL" + default ARCH_QCOM help Support for the A53 PLL on MSM8916 devices. It provides the CPU with frequencies above 1GHz. @@ -250,6 +347,8 @@ config QCOM_A53PLL config QCOM_A7PLL tristate "A7 PLL driver for SDX55 and SDX65" + depends on ARM || COMPILE_TEST + default ARCH_QCOM help Support for the A7 PLL on SDX55 and SDX65 devices. It provides the CPU with frequencies above 1GHz. @@ -259,6 +358,7 @@ config QCOM_A7PLL config QCOM_CLK_APCS_MSM8916 tristate "MSM8916 APCS Clock Controller" depends on QCOM_APCS_IPC || COMPILE_TEST + default ARCH_QCOM help Support for the APCS Clock Controller on msm8916 devices. The APCS is managing the mux and divider which feeds the CPUs. @@ -270,6 +370,7 @@ config QCOM_CLK_APCC_MSM8996 select QCOM_KRYO_L2_ACCESSORS select INTERCONNECT_CLK if INTERCONNECT depends on ARM64 + default ARCH_QCOM help Support for the CPU clock controller on msm8996 devices. Say Y if you want to support CPU clock scaling using CPUfreq @@ -279,6 +380,7 @@ config QCOM_CLK_APCS_SDX55 tristate "SDX55 and SDX65 APCS Clock Controller" depends on QCOM_APCS_IPC || COMPILE_TEST depends on ARM || COMPILE_TEST + default ARCH_QCOM help Support for the APCS Clock Controller on SDX55, SDX65 platforms. The APCS is managing the mux and divider which feeds the CPUs. @@ -288,6 +390,7 @@ config QCOM_CLK_APCS_SDX55 config QCOM_CLK_RPM tristate "RPM based Clock Controller" depends on MFD_QCOM_RPM + default ARCH_QCOM help The RPM (Resource Power Manager) is a dedicated hardware engine for managing the shared SoC resources in order to keep the lowest power @@ -300,6 +403,7 @@ config QCOM_CLK_RPM config QCOM_CLK_SMD_RPM tristate "RPM over SMD based Clock Controller" depends on QCOM_SMD_RPM + default ARCH_QCOM help The RPM (Resource Power Manager) is a dedicated hardware engine for managing the shared SoC resources in order to keep the lowest power @@ -312,6 +416,7 @@ config QCOM_CLK_SMD_RPM config QCOM_CLK_RPMH tristate "RPMh Clock Driver" depends on QCOM_RPMH + default ARCH_QCOM help RPMh manages shared resources on some Qualcomm Technologies, Inc. SoCs. It accepts requests from other hardware subsystems via RSC. @@ -322,6 +427,7 @@ config CLK_HAWI_GCC tristate "Hawi Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on Hawi devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -330,14 +436,26 @@ config CLK_HAWI_GCC config CLK_HAWI_TCSRCC tristate "Hawi TCSR Clock Controller" depends on ARM64 || COMPILE_TEST + default m if ARCH_QCOM help Support for the TCSR clock controller on Hawi devices. Say Y if you want to use peripheral devices such as PCIe, USB, UFS. +config CLK_HAWI_VIDEOCC + tristate "Hawi Video Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_HAWI_GCC + default m if ARCH_QCOM + help + Support for the video clock controller on Hawi devices. + Say Y if you want to support video devices and functionality such as + video encode/decode. + config APQ_GCC_8084 tristate "APQ8084 Global Clock Controller" depends on ARM || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on apq8084 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -348,6 +466,7 @@ config APQ_MMCC_8084 depends on ARM || COMPILE_TEST select APQ_GCC_8084 select QCOM_GDSC + default ARCH_QCOM help Support for the multimedia clock controller on apq8084 devices. Say Y if you want to support multimedia devices such as display, @@ -363,6 +482,7 @@ config IPQ_APSS_PLL config IPQ_APSS_5424 tristate "IPQ5424 APSS Clock Controller" + depends on ARM64 || COMPILE_TEST select IPQ_APSS_PLL default y if IPQ_GCC_5424 help @@ -373,8 +493,10 @@ config IPQ_APSS_5424 config IPQ_APSS_6018 tristate "IPQ6018 APSS Clock Controller" select IPQ_APSS_PLL + depends on ARM64 || COMPILE_TEST depends on QCOM_APCS_IPC || COMPILE_TEST depends on QCOM_SMEM + default ARCH_QCOM help Support for APSS clock controller on IPQ platforms. The APSS clock controller manages the Mux and enable block that feeds the @@ -384,6 +506,8 @@ config IPQ_APSS_6018 config IPQ_CMN_PLL tristate "IPQ CMN PLL Clock Controller" + depends on ARM64 || COMPILE_TEST + default m if ARCH_QCOM help Support for CMN PLL clock controller on IPQ platform. The CMN PLL consumes the AHB/SYS clocks from GCC and supplies @@ -393,6 +517,8 @@ config IPQ_CMN_PLL config IPQ_GCC_4019 tristate "IPQ4019 Global Clock Controller" + depends on ARM || COMPILE_TEST + default ARCH_QCOM help Support for the global clock controller on ipq4019 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -401,6 +527,7 @@ config IPQ_GCC_4019 config IPQ_GCC_5018 tristate "IPQ5018 Global Clock Controller" depends on ARM || ARM64 || COMPILE_TEST + default ARCH_QCOM && ARM64 help Support for global clock controller on ipq5018 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -409,6 +536,7 @@ config IPQ_GCC_5018 config IPQ_GCC_5210 tristate "IPQ5210 Global Clock Controller" depends on ARM64 || COMPILE_TEST + default ARCH_QCOM help Support for the global clock controller on ipq5210 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -417,6 +545,7 @@ config IPQ_GCC_5210 config IPQ_GCC_5332 tristate "IPQ5332 Global Clock Controller" depends on ARM64 || COMPILE_TEST + default ARCH_QCOM help Support for the global clock controller on ipq5332 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -425,6 +554,7 @@ config IPQ_GCC_5332 config IPQ_GCC_5424 tristate "IPQ5424 Global Clock Controller" depends on ARM64 || COMPILE_TEST + default ARCH_QCOM help Support for the global clock controller on ipq5424 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -432,6 +562,8 @@ config IPQ_GCC_5424 config IPQ_GCC_6018 tristate "IPQ6018 Global Clock Controller" + depends on ARM64 || COMPILE_TEST + default ARCH_QCOM help Support for global clock controller on ipq6018 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -441,6 +573,7 @@ config IPQ_GCC_6018 config IPQ_GCC_806X tristate "IPQ806x Global Clock Controller" depends on ARM || COMPILE_TEST + default ARCH_QCOM help Support for the global clock controller on ipq806x devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -450,6 +583,7 @@ config IPQ_LCC_806X tristate "IPQ806x LPASS Clock Controller" depends on ARM || COMPILE_TEST select IPQ_GCC_806X + default ARCH_QCOM help Support for the LPASS clock controller on ipq806x devices. Say Y if you want to use audio devices such as i2s, pcm, @@ -457,7 +591,9 @@ config IPQ_LCC_806X config IPQ_GCC_8074 tristate "IPQ8074 Global Clock Controller" + depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for global clock controller on ipq8074 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -466,6 +602,8 @@ config IPQ_GCC_8074 config IPQ_GCC_9574 tristate "IPQ9574 Global Clock Controller" + depends on ARM64 || COMPILE_TEST + default ARCH_QCOM help Support for global clock controller on ipq9574 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -486,6 +624,7 @@ config IPQ_NSSCC_5424 tristate "IPQ5424 NSS Clock Controller" depends on ARM64 || COMPILE_TEST depends on IPQ_GCC_5424 + default m if ARCH_QCOM help Support for NSS clock controller on ipq5424 devices. NSSCC receives the clock sources from GCC, CMN PLL and UNIPHY (PCS). @@ -497,6 +636,7 @@ config IPQ_NSSCC_9574 tristate "IPQ9574 NSS Clock Controller" depends on ARM64 || COMPILE_TEST depends on IPQ_GCC_9574 + default m if ARCH_QCOM help Support for NSS clock controller on ipq9574 devices. @@ -512,6 +652,7 @@ config IPQ_NSSCC_QCA8K config MSM_GCC_8660 tristate "MSM8660 Global Clock Controller" depends on ARM || COMPILE_TEST + default ARCH_QCOM help Support for the global clock controller on msm8660 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -529,6 +670,7 @@ config MSM_GCC_8909 config MSM_GCC_8916 tristate "MSM8916 Global Clock Controller" select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on msm8916 devices. Say Y if you want to use devices such as UART, SPI i2c, USB, @@ -555,6 +697,7 @@ config MSM_GCC_8939 config MSM_GCC_8960 tristate "APQ8064/MSM8960 Global Clock Controller" depends on ARM || COMPILE_TEST + default ARCH_QCOM help Support for the global clock controller on apq8064/msm8960 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -563,6 +706,7 @@ config MSM_GCC_8960 config MSM_LCC_8960 tristate "APQ8064/MSM8960/MDM9650 LPASS Clock Controller" depends on ARM || COMPILE_TEST + default ARCH_QCOM help Support for the LPASS clock controller on apq8064/msm8960/mdm9650 devices. @@ -589,6 +733,7 @@ config MSM_MMCC_8960 tristate "MSM8960 Multimedia Clock Controller" depends on ARM || COMPILE_TEST select MSM_GCC_8960 + default ARCH_QCOM help Support for the multimedia clock controller on msm8960 devices. Say Y if you want to support multimedia devices such as display, @@ -597,6 +742,7 @@ config MSM_MMCC_8960 config MSM_GCC_8953 tristate "MSM8953 Global Clock Controller" select QCOM_GDSC + default ARCH_QCOM if ARM64 help Support for the global clock controller on msm8953 devices. Say Y if you want to use devices such as UART, SPI i2c, USB, @@ -606,6 +752,7 @@ config MSM_GCC_8974 tristate "MSM8974 Global Clock Controller" depends on ARM || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on msm8974 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -616,6 +763,7 @@ config MSM_MMCC_8974 depends on ARM || COMPILE_TEST select MSM_GCC_8974 select QCOM_GDSC + default ARCH_QCOM help Support for the multimedia clock controller on msm8974 devices. Say Y if you want to support multimedia devices such as display, @@ -624,6 +772,7 @@ config MSM_MMCC_8974 config MSM_GCC_8976 tristate "MSM8956/76 Global Clock Controller" select QCOM_GDSC + default ARCH_QCOM if ARM64 help Support for the global clock controller on msm8956/76 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -633,6 +782,7 @@ config MSM_MMCC_8994 tristate "MSM8994 Multimedia Clock Controller" select MSM_GCC_8994 select QCOM_GDSC + default m if ARCH_QCOM && ARM64 help Support for the multimedia clock controller on msm8994 devices. Say Y if you want to support multimedia devices such as display, @@ -640,6 +790,7 @@ config MSM_MMCC_8994 config MSM_GCC_8994 tristate "MSM8994 Global Clock Controller" + default ARCH_QCOM if ARM64 help Support for the global clock controller on msm8994 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -648,6 +799,7 @@ config MSM_GCC_8994 config MSM_GCC_8996 tristate "MSM8996 Global Clock Controller" select QCOM_GDSC + default ARCH_QCOM if ARM64 help Support for the global clock controller on msm8996 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -657,6 +809,7 @@ config MSM_MMCC_8996 tristate "MSM8996 Multimedia Clock Controller" select MSM_GCC_8996 select QCOM_GDSC + default m if ARCH_QCOM && ARM64 help Support for the multimedia clock controller on msm8996 devices. Say Y if you want to support multimedia devices such as display, @@ -665,6 +818,7 @@ config MSM_MMCC_8996 config MSM_GCC_8998 tristate "MSM8998 Global Clock Controller" select QCOM_GDSC + default ARCH_QCOM if ARM64 help Support for the global clock controller on msm8998 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -674,6 +828,7 @@ config MSM_GPUCC_8998 tristate "MSM8998 Graphics Clock Controller" select MSM_GCC_8998 select QCOM_GDSC + default m if ARCH_QCOM && ARM64 help Support for the graphics clock controller on MSM8998 devices. Say Y if you want to support graphics controller devices and @@ -683,6 +838,7 @@ config MSM_MMCC_8998 tristate "MSM8998 Multimedia Clock Controller" select MSM_GCC_8998 select QCOM_GDSC + default m if ARCH_QCOM && ARM64 help Support for the multimedia clock controller on msm8998 devices. Say Y if you want to support multimedia devices such as display, @@ -690,7 +846,9 @@ config MSM_MMCC_8998 config QCM_GCC_2290 tristate "QCM2290 Global Clock Controller" + depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on QCM2290 devices. Say Y if you want to use multimedia devices or peripheral @@ -698,7 +856,9 @@ config QCM_GCC_2290 config QCM_DISPCC_2290 tristate "QCM2290 Display Clock Controller" + depends on ARM64 || COMPILE_TEST select QCM_GCC_2290 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc QCM2290 devices. @@ -709,6 +869,7 @@ config QCS_DISPCC_615 tristate "QCS615 Display Clock Controller" depends on ARM64 || COMPILE_TEST select QCS_GCC_615 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc QCS615 devices. @@ -719,6 +880,7 @@ config QCS_CAMCC_615 tristate "QCS615 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select QCS_GCC_615 + default m if ARCH_QCOM help Support for the camera clock controller on Qualcomm Technologies, Inc QCS615 devices. @@ -727,6 +889,7 @@ config QCS_CAMCC_615 config QCS_GCC_404 tristate "QCS404 Global Clock Controller" + default y if ARCH_QCOM && ARM64 help Support for the global clock controller on QCS404 devices. Say Y if you want to use multimedia devices or peripheral @@ -735,6 +898,7 @@ config QCS_GCC_404 config CLK_NORD_TCSRCC tristate "Nord TCSR Clock Controller" depends on ARM64 || COMPILE_TEST + default m if ARCH_QCOM help Support for the TCSR clock controller on Nord devices. Say Y if you want to use peripheral devices such as PCIe, USB, UFS etc. @@ -743,6 +907,7 @@ config SA_CAMCC_8775P tristate "SA8775P Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SA_GCC_8775P + default m if ARCH_QCOM help Support for the camera clock controller on Qualcomm Technologies, Inc SA8775P devices. @@ -753,6 +918,7 @@ config QCS_GCC_8300 tristate "QCS8300 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on Qualcomm Technologies, Inc QCS8300 devices. @@ -763,6 +929,7 @@ config QCS_GCC_615 tristate "QCS615 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on QCS615 devices. Say Y if you want to use multimedia devices or peripheral @@ -772,6 +939,7 @@ config QCS_GPUCC_615 tristate "QCS615 Graphics clock controller" depends on ARM64 || COMPILE_TEST select QCS_GCC_615 + default m if ARCH_QCOM help Support for the graphics clock controller on QCS615 devices. Say Y if you want to support graphics controller devices and @@ -781,6 +949,7 @@ config QCS_VIDEOCC_615 tristate "QCS615 Video Clock Controller" depends on ARM64 || COMPILE_TEST select QCS_GCC_615 + default m if ARCH_QCOM help Support for the video clock controller on QCS615 devices. Say Y if you want to support video devices and functionality such as @@ -790,6 +959,7 @@ config SC_CAMCC_7180 tristate "SC7180 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_7180 + default m if ARCH_QCOM help Support for the camera clock controller on Qualcomm Technologies, Inc SC7180 devices. @@ -800,6 +970,7 @@ config SC_CAMCC_7280 tristate "SC7280 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_7280 + default m if ARCH_QCOM help Support for the camera clock controller on Qualcomm Technologies, Inc SC7280 devices. @@ -810,6 +981,7 @@ config SC_CAMCC_8180X tristate "SC8180X Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_8180X + default m if ARCH_QCOM help Support for the camera clock controller on Qualcomm Technologies, Inc SC8180X devices. @@ -820,6 +992,7 @@ config SC_CAMCC_8280XP tristate "SC8280XP Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_8280XP + default m if ARCH_QCOM help Support for the camera clock controller on Qualcomm Technologies, Inc SC8280XP devices. @@ -830,6 +1003,7 @@ config SA_DISPCC_8775P tristate "SA8775P Display Clock Controller" depends on ARM64 || COMPILE_TEST select SA_GCC_8775P + default m if ARCH_QCOM help Support for the two display clock controllers on Qualcomm Technologies, Inc. SA8775P devices. @@ -840,6 +1014,7 @@ config SC_DISPCC_7180 tristate "SC7180 Display Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_7180 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SC7180 devices. @@ -850,6 +1025,7 @@ config SC_DISPCC_7280 tristate "SC7280 Display Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_7280 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc. SC7280 devices. @@ -860,6 +1036,7 @@ config SC_DISPCC_8280XP tristate "SC8280XP Display Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_8280XP + default m if ARCH_QCOM help Support for the two display clock controllers on Qualcomm Technologies, Inc. SC8280XP devices. @@ -869,7 +1046,9 @@ config SC_DISPCC_8280XP config SA_GCC_8775P tristate "SA8775 Global Clock Controller" select QCOM_GDSC + depends on ARM64 || COMPILE_TEST depends on COMMON_CLK_QCOM + default ARCH_QCOM help Support for the global clock controller on SA8775 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -877,8 +1056,10 @@ config SA_GCC_8775P config SA_GPUCC_8775P tristate "SA8775P Graphics clock controller" + depends on ARM64 || COMPILE_TEST select QCOM_GDSC select SA_GCC_8775P + default m if ARCH_QCOM help Support for the graphics clock controller on SA8775P devices. Say Y if you want to support graphics controller devices and @@ -907,6 +1088,7 @@ config SC_GCC_7180 select QCOM_GDSC depends on COMMON_CLK_QCOM depends on ARM64 || COMPILE_TEST + default ARCH_QCOM help Support for the global clock controller on SC7180 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -917,6 +1099,7 @@ config SC_GCC_7280 select QCOM_GDSC depends on COMMON_CLK_QCOM depends on ARM64 || COMPILE_TEST + default ARCH_QCOM help Support for the global clock controller on SC7280 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -927,6 +1110,7 @@ config SC_GCC_8180X select QCOM_GDSC depends on COMMON_CLK_QCOM depends on ARM64 || COMPILE_TEST + default ARCH_QCOM help Support for the global clock controller on SC8180X devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -937,6 +1121,7 @@ config SC_GCC_8280XP select QCOM_GDSC depends on COMMON_CLK_QCOM depends on ARM64 || COMPILE_TEST + default ARCH_QCOM help Support for the global clock controller on SC8280XP devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -946,6 +1131,7 @@ config SC_GPUCC_7180 tristate "SC7180 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_7180 + default m if ARCH_QCOM help Support for the graphics clock controller on SC7180 devices. Say Y if you want to support graphics controller devices and @@ -955,6 +1141,7 @@ config SC_GPUCC_7280 tristate "SC7280 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_7280 + default m if ARCH_QCOM help Support for the graphics clock controller on SC7280 devices. Say Y if you want to support graphics controller devices and @@ -964,6 +1151,7 @@ config SC_GPUCC_8280XP tristate "SC8280XP Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_8280XP + default m if ARCH_QCOM help Support for the graphics clock controller on SC8280XP devices. Say Y if you want to support graphics controller devices and @@ -973,6 +1161,7 @@ config SC_LPASSCC_7280 tristate "SC7280 Low Power Audio Subsystem (LPASS) Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_7280 + default m if ARCH_QCOM help Support for the LPASS clock controller on SC7280 devices. Say Y if you want to use the LPASS branch clocks of the LPASS clock @@ -982,6 +1171,7 @@ config SC_LPASSCC_8280XP tristate "SC8280 Low Power Audio Subsystem (LPASS) Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_8280XP + default m if ARCH_QCOM help Support for the LPASS clock controller on SC8280XP devices. Say Y if you want to use the LPASS branch clocks of the LPASS clock @@ -1002,6 +1192,7 @@ config SC_LPASS_CORECC_7280 depends on ARM64 || COMPILE_TEST select SC_GCC_7280 select QCOM_GDSC + default m if ARCH_QCOM help Support for the LPASS(Low Power Audio Subsystem) core and audio clock controller on SC7280 devices. @@ -1012,6 +1203,7 @@ config SC_VIDEOCC_7180 tristate "SC7180 Video Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_7180 + default m if ARCH_QCOM help Support for the video clock controller on SC7180 devices. Say Y if you want to support video devices and functionality such as @@ -1021,6 +1213,7 @@ config SC_VIDEOCC_7280 tristate "SC7280 Video Clock Controller" depends on ARM64 || COMPILE_TEST select SC_GCC_7280 + default m if ARCH_QCOM help Support for the video clock controller on SC7280 devices. Say Y if you want to support video devices and functionality such as @@ -1030,6 +1223,7 @@ config SDM_CAMCC_845 tristate "SDM845 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SDM_GCC_845 + default m if ARCH_QCOM help Support for the camera clock controller on SDM845 devices. Say Y if you want to support camera devices and camera functionality. @@ -1038,6 +1232,7 @@ config SDM_GCC_660 tristate "SDM660 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SDM660 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -1048,6 +1243,7 @@ config SDM_MMCC_660 depends on ARM64 || COMPILE_TEST select SDM_GCC_660 select QCOM_GDSC + default m if ARCH_QCOM help Support for the multimedia clock controller on SDM660 devices. Say Y if you want to support multimedia devices such as display, @@ -1058,6 +1254,7 @@ config SDM_GPUCC_660 depends on ARM64 || COMPILE_TEST select SDM_GCC_660 select QCOM_GDSC + default m if ARCH_QCOM help Support for the graphics clock controller on SDM630/636/660 devices. Say Y if you want to support graphics controller devices and @@ -1079,7 +1276,9 @@ config QCS_Q6SSTOP_404 config QDU_GCC_1000 tristate "QDU1000/QRU1000 Global Clock Controller" + depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on QDU1000 and QRU1000 devices. Say Y if you want to use peripheral @@ -1089,6 +1288,7 @@ config QDU_ECPRICC_1000 tristate "QDU1000/QRU1000 ECPRI Clock Controller" depends on ARM64 || COMPILE_TEST select QDU_GCC_1000 + default m if ARCH_QCOM help Support for the ECPRI clock controller on QDU1000 and QRU1000 devices. Say Y if you want to support the ECPRI @@ -1098,6 +1298,7 @@ config SDM_GCC_845 tristate "SDM845/SDM670 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SDM845 and SDM670 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -1107,6 +1308,7 @@ config SDM_GPUCC_845 tristate "SDM845 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SDM_GCC_845 + default m if ARCH_QCOM help Support for the graphics clock controller on SDM845 devices. Say Y if you want to support graphics controller devices and @@ -1117,6 +1319,7 @@ config SDM_VIDEOCC_845 depends on ARM64 || COMPILE_TEST select SDM_GCC_845 select QCOM_GDSC + default m if ARCH_QCOM help Support for the video clock controller on SDM845 devices. Say Y if you want to support video devices and functionality such as @@ -1126,6 +1329,7 @@ config SDM_DISPCC_845 tristate "SDM845 Display Clock Controller" depends on ARM64 || COMPILE_TEST select SDM_GCC_845 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SDM845 devices. @@ -1136,6 +1340,7 @@ config SDM_LPASSCC_845 tristate "SDM845 Low Power Audio Subsystem (LPAAS) Clock Controller" depends on ARM64 || COMPILE_TEST select SDM_GCC_845 + default m if ARCH_QCOM help Support for the LPASS clock controller on SDM845 devices. Say Y if you want to use the LPASS branch clocks of the LPASS clock @@ -1145,6 +1350,7 @@ config SDX_GCC_55 tristate "SDX55 Global Clock Controller" depends on ARM || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SDX55 devices. Say Y if you want to use peripheral devices such as UART, @@ -1162,6 +1368,7 @@ config SDX_GCC_65 config SDX_GCC_75 tristate "SDX75 Global Clock Controller" select QCOM_GDSC + default ARCH_QCOM if ARM64 help Support for the global clock controller on SDX75 devices. Say Y if you want to use peripheral devices such as UART, @@ -1171,6 +1378,7 @@ config SM_CAMCC_4450 tristate "SM4450 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_4450 + default m if ARCH_QCOM help Support for the camera clock controller on SM4450 devices. Say Y if you want to support camera devices and camera functionality. @@ -1179,6 +1387,7 @@ config SM_CAMCC_6350 tristate "SM6350 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_6350 + default m if ARCH_QCOM help Support for the camera clock controller on SM6350 devices. Say Y if you want to support camera devices and camera functionality. @@ -1187,6 +1396,7 @@ config SM_CAMCC_7150 tristate "SM7150 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_7150 + default m if ARCH_QCOM help Support for the camera clock controller on SM7150 devices. Say Y if you want to support camera devices and camera functionality. @@ -1195,6 +1405,7 @@ config SM_CAMCC_MILOS tristate "Milos Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_MILOS + default m if ARCH_QCOM help Support for the camera clock controller on Milos devices. Say Y if you want to support camera devices and camera functionality. @@ -1203,6 +1414,7 @@ config SM_CAMCC_8150 tristate "SM8150 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8150 + default m if ARCH_QCOM help Support for the camera clock controller on Qualcomm Technologies, Inc SM8150 devices. @@ -1213,6 +1425,7 @@ config SM_CAMCC_8250 tristate "SM8250 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8250 + default m if ARCH_QCOM help Support for the camera clock controller on SM8250 devices. Say Y if you want to support camera devices and camera functionality. @@ -1221,6 +1434,7 @@ config SM_CAMCC_8450 tristate "SM8450 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8450 + default m if ARCH_QCOM help Support for the camera clock controller on SM8450 or SM8475 devices. Say Y if you want to support camera devices and camera functionality. @@ -1229,6 +1443,7 @@ config SM_CAMCC_8550 tristate "SM8550 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8550 + default m if ARCH_QCOM help Support for the camera clock controller on SM8550 devices. Say Y if you want to support camera devices and camera functionality. @@ -1237,6 +1452,7 @@ config SM_CAMCC_8650 tristate "SM8650 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8650 + default m if ARCH_QCOM help Support for the camera clock controller on SM8650 devices. Say Y if you want to support camera devices and camera functionality. @@ -1245,6 +1461,7 @@ config SM_CAMCC_8750 tristate "SM8750 Camera Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8750 + default m if ARCH_QCOM help Support for the camera clock controller on SM8750 devices. The camera clock controller has a separate cambist controller which @@ -1255,6 +1472,7 @@ config SM_DISPCC_4450 tristate "SM4450 Display Clock Controller" depends on ARM64 || COMPILE_TEST depends on SM_GCC_4450 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SM4450 devices. @@ -1265,6 +1483,7 @@ config SM_DISPCC_6115 tristate "SM6115 Display Clock Controller" depends on ARM64 || COMPILE_TEST depends on SM_GCC_6115 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SM6115/SM4250 devices. @@ -1275,6 +1494,7 @@ config SM_DISPCC_6125 tristate "SM6125 Display Clock Controller" depends on ARM64 || COMPILE_TEST depends on SM_GCC_6125 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SM6125 devices. @@ -1285,6 +1505,7 @@ config SM_DISPCC_7150 tristate "SM7150 Display Clock Controller" depends on ARM64 || COMPILE_TEST depends on SM_GCC_7150 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SM7150 devices. @@ -1295,6 +1516,7 @@ config SM_DISPCC_8250 tristate "SM8150/SM8250/SM8350 Display Clock Controller" depends on ARM64 || COMPILE_TEST depends on SM_GCC_8150 || SM_GCC_8250 || SM_GCC_8350 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SM8150/SM8250/SM8350 devices. @@ -1305,6 +1527,7 @@ config SM_DISPCC_6350 tristate "SM6350 Display Clock Controller" depends on ARM64 || COMPILE_TEST depends on SM_GCC_6350 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SM6350 devices. @@ -1315,6 +1538,7 @@ config SM_DISPCC_6375 tristate "SM6375 Display Clock Controller" depends on ARM64 || COMPILE_TEST depends on SM_GCC_6375 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SM6375 devices. @@ -1325,6 +1549,7 @@ config SM_DISPCC_MILOS tristate "Milos Display Clock Controller" depends on ARM64 || COMPILE_TEST depends on SM_GCC_MILOS + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc Milos devices. @@ -1335,6 +1560,7 @@ config SM_DISPCC_8450 tristate "SM8450 Display Clock Controller" depends on ARM64 || COMPILE_TEST depends on SM_GCC_8450 + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SM8450 or SM8475 devices. @@ -1345,6 +1571,7 @@ config SM_DISPCC_8550 tristate "SM8550 Display Clock Controller" depends on ARM64 || COMPILE_TEST depends on SM_GCC_8550 || SM_GCC_8650 || SAR_GCC_2130P + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SAR2130P, SM8550 or SM8650 devices. @@ -1356,6 +1583,7 @@ config SM_DISPCC_8750 depends on ARM64 || COMPILE_TEST depends on SM_GCC_8750 select QCOM_GDSC + default m if ARCH_QCOM help Support for the display clock controller on Qualcomm Technologies, Inc SM8750 devices. @@ -1366,6 +1594,7 @@ config SM_GCC_4450 tristate "SM4450 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM4450 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -1375,6 +1604,7 @@ config SM_GCC_6115 tristate "SM6115 and SM4250 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM6115 and SM4250 devices. Say Y if you want to use peripheral devices such as UART, SPI, @@ -1384,6 +1614,7 @@ config SM_GCC_6125 tristate "SM6125 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM6125 devices. Say Y if you want to use peripheral devices such as UART, @@ -1393,6 +1624,7 @@ config SM_GCC_6350 tristate "SM6350 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM6350 devices. Say Y if you want to use peripheral devices such as UART, @@ -1402,6 +1634,7 @@ config SM_GCC_6375 tristate "SM6375 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM6375 devices. Say Y if you want to use peripheral devices such as UART, @@ -1411,6 +1644,7 @@ config SM_GCC_7150 tristate "SM7150 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM7150 devices. Say Y if you want to use peripheral devices such as UART, @@ -1420,6 +1654,7 @@ config SM_GCC_MILOS tristate "Milos Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on Milos devices. Say Y if you want to use peripheral devices such as UART, @@ -1429,6 +1664,7 @@ config SM_GCC_8150 tristate "SM8150 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM8150 devices. Say Y if you want to use peripheral devices such as UART, @@ -1438,6 +1674,7 @@ config SM_GCC_8250 tristate "SM8250 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM8250 devices. Say Y if you want to use peripheral devices such as UART, @@ -1447,6 +1684,7 @@ config SM_GCC_8350 tristate "SM8350 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM8350 devices. Say Y if you want to use peripheral devices such as UART, @@ -1456,6 +1694,7 @@ config SM_GCC_8450 tristate "SM8450 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM8450 or SM8475 devices. @@ -1466,6 +1705,7 @@ config SM_GCC_8550 tristate "SM8550 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM8550 devices. Say Y if you want to use peripheral devices such as UART, @@ -1475,6 +1715,7 @@ config SM_GCC_8650 tristate "SM8650 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM8650 devices. Say Y if you want to use peripheral devices such as UART, @@ -1484,6 +1725,7 @@ config SM_GCC_8750 tristate "SM8750 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the global clock controller on SM8750 devices. Say Y if you want to use peripheral devices such as UART, @@ -1493,6 +1735,7 @@ config SM_GPUCC_4450 tristate "SM4450 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_4450 + default m if ARCH_QCOM help Support for the graphics clock controller on SM4450 devices. Say Y if you want to support graphics controller devices and @@ -1502,6 +1745,7 @@ config SM_GPUCC_6115 tristate "SM6115 Graphics Clock Controller" select SM_GCC_6115 depends on ARM64 || COMPILE_TEST + default m if ARCH_QCOM help Support for the graphics clock controller on SM6115 devices. Say Y if you want to support graphics controller devices and @@ -1511,6 +1755,7 @@ config SM_GPUCC_6125 tristate "SM6125 Graphics Clock Controller" select SM_GCC_6125 depends on ARM64 || COMPILE_TEST + default m if ARCH_QCOM help Support for the graphics clock controller on SM6125 devices. Say Y if you want to support graphics controller devices and @@ -1520,6 +1765,7 @@ config SM_GPUCC_6375 tristate "SM6375 Graphics Clock Controller" select SM_GCC_6375 depends on ARM64 || COMPILE_TEST + default m if ARCH_QCOM help Support for the graphics clock controller on SM6375 devices. Say Y if you want to support graphics controller devices and @@ -1529,6 +1775,7 @@ config SM_GPUCC_6350 tristate "SM6350 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_6350 + default m if ARCH_QCOM help Support for the graphics clock controller on SM6350 devices. Say Y if you want to support graphics controller devices and @@ -1538,6 +1785,7 @@ config SM_GPUCC_MILOS tristate "Milos Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_MILOS + default m if ARCH_QCOM help Support for the graphics clock controller on Milos devices. Say Y if you want to support graphics controller devices and @@ -1547,6 +1795,7 @@ config SM_GPUCC_8150 tristate "SM8150 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8150 + default m if ARCH_QCOM help Support for the graphics clock controller on SM8150 devices. Say Y if you want to support graphics controller devices and @@ -1556,6 +1805,7 @@ config SM_GPUCC_8250 tristate "SM8250 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8250 + default m if ARCH_QCOM help Support for the graphics clock controller on SM8250 devices. Say Y if you want to support graphics controller devices and @@ -1565,6 +1815,7 @@ config SM_GPUCC_8350 tristate "SM8350 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8350 + default m if ARCH_QCOM help Support for the graphics clock controller on SM8350 devices. Say Y if you want to support graphics controller devices and @@ -1574,6 +1825,7 @@ config SM_GPUCC_8450 tristate "SM8450 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8450 + default m if ARCH_QCOM help Support for the graphics clock controller on SM8450 or SM8475 devices. @@ -1584,6 +1836,7 @@ config SM_GPUCC_8550 tristate "SM8550 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8550 + default m if ARCH_QCOM help Support for the graphics clock controller on SM8550 devices. Say Y if you want to support graphics controller devices and @@ -1593,6 +1846,7 @@ config SM_GPUCC_8650 tristate "SM8650 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8650 + default m if ARCH_QCOM help Support for the graphics clock controller on SM8650 devices. Say Y if you want to support graphics controller devices and @@ -1602,6 +1856,7 @@ config SM_GPUCC_8750 tristate "SM8750 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_8750 + default m if ARCH_QCOM help Support for the graphics clock controller on SM8750 devices. Say Y if you want to support graphics controller devices and @@ -1611,6 +1866,7 @@ config SM_LPASSCC_6115 tristate "SM6115 Low Power Audio Subsystem (LPASS) Clock Controller" depends on ARM64 || COMPILE_TEST select SM_GCC_6115 + default m if ARCH_QCOM help Support for the LPASS clock controller on SM6115 devices. Say Y if you want to toggle LPASS-adjacent resets within @@ -1620,6 +1876,7 @@ config SM_TCSRCC_8550 tristate "SM8550 TCSR Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the TCSR clock controller on SM8550 devices. Say Y if you want to use peripheral devices such as SD/UFS. @@ -1628,6 +1885,7 @@ config SM_TCSRCC_8650 tristate "SM8650 TCSR Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default ARCH_QCOM help Support for the TCSR clock controller on SM8650 devices. Say Y if you want to use peripheral devices such as SD/UFS. @@ -1636,6 +1894,7 @@ config SM_TCSRCC_8750 tristate "SM8750 TCSR Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default m if ARCH_QCOM help Support for the TCSR clock controller on SM8750 devices. Say Y if you want to use peripheral devices such as UFS/USB/PCIe. @@ -1645,6 +1904,7 @@ config SA_VIDEOCC_8775P depends on ARM64 || COMPILE_TEST select SA_GCC_8775P select QCOM_GDSC + default m if ARCH_QCOM help Support for the video clock controller on Qualcomm Technologies, Inc. SA8775P devices. @@ -1656,6 +1916,7 @@ config SM_VIDEOCC_6350 depends on ARM64 || COMPILE_TEST select SM_GCC_6350 select QCOM_GDSC + default m if ARCH_QCOM help Support for the video clock controller on SM6350 devices. Say Y if you want to support video devices and functionality such as @@ -1666,6 +1927,7 @@ config SM_VIDEOCC_7150 depends on ARM64 || COMPILE_TEST select SM_GCC_7150 select QCOM_GDSC + default m if ARCH_QCOM help Support for the video clock controller on SM7150 devices. Say Y if you want to support video devices and functionality such as @@ -1676,6 +1938,7 @@ config SM_VIDEOCC_MILOS depends on ARM64 || COMPILE_TEST select SM_GCC_MILOS select QCOM_GDSC + default m if ARCH_QCOM help Support for the video clock controller on Qualcomm Technologies, Inc. Milos devices. @@ -1687,6 +1950,7 @@ config SM_VIDEOCC_8150 depends on ARM64 || COMPILE_TEST select SM_GCC_8150 select QCOM_GDSC + default m if ARCH_QCOM help Support for the video clock controller on SM8150 devices. Say Y if you want to support video devices and functionality such as @@ -1697,6 +1961,7 @@ config SM_VIDEOCC_8250 depends on ARM64 || COMPILE_TEST select SM_GCC_8250 select QCOM_GDSC + default m if ARCH_QCOM help Support for the video clock controller on SM8250 devices. Say Y if you want to support video devices and functionality such as @@ -1707,6 +1972,7 @@ config SM_VIDEOCC_8350 depends on ARM64 || COMPILE_TEST depends on SM_GCC_8350 || SC_GCC_8280XP select QCOM_GDSC + default m if ARCH_QCOM help Support for the video clock controller on SM8350 or SC8280XP devices. Say Y if you want to support video devices and functionality such as @@ -1716,6 +1982,7 @@ config SM_VIDEOCC_8550 tristate "SM8550 Video Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC + default m if ARCH_QCOM help Support for the video clock controller on Qualcomm Technologies, Inc. SM8550 or SM8650 or X1E80100 devices. @@ -1727,6 +1994,7 @@ config SM_VIDEOCC_8750 depends on ARM64 || COMPILE_TEST select SM_GCC_8750 select QCOM_GDSC + default m if ARCH_QCOM help Support for the video clock controller on Qualcomm Technologies, Inc. SM8750 devices. @@ -1767,6 +2035,7 @@ config KRAITCC config CLK_GFM_LPASS_SM8250 tristate "SM8250 GFM LPASS Clocks" depends on ARM64 || COMPILE_TEST + default m if ARCH_QCOM help Support for the Glitch Free Mux (GFM) Low power audio subsystem (LPASS) clocks found on SM8250 SoCs. @@ -1776,6 +2045,7 @@ config SM_VIDEOCC_8450 depends on ARM64 || COMPILE_TEST select SM_GCC_8450 select QCOM_GDSC + default m if ARCH_QCOM help Support for the video clock controller on Qualcomm Technologies, Inc. SM8450 or SM8475 devices. diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 58f9a5eb6fd7..daf25d583be2 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -8,6 +8,7 @@ clk-qcom-y += clk-pll.o clk-qcom-y += clk-rcg.o clk-qcom-y += clk-rcg2.o clk-qcom-y += clk-branch.o +clk-qcom-y += clk-ref.o clk-qcom-y += clk-regmap-divider.o clk-qcom-y += clk-regmap-mux.o clk-qcom-y += clk-regmap-mux-div.o @@ -24,21 +25,29 @@ obj-$(CONFIG_CLK_ELIZA_DISPCC) += dispcc-eliza.o obj-$(CONFIG_CLK_ELIZA_GCC) += gcc-eliza.o obj-$(CONFIG_CLK_ELIZA_TCSRCC) += tcsrcc-eliza.o obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o +obj-$(CONFIG_CLK_GLYMUR_CAMCC) += camcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_DISPCC) += dispcc-glymur.o +obj-$(CONFIG_CLK_GLYMUR_EVACC) += evacc-glymur.o obj-$(CONFIG_CLK_GLYMUR_GCC) += gcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_GPUCC) += gpucc-glymur.o gxclkctl-kaanapali.o obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_VIDEOCC) += videocc-glymur.o obj-$(CONFIG_CLK_HAWI_GCC) += gcc-hawi.o obj-$(CONFIG_CLK_HAWI_TCSRCC) += tcsrcc-hawi.o +obj-$(CONFIG_CLK_HAWI_VIDEOCC) += videocc-hawi.o obj-$(CONFIG_CLK_KAANAPALI_CAMCC) += cambistmclkcc-kaanapali.o camcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_DISPCC) += dispcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_GPUCC) += gpucc-kaanapali.o gxclkctl-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o +obj-$(CONFIG_CLK_MAILI_VIDEOCC) += videocc-maili.o +obj-$(CONFIG_CLK_NORD_DISPCC) += dispcc0-nord.o dispcc1-nord.o obj-$(CONFIG_CLK_NORD_GCC) += gcc-nord.o negcc-nord.o nwgcc-nord.o segcc-nord.o +obj-$(CONFIG_CLK_NORD_GPUCC) += gpucc-nord.o gpu2cc-nord.o obj-$(CONFIG_CLK_NORD_TCSRCC) += tcsrcc-nord.o +obj-$(CONFIG_CLK_SHIKRA_AUDIOCORECC) += audiocorecc-shikra.o +obj-$(CONFIG_CLK_SHIKRA_GCC) += gcc-shikra.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o diff --git a/drivers/clk/qcom/apss-ipq-pll.c b/drivers/clk/qcom/apss-ipq-pll.c index 3a8987fe7008..5653bb5e93f7 100644 --- a/drivers/clk/qcom/apss-ipq-pll.c +++ b/drivers/clk/qcom/apss-ipq-pll.c @@ -79,6 +79,18 @@ static const struct alpha_pll_config ipq5018_pll_config = { .test_ctl_hi_val = 0x00400003, }; +static const struct alpha_pll_config ipq5210_pll_config = { + .l = 0x22, + .config_ctl_val = 0x4001075b, + .config_ctl_hi_val = 0x6, + .early_output_mask = BIT(3), + .aux2_output_mask = BIT(2), + .aux_output_mask = BIT(1), + .main_output_mask = BIT(0), + .test_ctl_val = 0x0, + .test_ctl_hi_val = 0x400003, +}; + /* 1.080 GHz configuration */ static const struct alpha_pll_config ipq5332_pll_config = { .l = 0x2d, @@ -140,6 +152,12 @@ static const struct apss_pll_data ipq5018_pll_data = { .pll_config = &ipq5018_pll_config, }; +static const struct apss_pll_data ipq5210_pll_data = { + .pll_type = CLK_ALPHA_PLL_TYPE_HUAYRA, + .pll = &ipq_pll_huayra, + .pll_config = &ipq5210_pll_config, +}; + static const struct apss_pll_data ipq5332_pll_data = { .pll_type = CLK_ALPHA_PLL_TYPE_STROMER_PLUS, .pll = &ipq_pll_stromer_plus, @@ -207,6 +225,7 @@ static int apss_ipq_pll_probe(struct platform_device *pdev) static const struct of_device_id apss_ipq_pll_match_table[] = { { .compatible = "qcom,ipq5018-a53pll", .data = &ipq5018_pll_data }, + { .compatible = "qcom,ipq5210-a53pll", .data = &ipq5210_pll_data }, { .compatible = "qcom,ipq5332-a53pll", .data = &ipq5332_pll_data }, { .compatible = "qcom,ipq6018-a53pll", .data = &ipq6018_pll_data }, { .compatible = "qcom,ipq8074-a53pll", .data = &ipq8074_pll_data }, diff --git a/drivers/clk/qcom/audiocorecc-shikra.c b/drivers/clk/qcom/audiocorecc-shikra.c new file mode 100644 index 000000000000..19f67b50d623 --- /dev/null +++ b/drivers/clk/qcom/audiocorecc-shikra.c @@ -0,0 +1,810 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_SLEEP_CLK, + DT_AUD_REF_CLK_SRC, +}; + +enum { + P_AUD_REF_CLK_SRC, + P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, + P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, + P_BI_TCXO, + P_SLEEP_CLK, +}; + +static const struct pll_vco spark_vco[] = { + { 500000000, 1000000000, 2 }, +}; + +/* 614.4 MHz Configuration */ +static const struct alpha_pll_config audio_core_cc_dig_pll_config = { + .l = 0x20, + .alpha = 0x0, + .vco_val = BIT(21), + .post_div_val = 0x28100, + .post_div_mask = GENMASK(17, 8), + .vco_mask = GENMASK(21, 20), + .main_output_mask = BIT(0), + .aux_output_mask = BIT(1), + .aux2_output_mask = BIT(2), + .config_ctl_val = 0x4001055b, + .test_ctl_hi_val = 0x1, + .test_ctl_hi_mask = 0x1, +}; + +static struct clk_alpha_pll audio_core_cc_dig_pll = { + .offset = 0x0, + .config = &audio_core_cc_dig_pll_config, + .vco_table = spark_vco, + .num_vco = ARRAY_SIZE(spark_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_dig_pll", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static struct clk_fixed_factor audio_core_cc_dig_pll_out_aux = { + .mult = 1, + .div = 5, + .hw.init = &(struct clk_init_data) { + .name = "audio_core_cc_dig_pll_out_aux", + .parent_data = &(const struct clk_parent_data) { + .hw = &audio_core_cc_dig_pll.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_fixed_factor audio_core_cc_dig_pll_out_aux2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data) { + .name = "audio_core_cc_dig_pll_out_aux2", + .parent_data = &(const struct clk_parent_data) { + .hw = &audio_core_cc_dig_pll.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, +}; + +static const struct parent_map audio_core_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_AUD_REF_CLK_SRC, 1 }, + { P_SLEEP_CLK, 2 }, + { P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 4 }, + { P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 6 }, +}; + +static const struct clk_parent_data audio_core_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .index = DT_AUD_REF_CLK_SRC }, + { .index = DT_SLEEP_CLK }, + { .hw = &audio_core_cc_dig_pll_out_aux.hw }, + { .hw = &audio_core_cc_dig_pll_out_aux2.hw }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_aif_if0_clk_src[] = { + F(240000, P_BI_TCXO, 10, 1, 8), + F(256000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 32), + F(512000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 16), + F(768000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 16), + F(1024000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 8), + F(1536000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 8), + F(2048000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 4), + F(3072000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 4), + F(4096000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 2), + F(6144000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 2), + F(8192000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 0, 0), + F(9600000, P_BI_TCXO, 2, 0, 0), + F(12288000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24576000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 5, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_aif_if0_clk_src = { + .cmd_rcgr = 0x104c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if0_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 audio_core_cc_aif_if1_clk_src = { + .cmd_rcgr = 0x10b0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if1_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 audio_core_cc_aif_if2_clk_src = { + .cmd_rcgr = 0x1114, + .mnd_width = 16, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if2_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_aif_if3_clk_src[] = { + F(240000, P_BI_TCXO, 10, 1, 8), + F(256000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 32), + F(512000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 16), + F(768000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 16), + F(1024000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 8), + F(1536000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 8), + F(2048000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 4), + F(3072000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 4), + F(4096000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 2), + F(6144000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 2), + F(8192000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 0, 0), + F(9600000, P_BI_TCXO, 2, 0, 0), + F(12288000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24576000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 5, 0, 0), + F(49152000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_aif_if3_clk_src = { + .cmd_rcgr = 0x1178, + .mnd_width = 16, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if3_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if3_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_aud_dma_clk_src[] = { + F(38400000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 8, 0, 0), + F(102400000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 3, 0, 0), + F(153600000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 2, 0, 0), + F(307200000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 1, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_aud_dma_clk_src = { + .cmd_rcgr = 0x1028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aud_dma_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aud_dma_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_bus_clk_src[] = { + F(38400000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 8, 0, 0), + F(76800000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 4, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_bus_clk_src = { + .cmd_rcgr = 0x1008, + .mnd_width = 0, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_bus_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_bus_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 audio_core_cc_ext_mclka_clk_src = { + .cmd_rcgr = 0x123c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_ext_mclka_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 audio_core_cc_ext_mclkb_clk_src = { + .cmd_rcgr = 0x125c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_ext_mclkb_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_lpaif_pcmoe_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(15360000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 8, 0, 0), + F(30720000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 4, 0, 0), + F(61440000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 2, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_lpaif_pcmoe_clk_src = { + .cmd_rcgr = 0x12ac, + .mnd_width = 8, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_lpaif_pcmoe_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_lpaif_pcmoe_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_tx_mclk_rcg_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24576000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 5, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_tx_mclk_rcg_clk_src = { + .cmd_rcgr = 0x127c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_tx_mclk_rcg_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_tx_mclk_rcg_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div audio_core_cc_cdiv_tx_mclk_div_clk_src = { + .reg = 0x129c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_cdiv_tx_mclk_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_tx_mclk_rcg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch audio_core_cc_aif_if0_ebit_clk = { + .halt_reg = 0x1068, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if0_ebit_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if0_ibit_clk = { + .halt_reg = 0x1064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if0_ibit_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aif_if0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if1_ebit_clk = { + .halt_reg = 0x10cc, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x10cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if1_ebit_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if1_ibit_clk = { + .halt_reg = 0x10c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if1_ibit_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aif_if1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if2_ebit_clk = { + .halt_reg = 0x1130, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1130, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if2_ebit_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if2_ibit_clk = { + .halt_reg = 0x112c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x112c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if2_ibit_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aif_if2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if3_ebit_clk = { + .halt_reg = 0x1194, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1194, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if3_ebit_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if3_ibit_clk = { + .halt_reg = 0x1190, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1190, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if3_ibit_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aif_if3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aud_dma_clk = { + .halt_reg = 0x1040, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aud_dma_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aud_dma_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aud_dma_mem_clk = { + .halt_reg = 0x1044, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aud_dma_mem_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aud_dma_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_bus_clk = { + .halt_reg = 0x1020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_bus_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_bus_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_ext_mclka_out_clk = { + .halt_reg = 0x1254, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1254, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_ext_mclka_out_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_ext_mclka_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_ext_mclkb_out_clk = { + .halt_reg = 0x1274, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1274, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_ext_mclkb_out_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_ext_mclkb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_im_sleep_clk = { + .halt_reg = 0x12cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_im_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_lpaif_pcmoe_clk = { + .halt_reg = 0x12c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_lpaif_pcmoe_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_lpaif_pcmoe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_rx_mclk_2x_clk = { + .halt_reg = 0x1298, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1298, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_rx_mclk_2x_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_tx_mclk_rcg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_rx_mclk_clk = { + .halt_reg = 0x12a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_rx_mclk_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_cdiv_tx_mclk_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_sampling_clk = { + .halt_reg = 0x1000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_sampling_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_tx_mclk_2x_clk = { + .halt_reg = 0x1294, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1294, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_tx_mclk_2x_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_tx_mclk_rcg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_tx_mclk_clk = { + .halt_reg = 0x12a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_tx_mclk_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_cdiv_tx_mclk_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_hw *audio_core_cc_shikra_hws[] = { + [AUDIO_CORE_CC_DIG_PLL_OUT_AUX] = &audio_core_cc_dig_pll_out_aux.hw, + [AUDIO_CORE_CC_DIG_PLL_OUT_AUX2] = &audio_core_cc_dig_pll_out_aux2.hw, +}; + +static struct clk_regmap *audio_core_cc_shikra_clocks[] = { + [AUDIO_CORE_CC_AIF_IF0_CLK_SRC] = &audio_core_cc_aif_if0_clk_src.clkr, + [AUDIO_CORE_CC_AIF_IF0_EBIT_CLK] = &audio_core_cc_aif_if0_ebit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF0_IBIT_CLK] = &audio_core_cc_aif_if0_ibit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF1_CLK_SRC] = &audio_core_cc_aif_if1_clk_src.clkr, + [AUDIO_CORE_CC_AIF_IF1_EBIT_CLK] = &audio_core_cc_aif_if1_ebit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF1_IBIT_CLK] = &audio_core_cc_aif_if1_ibit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF2_CLK_SRC] = &audio_core_cc_aif_if2_clk_src.clkr, + [AUDIO_CORE_CC_AIF_IF2_EBIT_CLK] = &audio_core_cc_aif_if2_ebit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF2_IBIT_CLK] = &audio_core_cc_aif_if2_ibit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF3_CLK_SRC] = &audio_core_cc_aif_if3_clk_src.clkr, + [AUDIO_CORE_CC_AIF_IF3_EBIT_CLK] = &audio_core_cc_aif_if3_ebit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF3_IBIT_CLK] = &audio_core_cc_aif_if3_ibit_clk.clkr, + [AUDIO_CORE_CC_AUD_DMA_CLK] = &audio_core_cc_aud_dma_clk.clkr, + [AUDIO_CORE_CC_AUD_DMA_CLK_SRC] = &audio_core_cc_aud_dma_clk_src.clkr, + [AUDIO_CORE_CC_AUD_DMA_MEM_CLK] = &audio_core_cc_aud_dma_mem_clk.clkr, + [AUDIO_CORE_CC_BUS_CLK] = &audio_core_cc_bus_clk.clkr, + [AUDIO_CORE_CC_BUS_CLK_SRC] = &audio_core_cc_bus_clk_src.clkr, + [AUDIO_CORE_CC_CDIV_TX_MCLK_DIV_CLK_SRC] = &audio_core_cc_cdiv_tx_mclk_div_clk_src.clkr, + [AUDIO_CORE_CC_DIG_PLL] = &audio_core_cc_dig_pll.clkr, + [AUDIO_CORE_CC_EXT_MCLKA_CLK_SRC] = &audio_core_cc_ext_mclka_clk_src.clkr, + [AUDIO_CORE_CC_EXT_MCLKA_OUT_CLK] = &audio_core_cc_ext_mclka_out_clk.clkr, + [AUDIO_CORE_CC_EXT_MCLKB_CLK_SRC] = &audio_core_cc_ext_mclkb_clk_src.clkr, + [AUDIO_CORE_CC_EXT_MCLKB_OUT_CLK] = &audio_core_cc_ext_mclkb_out_clk.clkr, + [AUDIO_CORE_CC_IM_SLEEP_CLK] = &audio_core_cc_im_sleep_clk.clkr, + [AUDIO_CORE_CC_LPAIF_PCMOE_CLK] = &audio_core_cc_lpaif_pcmoe_clk.clkr, + [AUDIO_CORE_CC_LPAIF_PCMOE_CLK_SRC] = &audio_core_cc_lpaif_pcmoe_clk_src.clkr, + [AUDIO_CORE_CC_RX_MCLK_2X_CLK] = &audio_core_cc_rx_mclk_2x_clk.clkr, + [AUDIO_CORE_CC_RX_MCLK_CLK] = &audio_core_cc_rx_mclk_clk.clkr, + [AUDIO_CORE_CC_SAMPLING_CLK] = &audio_core_cc_sampling_clk.clkr, + [AUDIO_CORE_CC_TX_MCLK_2X_CLK] = &audio_core_cc_tx_mclk_2x_clk.clkr, + [AUDIO_CORE_CC_TX_MCLK_CLK] = &audio_core_cc_tx_mclk_clk.clkr, + [AUDIO_CORE_CC_TX_MCLK_RCG_CLK_SRC] = &audio_core_cc_tx_mclk_rcg_clk_src.clkr, +}; + +static struct clk_alpha_pll *audio_core_cc_shikra_plls[] = { + &audio_core_cc_dig_pll, +}; + +static const struct qcom_cc_driver_data audio_core_cc_shikra_driver_data = { + .alpha_plls = audio_core_cc_shikra_plls, + .num_alpha_plls = ARRAY_SIZE(audio_core_cc_shikra_plls), +}; + +static const struct regmap_config audio_core_cc_shikra_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x305c, + .fast_io = true, +}; + +static const struct qcom_reset_map audio_core_csr_shikra_resets[] = { + [AUDIO_CORE_CSR_RX_SWR_CGCR] = { 0x1c, 1 }, + [AUDIO_CORE_CSR_TX_SWR_CGCR] = { 0x30, 1 }, +}; + +static const struct regmap_config audio_core_csr_shikra_regmap_config = { + .name = "audio_core_cc_shikra_reset", + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, + .max_register = 0x34, +}; + +static const struct qcom_cc_desc audio_core_csr_shikra_desc = { + .config = &audio_core_csr_shikra_regmap_config, + .resets = audio_core_csr_shikra_resets, + .num_resets = ARRAY_SIZE(audio_core_csr_shikra_resets), +}; + +static const struct qcom_cc_desc audio_core_cc_shikra_desc = { + .config = &audio_core_cc_shikra_regmap_config, + .clk_hws = audio_core_cc_shikra_hws, + .num_clk_hws = ARRAY_SIZE(audio_core_cc_shikra_hws), + .clks = audio_core_cc_shikra_clocks, + .num_clks = ARRAY_SIZE(audio_core_cc_shikra_clocks), + .driver_data = &audio_core_cc_shikra_driver_data, +}; + +static const struct of_device_id audio_core_cc_shikra_match_table[] = { + { .compatible = "qcom,shikra-audiocorecc", .data = &audio_core_cc_shikra_desc }, + { .compatible = "qcom,shikra-audiocore-csr", .data = &audio_core_csr_shikra_desc }, + { } +}; +MODULE_DEVICE_TABLE(of, audio_core_cc_shikra_match_table); + +static int audio_core_cc_shikra_probe(struct platform_device *pdev) +{ + const struct qcom_cc_desc *desc; + + desc = device_get_match_data(&pdev->dev); + if (!desc) + return -EINVAL; + + return qcom_cc_probe(pdev, desc); +} + +static struct platform_driver audio_core_cc_shikra_driver = { + .probe = audio_core_cc_shikra_probe, + .driver = { + .name = "audiocorecc-shikra", + .of_match_table = audio_core_cc_shikra_match_table, + }, +}; + +module_platform_driver(audio_core_cc_shikra_driver); + +MODULE_DESCRIPTION("QTI AUDIOCORECC Shikra Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-glymur.c b/drivers/clk/qcom/camcc-glymur.c new file mode 100644 index 000000000000..81c1e102b110 --- /dev/null +++ b/drivers/clk/qcom/camcc-glymur.c @@ -0,0 +1,2279 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_IFACE, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_BI_TCXO_AO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL0_OUT_MAIN, + P_CAM_CC_PLL0_OUT_ODD, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL2_OUT_MAIN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CAM_CC_PLL4_OUT_EVEN, + P_CAM_CC_PLL5_OUT_EVEN, + P_SLEEP_CLK, +}; + +static const struct pll_vco rivian_eko_t_vco[] = { + { 883200000, 1171200000, 0 }, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 1200.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .alpha = 0x8000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00008408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .config = &cam_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_odd = { + .offset = 0x0, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll0_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 608.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x1f, + .alpha = 0xaaaa, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .config = &cam_cc_pll1_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll1_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll1_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll1_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll1.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x12000000, + .config_ctl_hi_val = 0x00890263, + .config_ctl_hi1_val = 0x1af04237, + .config_ctl_hi2_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .config = &cam_cc_pll2_config, + .vco_table = rivian_eko_t_vco, + .num_vco = ARRAY_SIZE(rivian_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_rivian_eko_t_ops, + }, + }, +}; + +/* 691.2 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x24, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .config = &cam_cc_pll3_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll3_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = { + .offset = 0x3000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll3_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll3_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll3.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 691.2 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x24, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll4 = { + .offset = 0x4000, + .config = &cam_cc_pll4_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll4_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll4_out_even = { + .offset = 0x4000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll4_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll4_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll4_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll4.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll5_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll5 = { + .offset = 0x5000, + .config = &cam_cc_pll5_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll5", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll5_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll5_out_even = { + .offset = 0x5000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll5_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll5_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll5_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll5.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL5_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll0.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, + { .hw = &cam_cc_pll0_out_odd.clkr.hw }, + { .hw = &cam_cc_pll5_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 3 }, + { P_CAM_CC_PLL2_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll2.clkr.hw }, + { .hw = &cam_cc_pll2.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL3_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll4_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL1_OUT_EVEN, 4 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll1_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_5[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_5[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map cam_cc_parent_map_6_ao[] = { + { P_BI_TCXO_AO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_6_ao[] = { + { .index = DT_BI_TCXO_AO }, +}; + +static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = { + F(160000000, P_CAM_CC_PLL0_OUT_ODD, 2.5, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_bps_clk_src = { + .cmd_rcgr = 0x10278, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_bps_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_axi_rt_clk_src[] = { + F(240000000, P_CAM_CC_PLL0_OUT_EVEN, 2.5, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_camnoc_axi_rt_clk_src = { + .cmd_rcgr = 0x137b4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_camnoc_axi_rt_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_axi_rt_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cci_0_clk_src[] = { + F(30000000, P_CAM_CC_PLL5_OUT_EVEN, 16, 0, 0), + F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .cmd_rcgr = 0x1350c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_0_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_cci_1_clk_src = { + .cmd_rcgr = 0x1363c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_1_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = { + F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { + .cmd_rcgr = 0x11168, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cphy_rx_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = { + F(266666667, P_CAM_CC_PLL0_OUT_ODD, 1.5, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x150e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi0phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { + .cmd_rcgr = 0x15104, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi1phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_csi4phytimer_clk_src = { + .cmd_rcgr = 0x15124, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi4phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_csid_clk_src = { + .cmd_rcgr = 0x1378c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = { + F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { + .cmd_rcgr = 0x10018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_fast_ahb_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_icp_clk_src[] = { + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_clk_src = { + .cmd_rcgr = 0x133cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_icp_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_0_clk_src[] = { + F(345600000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(432000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(594000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(727000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_0_clk_src = { + .cmd_rcgr = 0x11018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_clk_src", + .parent_data = cam_cc_parent_data_2, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_1_clk_src[] = { + F(345600000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(432000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(594000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(727000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_1_clk_src = { + .cmd_rcgr = 0x12018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ife_1_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_clk_src", + .parent_data = cam_cc_parent_data_3, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_lite_clk_src[] = { + F(266666667, P_CAM_CC_PLL0_OUT_ODD, 1.5, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .cmd_rcgr = 0x13000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_lite_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { + .cmd_rcgr = 0x13140, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_lite_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ipe_nps_clk_src[] = { + F(304000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(364000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(500000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(700000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_nps_clk_src = { + .cmd_rcgr = 0x103d0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_4, + .freq_tbl = ftbl_cam_cc_ipe_nps_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_clk_src", + .parent_data = cam_cc_parent_data_4, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_jpeg_clk_src[] = { + F(160000000, P_CAM_CC_PLL0_OUT_ODD, 2.5, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0x13284, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_jpeg_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24000000, P_CAM_CC_PLL2_OUT_MAIN, 10, 1, 4), + F(68571429, P_CAM_CC_PLL2_OUT_MAIN, 14, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_mclk0_clk_src = { + .cmd_rcgr = 0x15000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk0_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_mclk1_clk_src = { + .cmd_rcgr = 0x1501c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk1_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_mclk2_clk_src = { + .cmd_rcgr = 0x15038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk2_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_mclk3_clk_src = { + .cmd_rcgr = 0x15054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk3_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_mclk4_clk_src = { + .cmd_rcgr = 0x15070, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk4_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_mclk5_clk_src = { + .cmd_rcgr = 0x1508c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk5_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_mclk6_clk_src = { + .cmd_rcgr = 0x150a8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk6_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 cam_cc_mclk7_clk_src = { + .cmd_rcgr = 0x150c4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk7_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_qdss_debug_clk_src[] = { + F(60000000, P_CAM_CC_PLL5_OUT_EVEN, 8, 0, 0), + F(75000000, P_CAM_CC_PLL0_OUT_EVEN, 8, 0, 0), + F(150000000, P_CAM_CC_PLL0_OUT_EVEN, 4, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qdss_debug_clk_src = { + .cmd_rcgr = 0x137fc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_qdss_debug_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_sleep_clk_src = { + .cmd_rcgr = 0x13964, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_sleep_clk_src, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sleep_clk_src", + .parent_data = cam_cc_parent_data_5, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = { + F(64000000, P_CAM_CC_PLL5_OUT_EVEN, 7.5, 0, 0), + F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { + .cmd_rcgr = 0x10148, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_slow_ahb_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_xo_clk_src[] = { + F(19200000, P_BI_TCXO_AO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_xo_clk_src = { + .cmd_rcgr = 0x13948, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_6_ao, + .freq_tbl = ftbl_cam_cc_xo_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_xo_clk_src", + .parent_data = cam_cc_parent_data_6_ao, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_6_ao), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_ahb_clk = { + .halt_reg = 0x10274, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10274, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_clk = { + .halt_reg = 0x103a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x103a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_bps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_fast_ahb_clk = { + .halt_reg = 0x10144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_axi_nrt_clk = { + .halt_reg = 0x137e0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x137e0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x137e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_axi_nrt_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_axi_rt_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_axi_rt_clk = { + .halt_reg = 0x137cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x137cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_axi_rt_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_axi_rt_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_dcd_xo_clk = { + .halt_reg = 0x137f0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x137f0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_dcd_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_xo_clk = { + .halt_reg = 0x137f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x137f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_0_clk = { + .halt_reg = 0x13638, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13638, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_1_clk = { + .halt_reg = 0x13768, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13768, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_core_ahb_clk = { + .halt_reg = 0x13944, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x13944, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_core_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ahb_clk = { + .halt_reg = 0x1376c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1376c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_bps_clk = { + .halt_reg = 0x103b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x103b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_bps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_bps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_fast_ahb_clk = { + .halt_reg = 0x1377c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1377c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ife_0_clk = { + .halt_reg = 0x11154, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11154, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ife_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ife_1_clk = { + .halt_reg = 0x12040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ife_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ife_lite_clk = { + .halt_reg = 0x1313c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1313c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ipe_nps_clk = { + .halt_reg = 0x1050c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1050c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ipe_nps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi0phytimer_clk = { + .halt_reg = 0x150f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi0phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi0phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi1phytimer_clk = { + .halt_reg = 0x1511c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1511c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi1phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi1phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi4phytimer_clk = { + .halt_reg = 0x15250, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15250, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi4phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi4phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csid_clk = { + .halt_reg = 0x137a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x137a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csid_csiphy_rx_clk = { + .halt_reg = 0x15100, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15100, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_csiphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy0_clk = { + .halt_reg = 0x150fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy1_clk = { + .halt_reg = 0x15120, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15120, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy4_clk = { + .halt_reg = 0x15254, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15254, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_ahb_clk = { + .halt_reg = 0x13508, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13508, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_clk = { + .halt_reg = 0x134f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x134f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_clk = { + .halt_reg = 0x11144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_dsp_clk = { + .halt_reg = 0x11158, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11158, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_dsp_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_fast_ahb_clk = { + .halt_reg = 0x11164, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11164, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_clk = { + .halt_reg = 0x12030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_dsp_clk = { + .halt_reg = 0x12044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_dsp_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_fast_ahb_clk = { + .halt_reg = 0x12050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_ahb_clk = { + .halt_reg = 0x13280, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13280, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_clk = { + .halt_reg = 0x1312c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1312c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = { + .halt_reg = 0x1327c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1327c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_csid_clk = { + .halt_reg = 0x1326c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1326c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_ahb_clk = { + .halt_reg = 0x10528, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10528, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_clk = { + .halt_reg = 0x104fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x104fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_fast_ahb_clk = { + .halt_reg = 0x1052c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1052c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_pps_clk = { + .halt_reg = 0x10510, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10510, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_pps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_pps_fast_ahb_clk = { + .halt_reg = 0x10530, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10530, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_pps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_jpeg_clk = { + .halt_reg = 0x133b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x133b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_jpeg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk0_clk = { + .halt_reg = 0x15018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk1_clk = { + .halt_reg = 0x15034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk2_clk = { + .halt_reg = 0x15050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk3_clk = { + .halt_reg = 0x1506c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1506c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk4_clk = { + .halt_reg = 0x15088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk5_clk = { + .halt_reg = 0x150a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk6_clk = { + .halt_reg = 0x150c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk6_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk7_clk = { + .halt_reg = 0x150dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk7_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qdss_debug_clk = { + .halt_reg = 0x13928, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13928, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qdss_debug_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qdss_debug_xo_clk = { + .halt_reg = 0x1392c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1392c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc cam_cc_titan_top_gdsc = { + .gdscr = 0x13930, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_titan_top_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_bps_gdsc = { + .gdscr = 0x10004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_bps_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ife_0_gdsc = { + .gdscr = 0x11004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ife_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ife_1_gdsc = { + .gdscr = 0x12004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ife_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ipe_0_gdsc = { + .gdscr = 0x103bc, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *cam_cc_glymur_clocks[] = { + [CAM_CC_BPS_AHB_CLK] = &cam_cc_bps_ahb_clk.clkr, + [CAM_CC_BPS_CLK] = &cam_cc_bps_clk.clkr, + [CAM_CC_BPS_CLK_SRC] = &cam_cc_bps_clk_src.clkr, + [CAM_CC_BPS_FAST_AHB_CLK] = &cam_cc_bps_fast_ahb_clk.clkr, + [CAM_CC_CAMNOC_AXI_NRT_CLK] = &cam_cc_camnoc_axi_nrt_clk.clkr, + [CAM_CC_CAMNOC_AXI_RT_CLK] = &cam_cc_camnoc_axi_rt_clk.clkr, + [CAM_CC_CAMNOC_AXI_RT_CLK_SRC] = &cam_cc_camnoc_axi_rt_clk_src.clkr, + [CAM_CC_CAMNOC_DCD_XO_CLK] = &cam_cc_camnoc_dcd_xo_clk.clkr, + [CAM_CC_CAMNOC_XO_CLK] = &cam_cc_camnoc_xo_clk.clkr, + [CAM_CC_CCI_0_CLK] = &cam_cc_cci_0_clk.clkr, + [CAM_CC_CCI_0_CLK_SRC] = &cam_cc_cci_0_clk_src.clkr, + [CAM_CC_CCI_1_CLK] = &cam_cc_cci_1_clk.clkr, + [CAM_CC_CCI_1_CLK_SRC] = &cam_cc_cci_1_clk_src.clkr, + [CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr, + [CAM_CC_CPAS_AHB_CLK] = &cam_cc_cpas_ahb_clk.clkr, + [CAM_CC_CPAS_BPS_CLK] = &cam_cc_cpas_bps_clk.clkr, + [CAM_CC_CPAS_FAST_AHB_CLK] = &cam_cc_cpas_fast_ahb_clk.clkr, + [CAM_CC_CPAS_IFE_0_CLK] = &cam_cc_cpas_ife_0_clk.clkr, + [CAM_CC_CPAS_IFE_1_CLK] = &cam_cc_cpas_ife_1_clk.clkr, + [CAM_CC_CPAS_IFE_LITE_CLK] = &cam_cc_cpas_ife_lite_clk.clkr, + [CAM_CC_CPAS_IPE_NPS_CLK] = &cam_cc_cpas_ipe_nps_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr, + [CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr, + [CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr, + [CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr, + [CAM_CC_CSI4PHYTIMER_CLK] = &cam_cc_csi4phytimer_clk.clkr, + [CAM_CC_CSI4PHYTIMER_CLK_SRC] = &cam_cc_csi4phytimer_clk_src.clkr, + [CAM_CC_CSID_CLK] = &cam_cc_csid_clk.clkr, + [CAM_CC_CSID_CLK_SRC] = &cam_cc_csid_clk_src.clkr, + [CAM_CC_CSID_CSIPHY_RX_CLK] = &cam_cc_csid_csiphy_rx_clk.clkr, + [CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr, + [CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr, + [CAM_CC_CSIPHY4_CLK] = &cam_cc_csiphy4_clk.clkr, + [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, + [CAM_CC_ICP_AHB_CLK] = &cam_cc_icp_ahb_clk.clkr, + [CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr, + [CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr, + [CAM_CC_IFE_0_CLK] = &cam_cc_ife_0_clk.clkr, + [CAM_CC_IFE_0_CLK_SRC] = &cam_cc_ife_0_clk_src.clkr, + [CAM_CC_IFE_0_DSP_CLK] = &cam_cc_ife_0_dsp_clk.clkr, + [CAM_CC_IFE_0_FAST_AHB_CLK] = &cam_cc_ife_0_fast_ahb_clk.clkr, + [CAM_CC_IFE_1_CLK] = &cam_cc_ife_1_clk.clkr, + [CAM_CC_IFE_1_CLK_SRC] = &cam_cc_ife_1_clk_src.clkr, + [CAM_CC_IFE_1_DSP_CLK] = &cam_cc_ife_1_dsp_clk.clkr, + [CAM_CC_IFE_1_FAST_AHB_CLK] = &cam_cc_ife_1_fast_ahb_clk.clkr, + [CAM_CC_IFE_LITE_AHB_CLK] = &cam_cc_ife_lite_ahb_clk.clkr, + [CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr, + [CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr, + [CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr, + [CAM_CC_IPE_NPS_AHB_CLK] = &cam_cc_ipe_nps_ahb_clk.clkr, + [CAM_CC_IPE_NPS_CLK] = &cam_cc_ipe_nps_clk.clkr, + [CAM_CC_IPE_NPS_CLK_SRC] = &cam_cc_ipe_nps_clk_src.clkr, + [CAM_CC_IPE_NPS_FAST_AHB_CLK] = &cam_cc_ipe_nps_fast_ahb_clk.clkr, + [CAM_CC_IPE_PPS_CLK] = &cam_cc_ipe_pps_clk.clkr, + [CAM_CC_IPE_PPS_FAST_AHB_CLK] = &cam_cc_ipe_pps_fast_ahb_clk.clkr, + [CAM_CC_JPEG_CLK] = &cam_cc_jpeg_clk.clkr, + [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr, + [CAM_CC_MCLK0_CLK] = &cam_cc_mclk0_clk.clkr, + [CAM_CC_MCLK0_CLK_SRC] = &cam_cc_mclk0_clk_src.clkr, + [CAM_CC_MCLK1_CLK] = &cam_cc_mclk1_clk.clkr, + [CAM_CC_MCLK1_CLK_SRC] = &cam_cc_mclk1_clk_src.clkr, + [CAM_CC_MCLK2_CLK] = &cam_cc_mclk2_clk.clkr, + [CAM_CC_MCLK2_CLK_SRC] = &cam_cc_mclk2_clk_src.clkr, + [CAM_CC_MCLK3_CLK] = &cam_cc_mclk3_clk.clkr, + [CAM_CC_MCLK3_CLK_SRC] = &cam_cc_mclk3_clk_src.clkr, + [CAM_CC_MCLK4_CLK] = &cam_cc_mclk4_clk.clkr, + [CAM_CC_MCLK4_CLK_SRC] = &cam_cc_mclk4_clk_src.clkr, + [CAM_CC_MCLK5_CLK] = &cam_cc_mclk5_clk.clkr, + [CAM_CC_MCLK5_CLK_SRC] = &cam_cc_mclk5_clk_src.clkr, + [CAM_CC_MCLK6_CLK] = &cam_cc_mclk6_clk.clkr, + [CAM_CC_MCLK6_CLK_SRC] = &cam_cc_mclk6_clk_src.clkr, + [CAM_CC_MCLK7_CLK] = &cam_cc_mclk7_clk.clkr, + [CAM_CC_MCLK7_CLK_SRC] = &cam_cc_mclk7_clk_src.clkr, + [CAM_CC_PLL0] = &cam_cc_pll0.clkr, + [CAM_CC_PLL0_OUT_EVEN] = &cam_cc_pll0_out_even.clkr, + [CAM_CC_PLL0_OUT_ODD] = &cam_cc_pll0_out_odd.clkr, + [CAM_CC_PLL1] = &cam_cc_pll1.clkr, + [CAM_CC_PLL1_OUT_EVEN] = &cam_cc_pll1_out_even.clkr, + [CAM_CC_PLL2] = &cam_cc_pll2.clkr, + [CAM_CC_PLL3] = &cam_cc_pll3.clkr, + [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr, + [CAM_CC_PLL4] = &cam_cc_pll4.clkr, + [CAM_CC_PLL4_OUT_EVEN] = &cam_cc_pll4_out_even.clkr, + [CAM_CC_PLL5] = &cam_cc_pll5.clkr, + [CAM_CC_PLL5_OUT_EVEN] = &cam_cc_pll5_out_even.clkr, + [CAM_CC_QDSS_DEBUG_CLK] = &cam_cc_qdss_debug_clk.clkr, + [CAM_CC_QDSS_DEBUG_CLK_SRC] = &cam_cc_qdss_debug_clk_src.clkr, + [CAM_CC_QDSS_DEBUG_XO_CLK] = &cam_cc_qdss_debug_xo_clk.clkr, + [CAM_CC_SLEEP_CLK_SRC] = &cam_cc_sleep_clk_src.clkr, + [CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, + [CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr, +}; + +static struct gdsc *cam_cc_glymur_gdscs[] = { + [CAM_CC_BPS_GDSC] = &cam_cc_bps_gdsc, + [CAM_CC_IFE_0_GDSC] = &cam_cc_ife_0_gdsc, + [CAM_CC_IFE_1_GDSC] = &cam_cc_ife_1_gdsc, + [CAM_CC_IPE_0_GDSC] = &cam_cc_ipe_0_gdsc, + [CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc, +}; + +static const struct qcom_reset_map cam_cc_glymur_resets[] = { + [CAM_CC_BPS_BCR] = { 0x10000 }, + [CAM_CC_ICP_BCR] = { 0x133c8 }, + [CAM_CC_IFE_0_BCR] = { 0x11000 }, + [CAM_CC_IFE_1_BCR] = { 0x12000 }, + [CAM_CC_IPE_0_BCR] = { 0x103b8 }, + [CAM_CC_QDSS_DEBUG_BCR] = { 0x137f8 }, +}; + +static struct clk_alpha_pll *cam_cc_glymur_plls[] = { + &cam_cc_pll0, + &cam_cc_pll1, + &cam_cc_pll2, + &cam_cc_pll3, + &cam_cc_pll4, + &cam_cc_pll5, +}; + +static const u32 cam_cc_glymur_critical_cbcrs[] = { + 0x13960, /* CAM_CC_GDSC_CLK */ + 0x1397c, /* CAM_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_cc_glymur_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1603c, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data cam_cc_glymur_driver_data = { + .alpha_plls = cam_cc_glymur_plls, + .num_alpha_plls = ARRAY_SIZE(cam_cc_glymur_plls), + .clk_cbcrs = cam_cc_glymur_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_glymur_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_cc_glymur_desc = { + .config = &cam_cc_glymur_regmap_config, + .clks = cam_cc_glymur_clocks, + .num_clks = ARRAY_SIZE(cam_cc_glymur_clocks), + .resets = cam_cc_glymur_resets, + .num_resets = ARRAY_SIZE(cam_cc_glymur_resets), + .gdscs = cam_cc_glymur_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_glymur_gdscs), + .use_rpm = true, + .driver_data = &cam_cc_glymur_driver_data, +}; + +static const struct of_device_id cam_cc_glymur_match_table[] = { + { .compatible = "qcom,glymur-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_glymur_match_table); + +static int cam_cc_glymur_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_cc_glymur_desc); +} + +static struct platform_driver cam_cc_glymur_driver = { + .probe = cam_cc_glymur_probe, + .driver = { + .name = "camcc-glymur", + .of_match_table = cam_cc_glymur_match_table, + }, +}; + +module_platform_driver(cam_cc_glymur_driver); + +MODULE_DESCRIPTION("QTI CAMCC GLYMUR Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-sc8280xp.c b/drivers/clk/qcom/camcc-sc8280xp.c index e97b8d4f3c84..660d8655d391 100644 --- a/drivers/clk/qcom/camcc-sc8280xp.c +++ b/drivers/clk/qcom/camcc-sc8280xp.c @@ -1753,24 +1753,6 @@ static struct clk_branch camcc_csiphy3_clk = { }, }; -static struct clk_branch camcc_gdsc_clk = { - .halt_reg = 0xc1e4, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xc1e4, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "camcc_gdsc_clk", - .parent_hws = (const struct clk_hw*[]){ - &camcc_xo_clk_src.clkr.hw, - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch camcc_icp_ahb_clk = { .halt_reg = 0xc0d8, .halt_check = BRANCH_HALT, @@ -2839,7 +2821,6 @@ static struct clk_regmap *camcc_sc8280xp_clocks[] = { [CAMCC_CSIPHY2_CLK] = &camcc_csiphy2_clk.clkr, [CAMCC_CSIPHY3_CLK] = &camcc_csiphy3_clk.clkr, [CAMCC_FAST_AHB_CLK_SRC] = &camcc_fast_ahb_clk_src.clkr, - [CAMCC_GDSC_CLK] = &camcc_gdsc_clk.clkr, [CAMCC_ICP_AHB_CLK] = &camcc_icp_ahb_clk.clkr, [CAMCC_ICP_CLK] = &camcc_icp_clk.clkr, [CAMCC_ICP_CLK_SRC] = &camcc_icp_clk_src.clkr, diff --git a/drivers/clk/qcom/camcc-x1p42100.c b/drivers/clk/qcom/camcc-x1p42100.c index cfe24bde4652..e2b8f7bd8974 100644 --- a/drivers/clk/qcom/camcc-x1p42100.c +++ b/drivers/clk/qcom/camcc-x1p42100.c @@ -2165,7 +2165,7 @@ static struct clk_alpha_pll *cam_cc_x1p42100_plls[] = { &cam_cc_pll6, }; -static u32 cam_cc_x1p42100_critical_cbcrs[] = { +static const u32 cam_cc_x1p42100_critical_cbcrs[] = { 0x13a9c, /* CAM_CC_GDSC_CLK */ 0x13ab8, /* CAM_CC_SLEEP_CLK */ }; @@ -2178,14 +2178,14 @@ static const struct regmap_config cam_cc_x1p42100_regmap_config = { .fast_io = true, }; -static struct qcom_cc_driver_data cam_cc_x1p42100_driver_data = { +static const struct qcom_cc_driver_data cam_cc_x1p42100_driver_data = { .alpha_plls = cam_cc_x1p42100_plls, .num_alpha_plls = ARRAY_SIZE(cam_cc_x1p42100_plls), .clk_cbcrs = cam_cc_x1p42100_critical_cbcrs, .num_clk_cbcrs = ARRAY_SIZE(cam_cc_x1p42100_critical_cbcrs), }; -static struct qcom_cc_desc cam_cc_x1p42100_desc = { +static const struct qcom_cc_desc cam_cc_x1p42100_desc = { .config = &cam_cc_x1p42100_regmap_config, .clks = cam_cc_x1p42100_clocks, .num_clks = ARRAY_SIZE(cam_cc_x1p42100_clocks), diff --git a/drivers/clk/qcom/clk-hfpll.c b/drivers/clk/qcom/clk-hfpll.c index 705352aff067..9e9118d24df7 100644 --- a/drivers/clk/qcom/clk-hfpll.c +++ b/drivers/clk/qcom/clk-hfpll.c @@ -166,7 +166,7 @@ static int clk_hfpll_set_rate(struct clk_hw *hw, unsigned long rate, spin_lock_irqsave(&h->lock, flags); - enabled = __clk_is_enabled(hw->clk); + enabled = clk_hw_is_enabled(hw); if (enabled) __clk_hfpll_disable(h); @@ -220,7 +220,7 @@ static int clk_hfpll_init(struct clk_hw *hw) regmap_read(regmap, hd->status_reg, &status); if (!(status & BIT(hd->lock_bit))) { WARN(1, "HFPLL %s is ON, but not locked!\n", - __clk_get_name(hw->clk)); + clk_hw_get_name(hw)); clk_hfpll_disable(hw); __clk_hfpll_init_once(hw); } diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c index f5ce403e1e27..5e4408b7445d 100644 --- a/drivers/clk/qcom/clk-krait.c +++ b/drivers/clk/qcom/clk-krait.c @@ -68,7 +68,7 @@ static int krait_mux_set_parent(struct clk_hw *hw, u8 index) sel = clk_mux_index_to_val(mux->parent_map, 0, index); mux->en_mask = sel; /* Don't touch mux if CPU is off as it won't work */ - if (__clk_is_enabled(hw->clk)) + if (clk_hw_is_enabled(hw)) __krait_mux_set_sel(mux, sel); mux->reparent = true; diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c index 31f0650b48ba..1664101e8f78 100644 --- a/drivers/clk/qcom/clk-rcg.c +++ b/drivers/clk/qcom/clk-rcg.c @@ -208,7 +208,7 @@ static int configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f) bool banked_p = !!rcg->p[1].pre_div_width; struct clk_hw *hw = &rcg->clkr.hw; - enabled = __clk_is_enabled(hw->clk); + enabled = clk_hw_is_enabled(hw); ret = regmap_read(rcg->clkr.regmap, rcg->bank_reg, ®); if (ret) @@ -771,7 +771,7 @@ static int clk_rcg_lcc_set_rate(struct clk_hw *hw, unsigned long rate, regmap_update_bits(rcg->clkr.regmap, rcg->ns_reg, gfm, 0); ret = __clk_rcg_set_rate(rcg, f); /* Switch back to M/N if it's clocking */ - if (__clk_is_enabled(hw->clk)) + if (clk_hw_is_enabled(hw)) regmap_update_bits(rcg->clkr.regmap, rcg->ns_reg, gfm, gfm); return ret; diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 6064a0e17d51..d7914e59129f 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -489,7 +489,7 @@ static int clk_rcg2_determine_gp_rate(struct clk_hw *hw, u64 parent_rate; parent = clk_hw_get_parent(hw); - parent_rate = clk_get_rate(parent->clk); + parent_rate = clk_hw_get_rate(parent); if (!parent_rate) return -EINVAL; diff --git a/drivers/clk/qcom/clk-ref.c b/drivers/clk/qcom/clk-ref.c new file mode 100644 index 000000000000..3efdf6749770 --- /dev/null +++ b/drivers/clk/qcom/clk-ref.c @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026, Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define QCOM_CLK_REF_EN_MASK BIT(0) + +struct qcom_clk_ref_provider { + size_t num_refs; + struct qcom_clk_ref refs[] __counted_by(num_refs); +}; + +static inline struct qcom_clk_ref *to_qcom_clk_ref(struct clk_hw *hw) +{ + return container_of(hw, struct qcom_clk_ref, hw); +} + +static const struct clk_parent_data qcom_clk_ref_parent_data = { + .index = 0, +}; + +static int qcom_clk_ref_prepare(struct clk_hw *hw) +{ + struct qcom_clk_ref *rclk = to_qcom_clk_ref(hw); + int ret; + + if (!rclk->desc.num_regulators) + return 0; + + ret = regulator_bulk_enable(rclk->desc.num_regulators, rclk->regulators); + if (ret) + pr_err("Failed to enable regulators for %s: %d\n", + clk_hw_get_name(hw), ret); + + return ret; +} + +static void qcom_clk_ref_unprepare(struct clk_hw *hw) +{ + struct qcom_clk_ref *rclk = to_qcom_clk_ref(hw); + + if (rclk->desc.num_regulators) + regulator_bulk_disable(rclk->desc.num_regulators, rclk->regulators); +} + +static int qcom_clk_ref_enable(struct clk_hw *hw) +{ + struct qcom_clk_ref *rclk = to_qcom_clk_ref(hw); + int ret; + + ret = regmap_set_bits(rclk->regmap, rclk->desc.offset, QCOM_CLK_REF_EN_MASK); + if (ret) + return ret; + + udelay(10); + + return 0; +} + +static void qcom_clk_ref_disable(struct clk_hw *hw) +{ + struct qcom_clk_ref *rclk = to_qcom_clk_ref(hw); + + regmap_clear_bits(rclk->regmap, rclk->desc.offset, QCOM_CLK_REF_EN_MASK); + udelay(10); +} + +static int qcom_clk_ref_is_enabled(struct clk_hw *hw) +{ + struct qcom_clk_ref *rclk = to_qcom_clk_ref(hw); + u32 val; + int ret; + + ret = regmap_read(rclk->regmap, rclk->desc.offset, &val); + if (ret) + return 0; + + return !!(val & QCOM_CLK_REF_EN_MASK); +} + +static const struct clk_ops qcom_clk_ref_ops = { + .prepare = qcom_clk_ref_prepare, + .unprepare = qcom_clk_ref_unprepare, + .enable = qcom_clk_ref_enable, + .disable = qcom_clk_ref_disable, + .is_enabled = qcom_clk_ref_is_enabled, +}; + +static int qcom_clk_ref_register(struct device *dev, struct regmap *regmap, + struct qcom_clk_ref *clk_refs, + const struct qcom_clk_ref_desc * const *descs, + size_t num_clk_refs) +{ + const struct qcom_clk_ref_desc *desc; + struct clk_init_data init_data = {}; + struct qcom_clk_ref *clk_ref; + size_t clk_idx; + unsigned int i; + int ret; + + for (clk_idx = 0; clk_idx < num_clk_refs; clk_idx++) { + clk_ref = &clk_refs[clk_idx]; + desc = descs[clk_idx]; + + /* Skip unpopulated indices; the array is indexed by clock ID. */ + if (!desc) + continue; + + if (WARN_ON(!desc->name)) + continue; + + clk_ref->regmap = regmap; + clk_ref->desc = *desc; + + if (clk_ref->desc.num_regulators) { + clk_ref->regulators = devm_kcalloc(dev, clk_ref->desc.num_regulators, + sizeof(*clk_ref->regulators), + GFP_KERNEL); + if (!clk_ref->regulators) + return -ENOMEM; + + for (i = 0; i < clk_ref->desc.num_regulators; i++) + clk_ref->regulators[i].supply = + clk_ref->desc.regulator_names[i]; + + ret = devm_regulator_bulk_get(dev, clk_ref->desc.num_regulators, + clk_ref->regulators); + if (ret) + return dev_err_probe(dev, ret, + "Failed to get regulators for %s\n", + clk_ref->desc.name); + } + + init_data.name = clk_ref->desc.name; + init_data.parent_data = &qcom_clk_ref_parent_data; + init_data.num_parents = 1; + init_data.ops = &qcom_clk_ref_ops; + clk_ref->hw.init = &init_data; + + ret = devm_clk_hw_register(dev, &clk_ref->hw); + if (ret) + return ret; + } + + return 0; +} + +static struct clk_hw *qcom_clk_ref_provider_get(struct of_phandle_args *clkspec, void *data) +{ + struct qcom_clk_ref_provider *provider = data; + unsigned int idx = clkspec->args[0]; + + if (idx >= provider->num_refs) + return ERR_PTR(-EINVAL); + + if (!provider->refs[idx].regmap) + return ERR_PTR(-ENOENT); + + return &provider->refs[idx].hw; +} + +int qcom_clk_ref_probe(struct platform_device *pdev, + const struct regmap_config *config, + const struct qcom_clk_ref_desc * const *descs, + size_t num_clk_refs) +{ + struct qcom_clk_ref_provider *provider; + struct device *dev = &pdev->dev; + struct regmap *regmap; + void __iomem *base; + int ret; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(dev, base, config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + provider = devm_kzalloc(dev, struct_size(provider, refs, num_clk_refs), + GFP_KERNEL); + if (!provider) + return -ENOMEM; + + provider->num_refs = num_clk_refs; + + ret = qcom_clk_ref_register(dev, regmap, provider->refs, descs, + provider->num_refs); + if (ret) + return ret; + + return devm_of_clk_add_hw_provider(dev, qcom_clk_ref_provider_get, provider); +} +EXPORT_SYMBOL_GPL(qcom_clk_ref_probe); diff --git a/drivers/clk/qcom/clk-rpm.c b/drivers/clk/qcom/clk-rpm.c index be0145631197..74f569b58017 100644 --- a/drivers/clk/qcom/clk-rpm.c +++ b/drivers/clk/qcom/clk-rpm.c @@ -351,17 +351,6 @@ static int clk_rpm_set_rate(struct clk_hw *hw, return 0; } -static int clk_rpm_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - /* - * RPM handles rate rounding and we don't have a way to - * know what the rate will be, so just return whatever - * rate is requested. - */ - return 0; -} - static unsigned long clk_rpm_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -383,7 +372,7 @@ static const struct clk_ops clk_rpm_xo_ops = { static const struct clk_ops clk_rpm_fixed_ops = { .prepare = clk_rpm_fixed_prepare, .unprepare = clk_rpm_fixed_unprepare, - .determine_rate = clk_rpm_determine_rate, + .determine_rate = clk_determine_rate_noop, .recalc_rate = clk_rpm_recalc_rate, }; @@ -391,7 +380,7 @@ static const struct clk_ops clk_rpm_ops = { .prepare = clk_rpm_prepare, .unprepare = clk_rpm_unprepare, .set_rate = clk_rpm_set_rate, - .determine_rate = clk_rpm_determine_rate, + .determine_rate = clk_determine_rate_noop, .recalc_rate = clk_rpm_recalc_rate, }; diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 6367b2a5a4e0..a224a94ae273 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -319,12 +319,6 @@ static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static int clk_rpmh_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - return 0; -} - static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw, unsigned long prate) { @@ -337,7 +331,7 @@ static const struct clk_ops clk_rpmh_bcm_ops = { .prepare = clk_rpmh_bcm_prepare, .unprepare = clk_rpmh_bcm_unprepare, .set_rate = clk_rpmh_bcm_set_rate, - .determine_rate = clk_rpmh_determine_rate, + .determine_rate = clk_determine_rate_noop, .recalc_rate = clk_rpmh_bcm_recalc_rate, }; diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 103db984a40b..487d715ed5d2 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -370,17 +370,6 @@ static int clk_smd_rpm_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static int clk_smd_rpm_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - /* - * RPM handles rate rounding and we don't have a way to - * know what the rate will be, so just return whatever - * rate is requested. - */ - return 0; -} - static unsigned long clk_smd_rpm_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -427,7 +416,7 @@ static const struct clk_ops clk_smd_rpm_ops = { .prepare = clk_smd_rpm_prepare, .unprepare = clk_smd_rpm_unprepare, .set_rate = clk_smd_rpm_set_rate, - .determine_rate = clk_smd_rpm_determine_rate, + .determine_rate = clk_determine_rate_noop, .recalc_rate = clk_smd_rpm_recalc_rate, }; @@ -495,6 +484,7 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(rf_clk2, 5, 19200000); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(rf_clk3, 6, 19200000); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(ln_bb_clk, 8, 19200000); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PREFIX(38m4_, rf_clk2, 5, 38400000); DEFINE_CLK_SMD_RPM_XO_BUFFER_PREFIX(38m4_, rf_clk3, 6, 38400000); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(cxo_d0, 1, 19200000); @@ -1262,6 +1252,10 @@ static struct clk_smd_rpm *qcm2290_clks[] = { [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_branch_qdss_a_clk, [RPM_SMD_LN_BB_CLK2] = &clk_smd_rpm_ln_bb_clk2, [RPM_SMD_LN_BB_CLK2_A] = &clk_smd_rpm_ln_bb_clk2_a, + [RPM_SMD_RF_CLK1] = &clk_smd_rpm_rf_clk1, + [RPM_SMD_RF_CLK1_A] = &clk_smd_rpm_rf_clk1_a, + [RPM_SMD_RF_CLK2] = &clk_smd_rpm_38m4_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &clk_smd_rpm_38m4_rf_clk2_a, [RPM_SMD_RF_CLK3] = &clk_smd_rpm_38m4_rf_clk3, [RPM_SMD_RF_CLK3_A] = &clk_smd_rpm_38m4_rf_clk3_a, [RPM_SMD_IPA_CLK] = &clk_smd_rpm_ipa_clk, diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index eec369d2173b..08fd62ac780d 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -169,7 +169,7 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path, if (!node) { fixed = devm_kzalloc(dev, sizeof(*fixed), GFP_KERNEL); if (!fixed) - return -EINVAL; + return -ENOMEM; fixed->fixed_rate = rate; fixed->hw.init = &init_data; @@ -186,7 +186,7 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path, if (add_factor) { factor = devm_kzalloc(dev, sizeof(*factor), GFP_KERNEL); if (!factor) - return -EINVAL; + return -ENOMEM; factor->mult = factor->div = 1; factor->hw.init = &init_data; @@ -428,7 +428,7 @@ int qcom_cc_really_probe(struct device *dev, put_rpm: if (desc->use_rpm) - pm_runtime_put(dev); + pm_runtime_put_sync(dev); return ret; } diff --git a/drivers/clk/qcom/dispcc-qcm2290.c b/drivers/clk/qcom/dispcc-qcm2290.c index 4d6aad280ae1..d32fd3f8d7ac 100644 --- a/drivers/clk/qcom/dispcc-qcm2290.c +++ b/drivers/clk/qcom/dispcc-qcm2290.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. * Copyright (c) 2021, Linaro Ltd. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -48,6 +49,7 @@ static const struct alpha_pll_config disp_cc_pll0_config = { static struct clk_alpha_pll disp_cc_pll0 = { .offset = 0x0, + .config = &disp_cc_pll0_config, .vco_table = spark_vco, .num_vco = ARRAY_SIZE(spark_vco), .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], @@ -449,11 +451,14 @@ static const struct qcom_reset_map disp_cc_qcm2290_resets[] = { static struct gdsc mdss_gdsc = { .gdscr = 0x3000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "mdss_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = HW_CTRL, + .flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; static struct gdsc *disp_cc_qcm2290_gdscs[] = { @@ -482,6 +487,14 @@ static struct clk_regmap *disp_cc_qcm2290_clocks[] = { [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr, }; +static struct clk_alpha_pll *disp_cc_qcm2290_plls[] = { + &disp_cc_pll0, +}; + +static const u32 disp_cc_qcm2290_critical_cbcrs[] = { + 0x604c, /* DISP_CC_XO_CLK */ +}; + static const struct regmap_config disp_cc_qcm2290_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -490,6 +503,13 @@ static const struct regmap_config disp_cc_qcm2290_regmap_config = { .fast_io = true, }; +static const struct qcom_cc_driver_data disp_cc_qcm2290_driver_data = { + .alpha_plls = disp_cc_qcm2290_plls, + .num_alpha_plls = ARRAY_SIZE(disp_cc_qcm2290_plls), + .clk_cbcrs = disp_cc_qcm2290_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_qcm2290_critical_cbcrs), +}; + static const struct qcom_cc_desc disp_cc_qcm2290_desc = { .config = &disp_cc_qcm2290_regmap_config, .clks = disp_cc_qcm2290_clocks, @@ -498,6 +518,8 @@ static const struct qcom_cc_desc disp_cc_qcm2290_desc = { .num_gdscs = ARRAY_SIZE(disp_cc_qcm2290_gdscs), .resets = disp_cc_qcm2290_resets, .num_resets = ARRAY_SIZE(disp_cc_qcm2290_resets), + .use_rpm = true, + .driver_data = &disp_cc_qcm2290_driver_data, }; static const struct of_device_id disp_cc_qcm2290_match_table[] = { @@ -508,25 +530,7 @@ MODULE_DEVICE_TABLE(of, disp_cc_qcm2290_match_table); static int disp_cc_qcm2290_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &disp_cc_qcm2290_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x604c); /* DISP_CC_XO_CLK */ - - ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_qcm2290_desc, regmap); - if (ret) { - dev_err(&pdev->dev, "Failed to register DISP CC clocks\n"); - return ret; - } - - return ret; + return qcom_cc_probe(pdev, &disp_cc_qcm2290_desc); } static struct platform_driver disp_cc_qcm2290_driver = { diff --git a/drivers/clk/qcom/dispcc0-nord.c b/drivers/clk/qcom/dispcc0-nord.c new file mode 100644 index 000000000000..835aba159613 --- /dev/null +++ b/drivers/clk/qcom/dispcc0-nord.c @@ -0,0 +1,2004 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_AHB_CLK, + DT_SLEEP_CLK, + + DT_DSI0_PHY_PLL_OUT_BYTECLK, + DT_DSI0_PHY_PLL_OUT_DSICLK, + DT_DSI1_PHY_PLL_OUT_BYTECLK, + DT_DSI1_PHY_PLL_OUT_DSICLK, + + DT_DP0_PHY_PLL_LINK_CLK, + DT_DP0_PHY_PLL_VCO_DIV_CLK, + DT_DP1_PHY_PLL_LINK_CLK, + DT_DP1_PHY_PLL_VCO_DIV_CLK, + DT_DP2_PHY_PLL_LINK_CLK, + DT_DP2_PHY_PLL_VCO_DIV_CLK, + DT_DP3_PHY_PLL_LINK_CLK, + DT_DP3_PHY_PLL_VCO_DIV_CLK, +}; + +enum { + P_BI_TCXO, + P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, + P_MDSS_0_DISP_CC_PLL1_OUT_EVEN, + P_MDSS_0_DISP_CC_PLL1_OUT_MAIN, + P_MDSS_0_DISP_CC_PLL2_OUT_MAIN, + P_MDSS_0_DISP_CC_PLL3_OUT_MAIN, + P_DP0_PHY_PLL_LINK_CLK, + P_DP0_PHY_PLL_VCO_DIV_CLK, + P_DP1_PHY_PLL_LINK_CLK, + P_DP1_PHY_PLL_VCO_DIV_CLK, + P_DP2_PHY_PLL_LINK_CLK, + P_DP2_PHY_PLL_VCO_DIV_CLK, + P_DP3_PHY_PLL_LINK_CLK, + P_DP3_PHY_PLL_VCO_DIV_CLK, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_DSI1_PHY_PLL_OUT_BYTECLK, + P_DSI1_PHY_PLL_OUT_DSICLK, + P_SLEEP_CLK, +}; + +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + +static const struct pll_vco zonda_ole_vco[] = { + { 700000000, 3600000000, 0 }, +}; + +/* 900.0 MHz Configuration */ +static const struct alpha_pll_config mdss_0_disp_cc_pll0_config = { + .l = 0x2e, + .alpha = 0xe000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll mdss_0_disp_cc_pll0 = { + .offset = 0x0, + .config = &mdss_0_disp_cc_pll0_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +/* 600.0 MHz Configuration */ +static const struct alpha_pll_config mdss_0_disp_cc_pll1_config = { + .l = 0x1f, + .alpha = 0x4000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll mdss_0_disp_cc_pll1 = { + .offset = 0x1000, + .config = &mdss_0_disp_cc_pll1_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +/* 1363.2 MHz Configuration */ +static const struct alpha_pll_config mdss_0_disp_cc_pll2_config = { + .l = 0x47, + .alpha = 0x0, + .config_ctl_val = 0x08240800, + .config_ctl_hi_val = 0x05008001, + .config_ctl_hi1_val = 0x00000000, + .config_ctl_hi2_val = 0x00000000, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000080, +}; + +static struct clk_alpha_pll mdss_0_disp_cc_pll2 = { + .offset = 0x2000, + .config = &mdss_0_disp_cc_pll2_config, + .vco_table = zonda_ole_vco, + .num_vco = ARRAY_SIZE(zonda_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_zonda_ole_ops, + }, + }, +}; + +/* 1363.2 MHz Configuration */ +static const struct alpha_pll_config mdss_0_disp_cc_pll3_config = { + .l = 0x47, + .alpha = 0x0, + .config_ctl_val = 0x08240800, + .config_ctl_hi_val = 0x05008001, + .config_ctl_hi1_val = 0x00000000, + .config_ctl_hi2_val = 0x00000000, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000080, +}; + +static struct clk_alpha_pll mdss_0_disp_cc_pll3 = { + .offset = 0x3000, + .config = &mdss_0_disp_cc_pll3_config, + .vco_table = zonda_ole_vco, + .num_vco = ARRAY_SIZE(zonda_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_zonda_ole_ops, + }, + }, +}; + +static const struct parent_map disp_cc_0_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_MDSS_0_DISP_CC_PLL2_OUT_MAIN, 1 }, + { P_DP0_PHY_PLL_VCO_DIV_CLK, 2 }, + { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 }, + { P_DP1_PHY_PLL_VCO_DIV_CLK, 4 }, + { P_MDSS_0_DISP_CC_PLL3_OUT_MAIN, 5 }, + { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_0_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &mdss_0_disp_cc_pll2.clkr.hw }, + { .index = DT_DP0_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP1_PHY_PLL_VCO_DIV_CLK }, + { .hw = &mdss_0_disp_cc_pll3.clkr.hw }, + { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map disp_cc_0_parent_map_1[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data disp_cc_0_parent_data_1[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map disp_cc_0_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 3 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_0_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_0_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_MDSS_0_DISP_CC_PLL2_OUT_MAIN, 1 }, + { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 }, + { P_MDSS_0_DISP_CC_PLL3_OUT_MAIN, 5 }, + { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_0_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &mdss_0_disp_cc_pll2.clkr.hw }, + { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK }, + { .hw = &mdss_0_disp_cc_pll3.clkr.hw }, + { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map disp_cc_0_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_DP0_PHY_PLL_LINK_CLK, 1 }, + { P_DP1_PHY_PLL_LINK_CLK, 2 }, + { P_DP2_PHY_PLL_LINK_CLK, 3 }, + { P_DP3_PHY_PLL_LINK_CLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_0_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP0_PHY_PLL_LINK_CLK }, + { .index = DT_DP1_PHY_PLL_LINK_CLK }, + { .index = DT_DP2_PHY_PLL_LINK_CLK }, + { .index = DT_DP3_PHY_PLL_LINK_CLK }, +}; + +static const struct parent_map disp_cc_0_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_DP2_PHY_PLL_LINK_CLK, 3 }, + { P_DP3_PHY_PLL_LINK_CLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_0_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP2_PHY_PLL_LINK_CLK }, + { .index = DT_DP3_PHY_PLL_LINK_CLK }, +}; + +static const struct parent_map disp_cc_0_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_0_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_0_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_MDSS_0_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_MDSS_0_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_0_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &mdss_0_disp_cc_pll1.clkr.hw }, + { .hw = &mdss_0_disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_0_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, 1 }, + { P_MDSS_0_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_MDSS_0_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_0_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &mdss_0_disp_cc_pll0.clkr.hw }, + { .hw = &mdss_0_disp_cc_pll1.clkr.hw }, + { .hw = &mdss_0_disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_0_parent_map_9[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data disp_cc_0_parent_data_9[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_mdss_0_disp_cc_mdss_ahb_clk_src[] = { + F(37500000, P_MDSS_0_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0), + F(75000000, P_MDSS_0_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0), + { } +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_ahb_clk_src = { + .cmd_rcgr = 0x837c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_7, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_ahb_clk_src", + .parent_data = disp_cc_0_parent_data_7, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_mdss_0_disp_cc_mdss_byte0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_byte0_clk_src = { + .cmd_rcgr = 0x813c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_2, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_byte0_clk_src", + .parent_data = disp_cc_0_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_byte1_clk_src = { + .cmd_rcgr = 0x8158, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_2, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_byte1_clk_src", + .parent_data = disp_cc_0_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_aux_clk_src = { + .cmd_rcgr = 0x8220, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_1, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_aux_clk_src", + .parent_data = disp_cc_0_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_link_clk_src = { + .cmd_rcgr = 0x81a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_4, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_link_clk_src", + .parent_data = disp_cc_0_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_pixel0_clk_src = { + .cmd_rcgr = 0x81c0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_0, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_pixel0_clk_src", + .parent_data = disp_cc_0_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_pixel1_clk_src = { + .cmd_rcgr = 0x81d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_0, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_pixel1_clk_src", + .parent_data = disp_cc_0_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_pixel2_clk_src = { + .cmd_rcgr = 0x81f0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_0, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_pixel2_clk_src", + .parent_data = disp_cc_0_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_pixel3_clk_src = { + .cmd_rcgr = 0x8208, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_0, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_pixel3_clk_src", + .parent_data = disp_cc_0_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx1_aux_clk_src = { + .cmd_rcgr = 0x82b4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_1, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_aux_clk_src", + .parent_data = disp_cc_0_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx1_link_clk_src = { + .cmd_rcgr = 0x8298, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_4, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_link_clk_src", + .parent_data = disp_cc_0_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx1_pixel0_clk_src = { + .cmd_rcgr = 0x8238, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_0, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_pixel0_clk_src", + .parent_data = disp_cc_0_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx1_pixel1_clk_src = { + .cmd_rcgr = 0x8250, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_0, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_pixel1_clk_src", + .parent_data = disp_cc_0_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx1_pixel2_clk_src = { + .cmd_rcgr = 0x8268, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_0, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_pixel2_clk_src", + .parent_data = disp_cc_0_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx1_pixel3_clk_src = { + .cmd_rcgr = 0x8280, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_0, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_pixel3_clk_src", + .parent_data = disp_cc_0_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx2_aux_clk_src = { + .cmd_rcgr = 0x8318, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_1, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx2_aux_clk_src", + .parent_data = disp_cc_0_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx2_link_clk_src = { + .cmd_rcgr = 0x82cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_5, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx2_link_clk_src", + .parent_data = disp_cc_0_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx2_pixel0_clk_src = { + .cmd_rcgr = 0x82e8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_3, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx2_pixel0_clk_src", + .parent_data = disp_cc_0_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx2_pixel1_clk_src = { + .cmd_rcgr = 0x8300, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_3, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx2_pixel1_clk_src", + .parent_data = disp_cc_0_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx3_aux_clk_src = { + .cmd_rcgr = 0x8364, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_1, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx3_aux_clk_src", + .parent_data = disp_cc_0_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx3_link_clk_src = { + .cmd_rcgr = 0x8348, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_5, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx3_link_clk_src", + .parent_data = disp_cc_0_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx3_pixel0_clk_src = { + .cmd_rcgr = 0x8330, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_3, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx3_pixel0_clk_src", + .parent_data = disp_cc_0_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_esc0_clk_src = { + .cmd_rcgr = 0x8174, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_6, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_esc0_clk_src", + .parent_data = disp_cc_0_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_esc1_clk_src = { + .cmd_rcgr = 0x818c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_6, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_esc1_clk_src", + .parent_data = disp_cc_0_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_mdss_0_disp_cc_mdss_mdp_clk_src[] = { + F(300000000, P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(417000000, P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(532000000, P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(650000000, P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(710000000, P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_mdp_clk_src = { + .cmd_rcgr = 0x810c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_8, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_mdp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_mdp_clk_src", + .parent_data = disp_cc_0_parent_data_8, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_pclk0_clk_src = { + .cmd_rcgr = 0x80c4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_2, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_pclk0_clk_src", + .parent_data = disp_cc_0_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_pclk1_clk_src = { + .cmd_rcgr = 0x80dc, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_2, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_pclk1_clk_src", + .parent_data = disp_cc_0_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_pclk2_clk_src = { + .cmd_rcgr = 0x80f4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_2, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_pclk2_clk_src", + .parent_data = disp_cc_0_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_mdss_vsync_clk_src = { + .cmd_rcgr = 0x8124, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_1, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_vsync_clk_src", + .parent_data = disp_cc_0_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_mdss_0_disp_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 mdss_0_disp_cc_sleep_clk_src = { + .cmd_rcgr = 0xe064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_9, + .freq_tbl = ftbl_mdss_0_disp_cc_sleep_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_sleep_clk_src", + .parent_data = disp_cc_0_parent_data_9, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mdss_0_disp_cc_xo_clk_src = { + .cmd_rcgr = 0xe044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_0_parent_map_1, + .freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_xo_clk_src", + .parent_data = disp_cc_0_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_0_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div mdss_0_disp_cc_mdss_byte0_div_clk_src = { + .reg = 0x8154, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_byte0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div mdss_0_disp_cc_mdss_byte1_div_clk_src = { + .reg = 0x8170, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_byte1_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div mdss_0_disp_cc_mdss_dptx0_link_div_clk_src = { + .reg = 0x81bc, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div mdss_0_disp_cc_mdss_dptx1_link_div_clk_src = { + .reg = 0x82b0, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div mdss_0_disp_cc_mdss_dptx2_link_div_clk_src = { + .reg = 0x82e4, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx2_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div mdss_0_disp_cc_mdss_dptx3_link_div_clk_src = { + .reg = 0x8360, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx3_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_accu_shift_clk = { + .halt_reg = 0xe060, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xe060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_accu_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_ahb1_clk = { + .halt_reg = 0xa028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_ahb1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_ahb_clk = { + .halt_reg = 0x80c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_byte0_clk = { + .halt_reg = 0x8034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_byte0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_byte0_intf_clk = { + .halt_reg = 0x8038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_byte0_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_byte0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_byte1_clk = { + .halt_reg = 0x803c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x803c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_byte1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_byte1_intf_clk = { + .halt_reg = 0x8040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_byte1_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_byte1_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx0_aux_clk = { + .halt_reg = 0x806c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x806c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx0_crypto_clk = { + .halt_reg = 0x8058, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx0_link_clk = { + .halt_reg = 0x804c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx0_link_intf_clk = { + .halt_reg = 0x8054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx0_pixel0_clk = { + .halt_reg = 0x805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx0_pixel1_clk = { + .halt_reg = 0x8060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx0_pixel2_clk = { + .halt_reg = 0x8064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_pixel2_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx0_pixel2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx0_pixel3_clk = { + .halt_reg = 0x8068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_pixel3_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx0_pixel3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx0_usb_router_link_intf_clk = { + .halt_reg = 0x8050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx0_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx1_aux_clk = { + .halt_reg = 0x8090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx1_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx1_crypto_clk = { + .halt_reg = 0x808c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x808c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx1_link_clk = { + .halt_reg = 0x8080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx1_link_intf_clk = { + .halt_reg = 0x8088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx1_pixel0_clk = { + .halt_reg = 0x8070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx1_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx1_pixel1_clk = { + .halt_reg = 0x8074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx1_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx1_pixel2_clk = { + .halt_reg = 0x8078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_pixel2_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx1_pixel2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx1_pixel3_clk = { + .halt_reg = 0x807c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x807c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_pixel3_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx1_pixel3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx1_usb_router_link_intf_clk = { + .halt_reg = 0x8084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8084, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx1_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx2_aux_clk = { + .halt_reg = 0x80a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx2_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx2_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx2_crypto_clk = { + .halt_reg = 0x80a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x80a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx2_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx2_link_clk = { + .halt_reg = 0x809c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x809c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx2_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx2_link_intf_clk = { + .halt_reg = 0x80a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx2_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx2_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx2_pixel0_clk = { + .halt_reg = 0x8094, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8094, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx2_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx2_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx2_pixel1_clk = { + .halt_reg = 0x8098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8098, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx2_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx2_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx3_aux_clk = { + .halt_reg = 0x80b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx3_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx3_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx3_crypto_clk = { + .halt_reg = 0x80bc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x80bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx3_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx3_link_clk = { + .halt_reg = 0x80b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx3_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx3_link_intf_clk = { + .halt_reg = 0x80b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx3_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx3_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_dptx3_pixel0_clk = { + .halt_reg = 0x80ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_dptx3_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_dptx3_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_esc0_clk = { + .halt_reg = 0x8044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_esc0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_esc0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_esc1_clk = { + .halt_reg = 0x8048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_esc1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_esc1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_mdp1_clk = { + .halt_reg = 0xa004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_mdp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_mdp_clk = { + .halt_reg = 0x8010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_mdp_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_mdp_lut1_clk = { + .halt_reg = 0xa014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xa014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_mdp_lut1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_mdp_lut_clk = { + .halt_reg = 0x8020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_mdp_lut_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_non_gdsc_ahb_clk = { + .halt_reg = 0xc004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xc004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_non_gdsc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_pclk0_clk = { + .halt_reg = 0x8004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_pclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_pclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_pclk1_clk = { + .halt_reg = 0x8008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_pclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_pclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_pclk2_clk = { + .halt_reg = 0x800c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x800c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_pclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_pclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_vsync1_clk = { + .halt_reg = 0xa024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_vsync1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_0_disp_cc_mdss_vsync_clk = { + .halt_reg = 0x8030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_0_disp_cc_mdss_vsync_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_0_disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc mdss_0_disp_cc_mdss_core_gdsc = { + .gdscr = 0x9000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "mdss_0_disp_cc_mdss_core_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc mdss_0_disp_cc_mdss_core_int2_gdsc = { + .gdscr = 0xb000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "mdss_0_disp_cc_mdss_core_int2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *disp_cc_0_nord_clocks[] = { + [MDSS_DISP_CC_MDSS_ACCU_SHIFT_CLK] = &mdss_0_disp_cc_mdss_accu_shift_clk.clkr, + [MDSS_DISP_CC_MDSS_AHB1_CLK] = &mdss_0_disp_cc_mdss_ahb1_clk.clkr, + [MDSS_DISP_CC_MDSS_AHB_CLK] = &mdss_0_disp_cc_mdss_ahb_clk.clkr, + [MDSS_DISP_CC_MDSS_AHB_CLK_SRC] = &mdss_0_disp_cc_mdss_ahb_clk_src.clkr, + [MDSS_DISP_CC_MDSS_BYTE0_CLK] = &mdss_0_disp_cc_mdss_byte0_clk.clkr, + [MDSS_DISP_CC_MDSS_BYTE0_CLK_SRC] = &mdss_0_disp_cc_mdss_byte0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &mdss_0_disp_cc_mdss_byte0_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_BYTE0_INTF_CLK] = &mdss_0_disp_cc_mdss_byte0_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_BYTE1_CLK] = &mdss_0_disp_cc_mdss_byte1_clk.clkr, + [MDSS_DISP_CC_MDSS_BYTE1_CLK_SRC] = &mdss_0_disp_cc_mdss_byte1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = &mdss_0_disp_cc_mdss_byte1_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_BYTE1_INTF_CLK] = &mdss_0_disp_cc_mdss_byte1_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK] = &mdss_0_disp_cc_mdss_dptx0_aux_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_aux_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_CRYPTO_CLK] = &mdss_0_disp_cc_mdss_dptx0_crypto_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK] = &mdss_0_disp_cc_mdss_dptx0_link_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_link_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] = + &mdss_0_disp_cc_mdss_dptx0_link_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &mdss_0_disp_cc_mdss_dptx0_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &mdss_0_disp_cc_mdss_dptx0_pixel0_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_pixel0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &mdss_0_disp_cc_mdss_dptx0_pixel1_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_pixel1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK] = &mdss_0_disp_cc_mdss_dptx0_pixel2_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_pixel2_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK] = &mdss_0_disp_cc_mdss_dptx0_pixel3_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_pixel3_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] = + &mdss_0_disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK] = &mdss_0_disp_cc_mdss_dptx1_aux_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx1_aux_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_CRYPTO_CLK] = &mdss_0_disp_cc_mdss_dptx1_crypto_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK] = &mdss_0_disp_cc_mdss_dptx1_link_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx1_link_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC] = + &mdss_0_disp_cc_mdss_dptx1_link_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_LINK_INTF_CLK] = &mdss_0_disp_cc_mdss_dptx1_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK] = &mdss_0_disp_cc_mdss_dptx1_pixel0_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx1_pixel0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK] = &mdss_0_disp_cc_mdss_dptx1_pixel1_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx1_pixel1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL2_CLK] = &mdss_0_disp_cc_mdss_dptx1_pixel2_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL2_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx1_pixel2_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL3_CLK] = &mdss_0_disp_cc_mdss_dptx1_pixel3_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL3_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx1_pixel3_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK] = + &mdss_0_disp_cc_mdss_dptx1_usb_router_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_AUX_CLK] = &mdss_0_disp_cc_mdss_dptx2_aux_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_AUX_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx2_aux_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_CRYPTO_CLK] = &mdss_0_disp_cc_mdss_dptx2_crypto_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_LINK_CLK] = &mdss_0_disp_cc_mdss_dptx2_link_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_LINK_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx2_link_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC] = + &mdss_0_disp_cc_mdss_dptx2_link_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_LINK_INTF_CLK] = &mdss_0_disp_cc_mdss_dptx2_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_PIXEL0_CLK] = &mdss_0_disp_cc_mdss_dptx2_pixel0_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx2_pixel0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_PIXEL1_CLK] = &mdss_0_disp_cc_mdss_dptx2_pixel1_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx2_pixel1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_AUX_CLK] = &mdss_0_disp_cc_mdss_dptx3_aux_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_AUX_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx3_aux_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_CRYPTO_CLK] = &mdss_0_disp_cc_mdss_dptx3_crypto_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_LINK_CLK] = &mdss_0_disp_cc_mdss_dptx3_link_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_LINK_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx3_link_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC] = + &mdss_0_disp_cc_mdss_dptx3_link_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_LINK_INTF_CLK] = &mdss_0_disp_cc_mdss_dptx3_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_PIXEL0_CLK] = &mdss_0_disp_cc_mdss_dptx3_pixel0_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx3_pixel0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_ESC0_CLK] = &mdss_0_disp_cc_mdss_esc0_clk.clkr, + [MDSS_DISP_CC_MDSS_ESC0_CLK_SRC] = &mdss_0_disp_cc_mdss_esc0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_ESC1_CLK] = &mdss_0_disp_cc_mdss_esc1_clk.clkr, + [MDSS_DISP_CC_MDSS_ESC1_CLK_SRC] = &mdss_0_disp_cc_mdss_esc1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_MDP1_CLK] = &mdss_0_disp_cc_mdss_mdp1_clk.clkr, + [MDSS_DISP_CC_MDSS_MDP_CLK] = &mdss_0_disp_cc_mdss_mdp_clk.clkr, + [MDSS_DISP_CC_MDSS_MDP_CLK_SRC] = &mdss_0_disp_cc_mdss_mdp_clk_src.clkr, + [MDSS_DISP_CC_MDSS_MDP_LUT1_CLK] = &mdss_0_disp_cc_mdss_mdp_lut1_clk.clkr, + [MDSS_DISP_CC_MDSS_MDP_LUT_CLK] = &mdss_0_disp_cc_mdss_mdp_lut_clk.clkr, + [MDSS_DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &mdss_0_disp_cc_mdss_non_gdsc_ahb_clk.clkr, + [MDSS_DISP_CC_MDSS_PCLK0_CLK] = &mdss_0_disp_cc_mdss_pclk0_clk.clkr, + [MDSS_DISP_CC_MDSS_PCLK0_CLK_SRC] = &mdss_0_disp_cc_mdss_pclk0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_PCLK1_CLK] = &mdss_0_disp_cc_mdss_pclk1_clk.clkr, + [MDSS_DISP_CC_MDSS_PCLK1_CLK_SRC] = &mdss_0_disp_cc_mdss_pclk1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_PCLK2_CLK] = &mdss_0_disp_cc_mdss_pclk2_clk.clkr, + [MDSS_DISP_CC_MDSS_PCLK2_CLK_SRC] = &mdss_0_disp_cc_mdss_pclk2_clk_src.clkr, + [MDSS_DISP_CC_MDSS_VSYNC1_CLK] = &mdss_0_disp_cc_mdss_vsync1_clk.clkr, + [MDSS_DISP_CC_MDSS_VSYNC_CLK] = &mdss_0_disp_cc_mdss_vsync_clk.clkr, + [MDSS_DISP_CC_MDSS_VSYNC_CLK_SRC] = &mdss_0_disp_cc_mdss_vsync_clk_src.clkr, + [MDSS_DISP_CC_PLL0] = &mdss_0_disp_cc_pll0.clkr, + [MDSS_DISP_CC_PLL1] = &mdss_0_disp_cc_pll1.clkr, + [MDSS_DISP_CC_PLL2] = &mdss_0_disp_cc_pll2.clkr, + [MDSS_DISP_CC_PLL3] = &mdss_0_disp_cc_pll3.clkr, + [MDSS_DISP_CC_SLEEP_CLK_SRC] = &mdss_0_disp_cc_sleep_clk_src.clkr, + [MDSS_DISP_CC_XO_CLK_SRC] = &mdss_0_disp_cc_xo_clk_src.clkr, +}; + +static struct gdsc *disp_cc_0_nord_gdscs[] = { + [MDSS_DISP_CC_MDSS_CORE_GDSC] = &mdss_0_disp_cc_mdss_core_gdsc, + [MDSS_DISP_CC_MDSS_CORE_INT2_GDSC] = &mdss_0_disp_cc_mdss_core_int2_gdsc, +}; + +static const struct qcom_reset_map disp_cc_0_nord_resets[] = { + [MDSS_DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, + [MDSS_DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, + [MDSS_DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, +}; + +static struct clk_alpha_pll *disp_cc_0_nord_plls[] = { + &mdss_0_disp_cc_pll0, + &mdss_0_disp_cc_pll1, + &mdss_0_disp_cc_pll2, + &mdss_0_disp_cc_pll3, +}; + +static const u32 disp_cc_0_nord_critical_cbcrs[] = { + 0xc00c, /* MDSS_DISP_CC_RSCC_AHB_CLK */ + 0xc008, /* MDSS_DISP_CC_RSCC_VSYNC_CLK */ + 0xe07c, /* MDSS_DISP_CC_SLEEP_CLK */ + 0xe05c, /* MDSS_DISP_CC_XO_CLK */ +}; + +static const struct regmap_config disp_cc_0_nord_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1a00c, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data disp_cc_0_nord_driver_data = { + .alpha_plls = disp_cc_0_nord_plls, + .num_alpha_plls = ARRAY_SIZE(disp_cc_0_nord_plls), + .clk_cbcrs = disp_cc_0_nord_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_0_nord_critical_cbcrs), +}; + +static const struct qcom_cc_desc disp_cc_0_nord_desc = { + .config = &disp_cc_0_nord_regmap_config, + .clks = disp_cc_0_nord_clocks, + .num_clks = ARRAY_SIZE(disp_cc_0_nord_clocks), + .resets = disp_cc_0_nord_resets, + .num_resets = ARRAY_SIZE(disp_cc_0_nord_resets), + .gdscs = disp_cc_0_nord_gdscs, + .num_gdscs = ARRAY_SIZE(disp_cc_0_nord_gdscs), + .use_rpm = true, + .driver_data = &disp_cc_0_nord_driver_data, +}; + +static const struct of_device_id disp_cc_0_nord_match_table[] = { + { .compatible = "qcom,nord-dispcc0" }, + { } +}; +MODULE_DEVICE_TABLE(of, disp_cc_0_nord_match_table); + +static int disp_cc_0_nord_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &disp_cc_0_nord_desc); +} + +static struct platform_driver disp_cc_0_nord_driver = { + .probe = disp_cc_0_nord_probe, + .driver = { + .name = "dispcc0-nord", + .of_match_table = disp_cc_0_nord_match_table, + }, +}; + +module_platform_driver(disp_cc_0_nord_driver); + +MODULE_DESCRIPTION("QTI DISPCC0 NORD Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/dispcc1-nord.c b/drivers/clk/qcom/dispcc1-nord.c new file mode 100644 index 000000000000..6b4efa735b9e --- /dev/null +++ b/drivers/clk/qcom/dispcc1-nord.c @@ -0,0 +1,2004 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_AHB_CLK, + DT_SLEEP_CLK, + + DT_DSI0_PHY_PLL_OUT_BYTECLK, + DT_DSI0_PHY_PLL_OUT_DSICLK, + DT_DSI1_PHY_PLL_OUT_BYTECLK, + DT_DSI1_PHY_PLL_OUT_DSICLK, + + DT_DP0_PHY_PLL_LINK_CLK, + DT_DP0_PHY_PLL_VCO_DIV_CLK, + DT_DP1_PHY_PLL_LINK_CLK, + DT_DP1_PHY_PLL_VCO_DIV_CLK, + DT_DP2_PHY_PLL_LINK_CLK, + DT_DP2_PHY_PLL_VCO_DIV_CLK, + DT_DP3_PHY_PLL_LINK_CLK, + DT_DP3_PHY_PLL_VCO_DIV_CLK, +}; + +enum { + P_BI_TCXO, + P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, + P_MDSS_1_DISP_CC_PLL1_OUT_EVEN, + P_MDSS_1_DISP_CC_PLL1_OUT_MAIN, + P_MDSS_1_DISP_CC_PLL2_OUT_MAIN, + P_MDSS_1_DISP_CC_PLL3_OUT_MAIN, + P_DP0_PHY_PLL_LINK_CLK, + P_DP0_PHY_PLL_VCO_DIV_CLK, + P_DP1_PHY_PLL_LINK_CLK, + P_DP1_PHY_PLL_VCO_DIV_CLK, + P_DP2_PHY_PLL_LINK_CLK, + P_DP2_PHY_PLL_VCO_DIV_CLK, + P_DP3_PHY_PLL_LINK_CLK, + P_DP3_PHY_PLL_VCO_DIV_CLK, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_DSI1_PHY_PLL_OUT_BYTECLK, + P_DSI1_PHY_PLL_OUT_DSICLK, + P_SLEEP_CLK, +}; + +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + +static const struct pll_vco zonda_ole_vco[] = { + { 700000000, 3600000000, 0 }, +}; + +/* 900.0 MHz Configuration */ +static const struct alpha_pll_config mdss_1_disp_cc_pll0_config = { + .l = 0x2e, + .alpha = 0xe000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll mdss_1_disp_cc_pll0 = { + .offset = 0x0, + .config = &mdss_1_disp_cc_pll0_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +/* 600.0 MHz Configuration */ +static const struct alpha_pll_config mdss_1_disp_cc_pll1_config = { + .l = 0x1f, + .alpha = 0x4000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll mdss_1_disp_cc_pll1 = { + .offset = 0x1000, + .config = &mdss_1_disp_cc_pll1_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +/* 1363.2 MHz Configuration */ +static const struct alpha_pll_config mdss_1_disp_cc_pll2_config = { + .l = 0x47, + .alpha = 0x0, + .config_ctl_val = 0x08240800, + .config_ctl_hi_val = 0x05008001, + .config_ctl_hi1_val = 0x00000000, + .config_ctl_hi2_val = 0x00000000, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000080, +}; + +static struct clk_alpha_pll mdss_1_disp_cc_pll2 = { + .offset = 0x2000, + .config = &mdss_1_disp_cc_pll2_config, + .vco_table = zonda_ole_vco, + .num_vco = ARRAY_SIZE(zonda_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_zonda_ole_ops, + }, + }, +}; + +/* 1363.2 MHz Configuration */ +static const struct alpha_pll_config mdss_1_disp_cc_pll3_config = { + .l = 0x47, + .alpha = 0x0, + .config_ctl_val = 0x08240800, + .config_ctl_hi_val = 0x05008001, + .config_ctl_hi1_val = 0x00000000, + .config_ctl_hi2_val = 0x00000000, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000080, +}; + +static struct clk_alpha_pll mdss_1_disp_cc_pll3 = { + .offset = 0x3000, + .config = &mdss_1_disp_cc_pll3_config, + .vco_table = zonda_ole_vco, + .num_vco = ARRAY_SIZE(zonda_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_zonda_ole_ops, + }, + }, +}; + +static const struct parent_map disp_cc_1_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_MDSS_1_DISP_CC_PLL2_OUT_MAIN, 1 }, + { P_DP0_PHY_PLL_VCO_DIV_CLK, 2 }, + { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 }, + { P_DP1_PHY_PLL_VCO_DIV_CLK, 4 }, + { P_MDSS_1_DISP_CC_PLL3_OUT_MAIN, 5 }, + { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_1_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &mdss_1_disp_cc_pll2.clkr.hw }, + { .index = DT_DP0_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP1_PHY_PLL_VCO_DIV_CLK }, + { .hw = &mdss_1_disp_cc_pll3.clkr.hw }, + { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map disp_cc_1_parent_map_1[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data disp_cc_1_parent_data_1[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map disp_cc_1_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 3 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_1_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_1_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_MDSS_1_DISP_CC_PLL2_OUT_MAIN, 1 }, + { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 }, + { P_MDSS_1_DISP_CC_PLL3_OUT_MAIN, 5 }, + { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_1_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &mdss_1_disp_cc_pll2.clkr.hw }, + { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK }, + { .hw = &mdss_1_disp_cc_pll3.clkr.hw }, + { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map disp_cc_1_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_DP0_PHY_PLL_LINK_CLK, 1 }, + { P_DP1_PHY_PLL_LINK_CLK, 2 }, + { P_DP2_PHY_PLL_LINK_CLK, 3 }, + { P_DP3_PHY_PLL_LINK_CLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_1_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP0_PHY_PLL_LINK_CLK }, + { .index = DT_DP1_PHY_PLL_LINK_CLK }, + { .index = DT_DP2_PHY_PLL_LINK_CLK }, + { .index = DT_DP3_PHY_PLL_LINK_CLK }, +}; + +static const struct parent_map disp_cc_1_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_DP2_PHY_PLL_LINK_CLK, 3 }, + { P_DP3_PHY_PLL_LINK_CLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_1_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP2_PHY_PLL_LINK_CLK }, + { .index = DT_DP3_PHY_PLL_LINK_CLK }, +}; + +static const struct parent_map disp_cc_1_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_1_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_1_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_MDSS_1_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_MDSS_1_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_1_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &mdss_1_disp_cc_pll1.clkr.hw }, + { .hw = &mdss_1_disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_1_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, 1 }, + { P_MDSS_1_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_MDSS_1_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_1_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &mdss_1_disp_cc_pll0.clkr.hw }, + { .hw = &mdss_1_disp_cc_pll1.clkr.hw }, + { .hw = &mdss_1_disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_1_parent_map_9[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data disp_cc_1_parent_data_9[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_mdss_1_disp_cc_mdss_ahb_clk_src[] = { + F(37500000, P_MDSS_1_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0), + F(75000000, P_MDSS_1_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0), + { } +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_ahb_clk_src = { + .cmd_rcgr = 0x837c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_7, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_ahb_clk_src", + .parent_data = disp_cc_1_parent_data_7, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_mdss_1_disp_cc_mdss_byte0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_byte0_clk_src = { + .cmd_rcgr = 0x813c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_2, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_byte0_clk_src", + .parent_data = disp_cc_1_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_byte1_clk_src = { + .cmd_rcgr = 0x8158, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_2, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_byte1_clk_src", + .parent_data = disp_cc_1_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_aux_clk_src = { + .cmd_rcgr = 0x8220, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_1, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_aux_clk_src", + .parent_data = disp_cc_1_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_link_clk_src = { + .cmd_rcgr = 0x81a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_4, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_link_clk_src", + .parent_data = disp_cc_1_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_pixel0_clk_src = { + .cmd_rcgr = 0x81c0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_0, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_pixel0_clk_src", + .parent_data = disp_cc_1_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_pixel1_clk_src = { + .cmd_rcgr = 0x81d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_0, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_pixel1_clk_src", + .parent_data = disp_cc_1_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_pixel2_clk_src = { + .cmd_rcgr = 0x81f0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_0, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_pixel2_clk_src", + .parent_data = disp_cc_1_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_pixel3_clk_src = { + .cmd_rcgr = 0x8208, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_0, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_pixel3_clk_src", + .parent_data = disp_cc_1_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx1_aux_clk_src = { + .cmd_rcgr = 0x82b4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_1, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_aux_clk_src", + .parent_data = disp_cc_1_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx1_link_clk_src = { + .cmd_rcgr = 0x8298, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_4, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_link_clk_src", + .parent_data = disp_cc_1_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx1_pixel0_clk_src = { + .cmd_rcgr = 0x8238, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_0, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_pixel0_clk_src", + .parent_data = disp_cc_1_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx1_pixel1_clk_src = { + .cmd_rcgr = 0x8250, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_0, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_pixel1_clk_src", + .parent_data = disp_cc_1_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx1_pixel2_clk_src = { + .cmd_rcgr = 0x8268, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_0, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_pixel2_clk_src", + .parent_data = disp_cc_1_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx1_pixel3_clk_src = { + .cmd_rcgr = 0x8280, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_0, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_pixel3_clk_src", + .parent_data = disp_cc_1_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx2_aux_clk_src = { + .cmd_rcgr = 0x8318, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_1, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx2_aux_clk_src", + .parent_data = disp_cc_1_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx2_link_clk_src = { + .cmd_rcgr = 0x82cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_5, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx2_link_clk_src", + .parent_data = disp_cc_1_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx2_pixel0_clk_src = { + .cmd_rcgr = 0x82e8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_3, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx2_pixel0_clk_src", + .parent_data = disp_cc_1_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx2_pixel1_clk_src = { + .cmd_rcgr = 0x8300, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_3, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx2_pixel1_clk_src", + .parent_data = disp_cc_1_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx3_aux_clk_src = { + .cmd_rcgr = 0x8364, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_1, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx3_aux_clk_src", + .parent_data = disp_cc_1_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx3_link_clk_src = { + .cmd_rcgr = 0x8348, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_5, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx3_link_clk_src", + .parent_data = disp_cc_1_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx3_pixel0_clk_src = { + .cmd_rcgr = 0x8330, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_3, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx3_pixel0_clk_src", + .parent_data = disp_cc_1_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_esc0_clk_src = { + .cmd_rcgr = 0x8174, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_6, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_esc0_clk_src", + .parent_data = disp_cc_1_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_esc1_clk_src = { + .cmd_rcgr = 0x818c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_6, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_esc1_clk_src", + .parent_data = disp_cc_1_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_mdss_1_disp_cc_mdss_mdp_clk_src[] = { + F(300000000, P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(417000000, P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(532000000, P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(650000000, P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(710000000, P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_mdp_clk_src = { + .cmd_rcgr = 0x810c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_8, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_mdp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_mdp_clk_src", + .parent_data = disp_cc_1_parent_data_8, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_pclk0_clk_src = { + .cmd_rcgr = 0x80c4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_2, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_pclk0_clk_src", + .parent_data = disp_cc_1_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_pclk1_clk_src = { + .cmd_rcgr = 0x80dc, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_2, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_pclk1_clk_src", + .parent_data = disp_cc_1_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_pclk2_clk_src = { + .cmd_rcgr = 0x80f4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_2, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_pclk2_clk_src", + .parent_data = disp_cc_1_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_mdss_vsync_clk_src = { + .cmd_rcgr = 0x8124, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_1, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_vsync_clk_src", + .parent_data = disp_cc_1_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_mdss_1_disp_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 mdss_1_disp_cc_sleep_clk_src = { + .cmd_rcgr = 0xe064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_9, + .freq_tbl = ftbl_mdss_1_disp_cc_sleep_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_sleep_clk_src", + .parent_data = disp_cc_1_parent_data_9, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mdss_1_disp_cc_xo_clk_src = { + .cmd_rcgr = 0xe044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_1_parent_map_1, + .freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_xo_clk_src", + .parent_data = disp_cc_1_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_1_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div mdss_1_disp_cc_mdss_byte0_div_clk_src = { + .reg = 0x8154, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_byte0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div mdss_1_disp_cc_mdss_byte1_div_clk_src = { + .reg = 0x8170, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_byte1_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div mdss_1_disp_cc_mdss_dptx0_link_div_clk_src = { + .reg = 0x81bc, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div mdss_1_disp_cc_mdss_dptx1_link_div_clk_src = { + .reg = 0x82b0, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div mdss_1_disp_cc_mdss_dptx2_link_div_clk_src = { + .reg = 0x82e4, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx2_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div mdss_1_disp_cc_mdss_dptx3_link_div_clk_src = { + .reg = 0x8360, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx3_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_accu_shift_clk = { + .halt_reg = 0xe060, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xe060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_accu_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_ahb1_clk = { + .halt_reg = 0xa028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_ahb1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_ahb_clk = { + .halt_reg = 0x80c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_byte0_clk = { + .halt_reg = 0x8034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_byte0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_byte0_intf_clk = { + .halt_reg = 0x8038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_byte0_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_byte0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_byte1_clk = { + .halt_reg = 0x803c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x803c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_byte1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_byte1_intf_clk = { + .halt_reg = 0x8040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_byte1_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_byte1_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx0_aux_clk = { + .halt_reg = 0x806c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x806c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx0_crypto_clk = { + .halt_reg = 0x8058, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx0_link_clk = { + .halt_reg = 0x804c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx0_link_intf_clk = { + .halt_reg = 0x8054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx0_pixel0_clk = { + .halt_reg = 0x805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx0_pixel1_clk = { + .halt_reg = 0x8060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx0_pixel2_clk = { + .halt_reg = 0x8064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_pixel2_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx0_pixel2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx0_pixel3_clk = { + .halt_reg = 0x8068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_pixel3_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx0_pixel3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx0_usb_router_link_intf_clk = { + .halt_reg = 0x8050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx0_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx1_aux_clk = { + .halt_reg = 0x8090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx1_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx1_crypto_clk = { + .halt_reg = 0x808c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x808c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx1_link_clk = { + .halt_reg = 0x8080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx1_link_intf_clk = { + .halt_reg = 0x8088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx1_pixel0_clk = { + .halt_reg = 0x8070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx1_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx1_pixel1_clk = { + .halt_reg = 0x8074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx1_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx1_pixel2_clk = { + .halt_reg = 0x8078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_pixel2_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx1_pixel2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx1_pixel3_clk = { + .halt_reg = 0x807c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x807c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_pixel3_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx1_pixel3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx1_usb_router_link_intf_clk = { + .halt_reg = 0x8084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8084, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx1_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx2_aux_clk = { + .halt_reg = 0x80a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx2_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx2_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx2_crypto_clk = { + .halt_reg = 0x80a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x80a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx2_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx2_link_clk = { + .halt_reg = 0x809c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x809c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx2_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx2_link_intf_clk = { + .halt_reg = 0x80a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx2_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx2_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx2_pixel0_clk = { + .halt_reg = 0x8094, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8094, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx2_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx2_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx2_pixel1_clk = { + .halt_reg = 0x8098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8098, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx2_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx2_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx3_aux_clk = { + .halt_reg = 0x80b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx3_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx3_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx3_crypto_clk = { + .halt_reg = 0x80bc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x80bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx3_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx3_link_clk = { + .halt_reg = 0x80b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx3_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx3_link_intf_clk = { + .halt_reg = 0x80b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx3_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx3_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_dptx3_pixel0_clk = { + .halt_reg = 0x80ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_dptx3_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_dptx3_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_esc0_clk = { + .halt_reg = 0x8044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_esc0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_esc0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_esc1_clk = { + .halt_reg = 0x8048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_esc1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_esc1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_mdp1_clk = { + .halt_reg = 0xa004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_mdp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_mdp_clk = { + .halt_reg = 0x8010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_mdp_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_mdp_lut1_clk = { + .halt_reg = 0xa014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xa014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_mdp_lut1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_mdp_lut_clk = { + .halt_reg = 0x8020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_mdp_lut_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_non_gdsc_ahb_clk = { + .halt_reg = 0xc004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xc004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_non_gdsc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_pclk0_clk = { + .halt_reg = 0x8004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_pclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_pclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_pclk1_clk = { + .halt_reg = 0x8008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_pclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_pclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_pclk2_clk = { + .halt_reg = 0x800c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x800c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_pclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_pclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_vsync1_clk = { + .halt_reg = 0xa024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_vsync1_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_1_disp_cc_mdss_vsync_clk = { + .halt_reg = 0x8030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "mdss_1_disp_cc_mdss_vsync_clk", + .parent_hws = (const struct clk_hw*[]) { + &mdss_1_disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc mdss_1_disp_cc_mdss_core_gdsc = { + .gdscr = 0x9000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "mdss_1_disp_cc_mdss_core_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc mdss_1_disp_cc_mdss_core_int2_gdsc = { + .gdscr = 0xb000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "mdss_1_disp_cc_mdss_core_int2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *disp_cc_1_nord_clocks[] = { + [MDSS_DISP_CC_MDSS_ACCU_SHIFT_CLK] = &mdss_1_disp_cc_mdss_accu_shift_clk.clkr, + [MDSS_DISP_CC_MDSS_AHB1_CLK] = &mdss_1_disp_cc_mdss_ahb1_clk.clkr, + [MDSS_DISP_CC_MDSS_AHB_CLK] = &mdss_1_disp_cc_mdss_ahb_clk.clkr, + [MDSS_DISP_CC_MDSS_AHB_CLK_SRC] = &mdss_1_disp_cc_mdss_ahb_clk_src.clkr, + [MDSS_DISP_CC_MDSS_BYTE0_CLK] = &mdss_1_disp_cc_mdss_byte0_clk.clkr, + [MDSS_DISP_CC_MDSS_BYTE0_CLK_SRC] = &mdss_1_disp_cc_mdss_byte0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &mdss_1_disp_cc_mdss_byte0_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_BYTE0_INTF_CLK] = &mdss_1_disp_cc_mdss_byte0_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_BYTE1_CLK] = &mdss_1_disp_cc_mdss_byte1_clk.clkr, + [MDSS_DISP_CC_MDSS_BYTE1_CLK_SRC] = &mdss_1_disp_cc_mdss_byte1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = &mdss_1_disp_cc_mdss_byte1_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_BYTE1_INTF_CLK] = &mdss_1_disp_cc_mdss_byte1_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK] = &mdss_1_disp_cc_mdss_dptx0_aux_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_aux_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_CRYPTO_CLK] = &mdss_1_disp_cc_mdss_dptx0_crypto_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK] = &mdss_1_disp_cc_mdss_dptx0_link_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_link_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] = + &mdss_1_disp_cc_mdss_dptx0_link_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &mdss_1_disp_cc_mdss_dptx0_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &mdss_1_disp_cc_mdss_dptx0_pixel0_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_pixel0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &mdss_1_disp_cc_mdss_dptx0_pixel1_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_pixel1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK] = &mdss_1_disp_cc_mdss_dptx0_pixel2_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_pixel2_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK] = &mdss_1_disp_cc_mdss_dptx0_pixel3_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_pixel3_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] = + &mdss_1_disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK] = &mdss_1_disp_cc_mdss_dptx1_aux_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx1_aux_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_CRYPTO_CLK] = &mdss_1_disp_cc_mdss_dptx1_crypto_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK] = &mdss_1_disp_cc_mdss_dptx1_link_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx1_link_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC] = + &mdss_1_disp_cc_mdss_dptx1_link_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_LINK_INTF_CLK] = &mdss_1_disp_cc_mdss_dptx1_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK] = &mdss_1_disp_cc_mdss_dptx1_pixel0_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx1_pixel0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK] = &mdss_1_disp_cc_mdss_dptx1_pixel1_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx1_pixel1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL2_CLK] = &mdss_1_disp_cc_mdss_dptx1_pixel2_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL2_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx1_pixel2_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL3_CLK] = &mdss_1_disp_cc_mdss_dptx1_pixel3_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_PIXEL3_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx1_pixel3_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK] = + &mdss_1_disp_cc_mdss_dptx1_usb_router_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_AUX_CLK] = &mdss_1_disp_cc_mdss_dptx2_aux_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_AUX_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx2_aux_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_CRYPTO_CLK] = &mdss_1_disp_cc_mdss_dptx2_crypto_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_LINK_CLK] = &mdss_1_disp_cc_mdss_dptx2_link_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_LINK_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx2_link_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC] = + &mdss_1_disp_cc_mdss_dptx2_link_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_LINK_INTF_CLK] = &mdss_1_disp_cc_mdss_dptx2_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_PIXEL0_CLK] = &mdss_1_disp_cc_mdss_dptx2_pixel0_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx2_pixel0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_PIXEL1_CLK] = &mdss_1_disp_cc_mdss_dptx2_pixel1_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx2_pixel1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_AUX_CLK] = &mdss_1_disp_cc_mdss_dptx3_aux_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_AUX_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx3_aux_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_CRYPTO_CLK] = &mdss_1_disp_cc_mdss_dptx3_crypto_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_LINK_CLK] = &mdss_1_disp_cc_mdss_dptx3_link_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_LINK_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx3_link_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC] = + &mdss_1_disp_cc_mdss_dptx3_link_div_clk_src.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_LINK_INTF_CLK] = &mdss_1_disp_cc_mdss_dptx3_link_intf_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_PIXEL0_CLK] = &mdss_1_disp_cc_mdss_dptx3_pixel0_clk.clkr, + [MDSS_DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx3_pixel0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_ESC0_CLK] = &mdss_1_disp_cc_mdss_esc0_clk.clkr, + [MDSS_DISP_CC_MDSS_ESC0_CLK_SRC] = &mdss_1_disp_cc_mdss_esc0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_ESC1_CLK] = &mdss_1_disp_cc_mdss_esc1_clk.clkr, + [MDSS_DISP_CC_MDSS_ESC1_CLK_SRC] = &mdss_1_disp_cc_mdss_esc1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_MDP1_CLK] = &mdss_1_disp_cc_mdss_mdp1_clk.clkr, + [MDSS_DISP_CC_MDSS_MDP_CLK] = &mdss_1_disp_cc_mdss_mdp_clk.clkr, + [MDSS_DISP_CC_MDSS_MDP_CLK_SRC] = &mdss_1_disp_cc_mdss_mdp_clk_src.clkr, + [MDSS_DISP_CC_MDSS_MDP_LUT1_CLK] = &mdss_1_disp_cc_mdss_mdp_lut1_clk.clkr, + [MDSS_DISP_CC_MDSS_MDP_LUT_CLK] = &mdss_1_disp_cc_mdss_mdp_lut_clk.clkr, + [MDSS_DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &mdss_1_disp_cc_mdss_non_gdsc_ahb_clk.clkr, + [MDSS_DISP_CC_MDSS_PCLK0_CLK] = &mdss_1_disp_cc_mdss_pclk0_clk.clkr, + [MDSS_DISP_CC_MDSS_PCLK0_CLK_SRC] = &mdss_1_disp_cc_mdss_pclk0_clk_src.clkr, + [MDSS_DISP_CC_MDSS_PCLK1_CLK] = &mdss_1_disp_cc_mdss_pclk1_clk.clkr, + [MDSS_DISP_CC_MDSS_PCLK1_CLK_SRC] = &mdss_1_disp_cc_mdss_pclk1_clk_src.clkr, + [MDSS_DISP_CC_MDSS_PCLK2_CLK] = &mdss_1_disp_cc_mdss_pclk2_clk.clkr, + [MDSS_DISP_CC_MDSS_PCLK2_CLK_SRC] = &mdss_1_disp_cc_mdss_pclk2_clk_src.clkr, + [MDSS_DISP_CC_MDSS_VSYNC1_CLK] = &mdss_1_disp_cc_mdss_vsync1_clk.clkr, + [MDSS_DISP_CC_MDSS_VSYNC_CLK] = &mdss_1_disp_cc_mdss_vsync_clk.clkr, + [MDSS_DISP_CC_MDSS_VSYNC_CLK_SRC] = &mdss_1_disp_cc_mdss_vsync_clk_src.clkr, + [MDSS_DISP_CC_PLL0] = &mdss_1_disp_cc_pll0.clkr, + [MDSS_DISP_CC_PLL1] = &mdss_1_disp_cc_pll1.clkr, + [MDSS_DISP_CC_PLL2] = &mdss_1_disp_cc_pll2.clkr, + [MDSS_DISP_CC_PLL3] = &mdss_1_disp_cc_pll3.clkr, + [MDSS_DISP_CC_SLEEP_CLK_SRC] = &mdss_1_disp_cc_sleep_clk_src.clkr, + [MDSS_DISP_CC_XO_CLK_SRC] = &mdss_1_disp_cc_xo_clk_src.clkr, +}; + +static struct gdsc *disp_cc_1_nord_gdscs[] = { + [MDSS_DISP_CC_MDSS_CORE_GDSC] = &mdss_1_disp_cc_mdss_core_gdsc, + [MDSS_DISP_CC_MDSS_CORE_INT2_GDSC] = &mdss_1_disp_cc_mdss_core_int2_gdsc, +}; + +static const struct qcom_reset_map disp_cc_1_nord_resets[] = { + [MDSS_DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, + [MDSS_DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, + [MDSS_DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, +}; + +static struct clk_alpha_pll *disp_cc_1_nord_plls[] = { + &mdss_1_disp_cc_pll0, + &mdss_1_disp_cc_pll1, + &mdss_1_disp_cc_pll2, + &mdss_1_disp_cc_pll3, +}; + +static const u32 disp_cc_1_nord_critical_cbcrs[] = { + 0xc00c, /* MDSS_DISP_CC_RSCC_AHB_CLK */ + 0xc008, /* MDSS_DISP_CC_RSCC_VSYNC CLK */ + 0xe07c, /* MDSS_DISP_CC_SLEEP_CLK */ + 0xe05c, /* MDSS_DISP_CC_XO_CLK */ +}; + +static const struct regmap_config disp_cc_1_nord_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1a00c, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data disp_cc_1_nord_driver_data = { + .alpha_plls = disp_cc_1_nord_plls, + .num_alpha_plls = ARRAY_SIZE(disp_cc_1_nord_plls), + .clk_cbcrs = disp_cc_1_nord_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_1_nord_critical_cbcrs), +}; + +static const struct qcom_cc_desc disp_cc_1_nord_desc = { + .config = &disp_cc_1_nord_regmap_config, + .clks = disp_cc_1_nord_clocks, + .num_clks = ARRAY_SIZE(disp_cc_1_nord_clocks), + .resets = disp_cc_1_nord_resets, + .num_resets = ARRAY_SIZE(disp_cc_1_nord_resets), + .gdscs = disp_cc_1_nord_gdscs, + .num_gdscs = ARRAY_SIZE(disp_cc_1_nord_gdscs), + .use_rpm = true, + .driver_data = &disp_cc_1_nord_driver_data, +}; + +static const struct of_device_id disp_cc_1_nord_match_table[] = { + { .compatible = "qcom,nord-dispcc1" }, + { } +}; +MODULE_DEVICE_TABLE(of, disp_cc_1_nord_match_table); + +static int disp_cc_1_nord_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &disp_cc_1_nord_desc); +} + +static struct platform_driver disp_cc_1_nord_driver = { + .probe = disp_cc_1_nord_probe, + .driver = { + .name = "dispcc1-nord", + .of_match_table = disp_cc_1_nord_match_table, + }, +}; + +module_platform_driver(disp_cc_1_nord_driver); + +MODULE_DESCRIPTION("QTI DISPCC1 NORD Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/evacc-glymur.c b/drivers/clk/qcom/evacc-glymur.c new file mode 100644 index 000000000000..7f031b05a94a --- /dev/null +++ b/drivers/clk/qcom/evacc-glymur.c @@ -0,0 +1,454 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_AHB_CLK, + DT_BI_TCXO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_EVA_CC_PLL0_OUT_MAIN, + P_SLEEP_CLK, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 840.0 MHz Configuration */ +static const struct alpha_pll_config eva_cc_pll0_config = { + .l = 0x2b, + .alpha = 0xc000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll eva_cc_pll0 = { + .offset = 0x0, + .config = &eva_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "eva_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct parent_map eva_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data eva_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map eva_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_EVA_CC_PLL0_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data eva_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &eva_cc_pll0.clkr.hw }, +}; + +static const struct parent_map eva_cc_parent_map_2[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data eva_cc_parent_data_2[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_eva_cc_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 eva_cc_ahb_clk_src = { + .cmd_rcgr = 0x8018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = eva_cc_parent_map_0, + .freq_tbl = ftbl_eva_cc_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "eva_cc_ahb_clk_src", + .parent_data = eva_cc_parent_data_0, + .num_parents = ARRAY_SIZE(eva_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_eva_cc_mvs0_clk_src[] = { + F(840000000, P_EVA_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1050000000, P_EVA_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1350000000, P_EVA_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1500000000, P_EVA_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1650000000, P_EVA_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 eva_cc_mvs0_clk_src = { + .cmd_rcgr = 0x8000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = eva_cc_parent_map_1, + .freq_tbl = ftbl_eva_cc_mvs0_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "eva_cc_mvs0_clk_src", + .parent_data = eva_cc_parent_data_1, + .num_parents = ARRAY_SIZE(eva_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_eva_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 eva_cc_sleep_clk_src = { + .cmd_rcgr = 0x80e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = eva_cc_parent_map_2, + .freq_tbl = ftbl_eva_cc_sleep_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "eva_cc_sleep_clk_src", + .parent_data = eva_cc_parent_data_2, + .num_parents = ARRAY_SIZE(eva_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_rcg2 eva_cc_xo_clk_src = { + .cmd_rcgr = 0x80bc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = eva_cc_parent_map_0, + .freq_tbl = ftbl_eva_cc_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "eva_cc_xo_clk_src", + .parent_data = eva_cc_parent_data_0, + .num_parents = ARRAY_SIZE(eva_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, + }, +}; + +static struct clk_regmap_div eva_cc_mvs0_div_clk_src = { + .reg = 0x809c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "eva_cc_mvs0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &eva_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div eva_cc_mvs0c_div2_div_clk_src = { + .reg = 0x8060, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "eva_cc_mvs0c_div2_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &eva_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch eva_cc_mvs0_clk = { + .halt_reg = 0x807c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x807c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x807c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "eva_cc_mvs0_clk", + .parent_hws = (const struct clk_hw*[]) { + &eva_cc_mvs0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch eva_cc_mvs0_freerun_clk = { + .halt_reg = 0x808c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x808c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "eva_cc_mvs0_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &eva_cc_mvs0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch eva_cc_mvs0_shift_clk = { + .halt_reg = 0x80d8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80d8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "eva_cc_mvs0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &eva_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch eva_cc_mvs0c_clk = { + .halt_reg = 0x804c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "eva_cc_mvs0c_clk", + .parent_hws = (const struct clk_hw*[]) { + &eva_cc_mvs0c_div2_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch eva_cc_mvs0c_freerun_clk = { + .halt_reg = 0x805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "eva_cc_mvs0c_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &eva_cc_mvs0c_div2_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch eva_cc_mvs0c_shift_clk = { + .halt_reg = 0x80dc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80dc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "eva_cc_mvs0c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &eva_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc eva_cc_mvs0c_gdsc = { + .gdscr = 0x8034, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "eva_cc_mvs0c_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc eva_cc_mvs0_gdsc = { + .gdscr = 0x8068, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "eva_cc_mvs0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &eva_cc_mvs0c_gdsc.pd, +}; + +static struct clk_regmap *eva_cc_glymur_clocks[] = { + [EVA_CC_AHB_CLK_SRC] = &eva_cc_ahb_clk_src.clkr, + [EVA_CC_MVS0_CLK] = &eva_cc_mvs0_clk.clkr, + [EVA_CC_MVS0_CLK_SRC] = &eva_cc_mvs0_clk_src.clkr, + [EVA_CC_MVS0_DIV_CLK_SRC] = &eva_cc_mvs0_div_clk_src.clkr, + [EVA_CC_MVS0_FREERUN_CLK] = &eva_cc_mvs0_freerun_clk.clkr, + [EVA_CC_MVS0_SHIFT_CLK] = &eva_cc_mvs0_shift_clk.clkr, + [EVA_CC_MVS0C_CLK] = &eva_cc_mvs0c_clk.clkr, + [EVA_CC_MVS0C_DIV2_DIV_CLK_SRC] = &eva_cc_mvs0c_div2_div_clk_src.clkr, + [EVA_CC_MVS0C_FREERUN_CLK] = &eva_cc_mvs0c_freerun_clk.clkr, + [EVA_CC_MVS0C_SHIFT_CLK] = &eva_cc_mvs0c_shift_clk.clkr, + [EVA_CC_PLL0] = &eva_cc_pll0.clkr, + [EVA_CC_SLEEP_CLK_SRC] = &eva_cc_sleep_clk_src.clkr, + [EVA_CC_XO_CLK_SRC] = &eva_cc_xo_clk_src.clkr, +}; + +static struct gdsc *eva_cc_glymur_gdscs[] = { + [EVA_CC_MVS0_GDSC] = &eva_cc_mvs0_gdsc, + [EVA_CC_MVS0C_GDSC] = &eva_cc_mvs0c_gdsc, +}; + +static const struct qcom_reset_map eva_cc_glymur_resets[] = { + [EVA_CC_INTERFACE_BCR] = { 0x80a0 }, + [EVA_CC_MVS0_BCR] = { 0x8064 }, + [EVA_CC_MVS0C_CLK_ARES] = { 0x804c, 2 }, + [EVA_CC_MVS0C_BCR] = { 0x8030 }, + [EVA_CC_MVS0C_FREERUN_CLK_ARES] = { 0x805c, 2 }, +}; + +static struct clk_alpha_pll *eva_cc_glymur_plls[] = { + &eva_cc_pll0, +}; + +static const u32 eva_cc_glymur_critical_cbcrs[] = { + 0x80a4, /* EVA_CC_AHB_CLK */ + 0x80f8, /* EVA_CC_SLEEP_CLK */ + 0x80d4, /* EVA_CC_XO_CLK */ +}; + +static const struct regmap_config eva_cc_glymur_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9f50, + .fast_io = true, +}; + +static void clk_glymur_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* + * Update CTRL_IN register as per HW recommendation to ensure clocks + * stay cycle‑aligned when the EVA core is ON. + */ + regmap_set_bits(regmap, 0x9f24, BIT(0)); +} + +static const struct qcom_cc_driver_data eva_cc_glymur_driver_data = { + .alpha_plls = eva_cc_glymur_plls, + .num_alpha_plls = ARRAY_SIZE(eva_cc_glymur_plls), + .clk_cbcrs = eva_cc_glymur_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(eva_cc_glymur_critical_cbcrs), + .clk_regs_configure = clk_glymur_regs_configure, +}; + +static const struct qcom_cc_desc eva_cc_glymur_desc = { + .config = &eva_cc_glymur_regmap_config, + .clks = eva_cc_glymur_clocks, + .num_clks = ARRAY_SIZE(eva_cc_glymur_clocks), + .resets = eva_cc_glymur_resets, + .num_resets = ARRAY_SIZE(eva_cc_glymur_resets), + .gdscs = eva_cc_glymur_gdscs, + .num_gdscs = ARRAY_SIZE(eva_cc_glymur_gdscs), + .use_rpm = true, + .driver_data = &eva_cc_glymur_driver_data, +}; + +static const struct of_device_id eva_cc_glymur_match_table[] = { + { .compatible = "qcom,glymur-evacc" }, + { } +}; +MODULE_DEVICE_TABLE(of, eva_cc_glymur_match_table); + +static int eva_cc_glymur_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &eva_cc_glymur_desc); +} + +static struct platform_driver eva_cc_glymur_driver = { + .probe = eva_cc_glymur_probe, + .driver = { + .name = "evacc-glymur", + .of_match_table = eva_cc_glymur_match_table, + }, +}; + +module_platform_driver(eva_cc_glymur_driver); + +MODULE_DESCRIPTION("QTI EVACC Glymur Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-glymur.c b/drivers/clk/qcom/gcc-glymur.c index f4ede4a3a1c0..2ee4820b6fdf 100644 --- a/drivers/clk/qcom/gcc-glymur.c +++ b/drivers/clk/qcom/gcc-glymur.c @@ -3668,21 +3668,6 @@ static struct clk_branch gcc_disp_hf_axi_clk = { }, }; -static struct clk_branch gcc_eva_ahb_clk = { - .halt_reg = 0x9b004, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x9b004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x9b004, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "gcc_eva_ahb_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_eva_axi0_clk = { .halt_reg = 0x9b008, .halt_check = BRANCH_HALT_SKIP, @@ -3713,19 +3698,6 @@ static struct clk_branch gcc_eva_axi0c_clk = { }, }; -static struct clk_branch gcc_eva_xo_clk = { - .halt_reg = 0x9b024, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x9b024, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "gcc_eva_xo_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gp1_clk = { .halt_reg = 0x64000, .halt_check = BRANCH_HALT, @@ -7992,10 +7964,8 @@ static struct clk_regmap *gcc_glymur_clocks[] = { [GCC_CFG_NOC_USB_ANOC_AHB_CLK] = &gcc_cfg_noc_usb_anoc_ahb_clk.clkr, [GCC_CFG_NOC_USB_ANOC_SOUTH_AHB_CLK] = &gcc_cfg_noc_usb_anoc_south_ahb_clk.clkr, [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, - [GCC_EVA_AHB_CLK] = &gcc_eva_ahb_clk.clkr, [GCC_EVA_AXI0_CLK] = &gcc_eva_axi0_clk.clkr, [GCC_EVA_AXI0C_CLK] = &gcc_eva_axi0c_clk.clkr, - [GCC_EVA_XO_CLK] = &gcc_eva_xo_clk.clkr, [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, @@ -8544,6 +8514,8 @@ static const u32 gcc_glymur_critical_cbcrs[] = { 0x71004, /* GCC_GPU_CFG_AHB_CLK */ 0x32004, /* GCC_VIDEO_AHB_CLK */ 0x32058, /* GCC_VIDEO_XO_CLK */ + 0x9b004, /* GCC_EVA_AHB_CLK */ + 0x9b024, /* GCC_EVA_XO_CLK */ }; static const struct regmap_config gcc_glymur_regmap_config = { @@ -8576,6 +8548,7 @@ static const struct qcom_cc_desc gcc_glymur_desc = { .num_resets = ARRAY_SIZE(gcc_glymur_resets), .gdscs = gcc_glymur_gdscs, .num_gdscs = ARRAY_SIZE(gcc_glymur_gdscs), + .use_rpm = true, .driver_data = &gcc_glymur_driver_data, }; diff --git a/drivers/clk/qcom/gcc-hawi.c b/drivers/clk/qcom/gcc-hawi.c index 018411e4f402..6fb5a3db9586 100644 --- a/drivers/clk/qcom/gcc-hawi.c +++ b/drivers/clk/qcom/gcc-hawi.c @@ -10,6 +10,7 @@ #include #include +#include #include "clk-alpha-pll.h" #include "clk-branch.h" @@ -1114,6 +1115,31 @@ static struct clk_rcg2 gcc_qupv3_wrap4_s4_clk_src = { .clkr.hw.init = &gcc_qupv3_wrap4_s4_clk_src_init, }; +static const struct freq_tbl ftbl_gcc_qupv3_wrap5_qspi_ref_clk_src[] = { + F(150000000, P_GCC_GPLL0_OUT_EVEN, 2, 0, 0), + F(196078431, P_GCC_GPLL0_OUT_EVEN, 1, 100, 153), + F(300000000, P_GCC_GPLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap5_qspi_ref_clk_src_init = { + .name = "gcc_qupv3_wrap5_qspi_ref_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap5_qspi_ref_clk_src = { + .cmd_rcgr = 0xad024, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap5_qspi_ref_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap5_qspi_ref_clk_src_init, +}; + static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { F(400000, P_BI_TCXO, 12, 1, 4), F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), @@ -1281,6 +1307,21 @@ static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { }, }; +static struct clk_regmap_div gcc_qupv3_wrap5_s0_clk_src = { + .reg = 0xad018, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap5_s0_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap5_qspi_ref_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { .cmd_rcgr = 0x3904c, .mnd_width = 0, @@ -2739,6 +2780,68 @@ static struct clk_branch gcc_qupv3_wrap4_s4_clk = { }, }; +static struct clk_branch gcc_qupv3_wrap5_core_2x_clk = { + .halt_reg = 0x236bc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap5_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap5_core_clk = { + .halt_reg = 0x236a8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap5_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap5_qspi_ref_clk = { + .halt_reg = 0xad01c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap5_qspi_ref_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap5_qspi_ref_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap5_s0_clk = { + .halt_reg = 0xad004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap5_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap5_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_qupv3_wrap_1_m_axi_clk = { .halt_reg = 0x23140, .halt_check = BRANCH_HALT_VOTED, @@ -2859,6 +2962,36 @@ static struct clk_branch gcc_qupv3_wrap_4_s_ahb_clk = { }, }; +static struct clk_branch gcc_qupv3_wrap_5_m_ahb_clk = { + .halt_reg = 0x236a0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x236a0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_5_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_5_s_ahb_clk = { + .halt_reg = 0x236a4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x236a4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_5_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_sdcc2_ahb_clk = { .halt_reg = 0x14014, .halt_check = BRANCH_HALT, @@ -3484,6 +3617,11 @@ static struct clk_regmap *gcc_hawi_clocks[] = { [GCC_USB3_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb3_prim_phy_pipe_clk_src.clkr, [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, [GCC_VIDEO_AXI0C_CLK] = &gcc_video_axi0c_clk.clkr, + /* + * Maili has more clocks than Hawi. Ensure the array is appropriately + * sized and assign the additional clocks in .probe() + */ + [GCC_QUPV3_WRAP_5_S_AHB_CLK] = NULL, }; static struct gdsc *gcc_hawi_gdscs[] = { @@ -3587,6 +3725,34 @@ static const struct clk_rcg_dfs_data gcc_hawi_dfs_clocks[] = { DEFINE_RCG_DFS(gcc_qupv3_wrap4_s4_clk_src), }; +static const struct clk_rcg_dfs_data gcc_maili_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap1_qspi_ref_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_qspi_ref_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap5_qspi_ref_clk_src), +}; + static const struct regmap_config gcc_hawi_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -3621,14 +3787,49 @@ static const struct qcom_cc_desc gcc_hawi_desc = { .driver_data = &gcc_hawi_driver_data, }; +static const struct qcom_cc_driver_data gcc_maili_driver_data = { + .clk_cbcrs = gcc_hawi_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_hawi_critical_cbcrs), + .dfs_rcgs = gcc_maili_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_maili_dfs_clocks), + .clk_regs_configure = clk_hawi_regs_configure, +}; + +static const struct qcom_cc_desc gcc_maili_desc = { + .config = &gcc_hawi_regmap_config, + .clks = gcc_hawi_clocks, + .num_clks = ARRAY_SIZE(gcc_hawi_clocks), + .resets = gcc_hawi_resets, + .num_resets = ARRAY_SIZE(gcc_hawi_resets), + .gdscs = gcc_hawi_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_hawi_gdscs), + .use_rpm = true, + .driver_data = &gcc_maili_driver_data, +}; + static const struct of_device_id gcc_hawi_match_table[] = { { .compatible = "qcom,hawi-gcc" }, + { .compatible = "qcom,maili-gcc" }, { } }; MODULE_DEVICE_TABLE(of, gcc_hawi_match_table); static int gcc_hawi_probe(struct platform_device *pdev) { + if (of_device_is_compatible(pdev->dev.of_node, "qcom,maili-gcc")) { + gcc_hawi_clocks[GCC_QUPV3_WRAP5_CORE_2X_CLK] = &gcc_qupv3_wrap5_core_2x_clk.clkr; + gcc_hawi_clocks[GCC_QUPV3_WRAP5_CORE_CLK] = &gcc_qupv3_wrap5_core_clk.clkr; + gcc_hawi_clocks[GCC_QUPV3_WRAP5_QSPI_REF_CLK] = &gcc_qupv3_wrap5_qspi_ref_clk.clkr; + gcc_hawi_clocks[GCC_QUPV3_WRAP5_QSPI_REF_CLK_SRC] = + &gcc_qupv3_wrap5_qspi_ref_clk_src.clkr; + gcc_hawi_clocks[GCC_QUPV3_WRAP5_S0_CLK] = &gcc_qupv3_wrap5_s0_clk.clkr; + gcc_hawi_clocks[GCC_QUPV3_WRAP5_S0_CLK_SRC] = &gcc_qupv3_wrap5_s0_clk_src.clkr; + gcc_hawi_clocks[GCC_QUPV3_WRAP_5_M_AHB_CLK] = &gcc_qupv3_wrap_5_m_ahb_clk.clkr; + gcc_hawi_clocks[GCC_QUPV3_WRAP_5_S_AHB_CLK] = &gcc_qupv3_wrap_5_s_ahb_clk.clkr; + + return qcom_cc_probe(pdev, &gcc_maili_desc); + } + return qcom_cc_probe(pdev, &gcc_hawi_desc); } diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c index 35af6ffeeb85..3ddd4b3aedea 100644 --- a/drivers/clk/qcom/gcc-ipq5424.c +++ b/drivers/clk/qcom/gcc-ipq5424.c @@ -139,17 +139,6 @@ static struct clk_alpha_pll gpll4 = { .parent_data = &gcc_parent_data_xo, .num_parents = 1, .ops = &clk_alpha_pll_ops, - /* - * There are no consumers for this GPLL in kernel yet, - * (will be added soon), so the clock framework - * disables this source. But some of the clocks - * initialized by boot loaders uses this source. So we - * need to keep this clock ON. Add the - * CLK_IGNORE_UNUSED flag so the clock will not be - * disabled. Once the consumer in kernel is added, we - * can get rid of this flag. - */ - .flags = CLK_IGNORE_UNUSED, }, }, }; diff --git a/drivers/clk/qcom/gcc-ipq9650.c b/drivers/clk/qcom/gcc-ipq9650.c index c556c2bbfd96..e65a52fdfa91 100644 --- a/drivers/clk/qcom/gcc-ipq9650.c +++ b/drivers/clk/qcom/gcc-ipq9650.c @@ -3022,6 +3022,90 @@ static struct clk_branch gcc_usb1_sleep_clk = { }, }; +static struct clk_rcg2 gcc_refgen_core_clk_src = { + .cmd_rcgr = 0x23004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_nss_ts_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_refgen_core_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_refgen_cmn_uphy_core_clk = { + .halt_reg = 0x2300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2300c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_refgen_cmn_uphy_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_refgen_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_refgen_pcie_core_clk = { + .halt_reg = 0x23020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x23020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_refgen_pcie_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_refgen_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_refgen_pcie_hclk = { + .halt_reg = 0x23024, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x23024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_refgen_pcie_hclk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcnoc_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_refgen_cmn_uphy_hclk = { + .halt_reg = 0x23010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x23010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_refgen_cmn_uphy_hclk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcnoc_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_regmap *gcc_ipq9650_clocks[] = { [GCC_ADSS_PWM_CLK] = &gcc_adss_pwm_clk.clkr, [GCC_ADSS_PWM_CLK_SRC] = &gcc_adss_pwm_clk_src.clkr, @@ -3179,6 +3263,11 @@ static struct clk_regmap *gcc_ipq9650_clocks[] = { [GPLL2] = &gpll2.clkr, [GPLL2_OUT_MAIN] = &gpll2_out_main.clkr, [GPLL4] = &gpll4.clkr, + [GCC_REFGEN_CORE_CLK_SRC] = &gcc_refgen_core_clk_src.clkr, + [GCC_REFGEN_PCIE_CORE_CLK] = &gcc_refgen_pcie_core_clk.clkr, + [GCC_REFGEN_PCIE_HCLK] = &gcc_refgen_pcie_hclk.clkr, + [GCC_REFGEN_CMN_UPHY_HCLK] = &gcc_refgen_cmn_uphy_hclk.clkr, + [GCC_REFGEN_CMN_UPHY_CORE_CLK] = &gcc_refgen_cmn_uphy_core_clk.clkr, }; static const struct qcom_reset_map gcc_ipq9650_resets[] = { diff --git a/drivers/clk/qcom/gcc-mdm9607.c b/drivers/clk/qcom/gcc-mdm9607.c index 07f1b78d737a..2e4cdb590623 100644 --- a/drivers/clk/qcom/gcc-mdm9607.c +++ b/drivers/clk/qcom/gcc-mdm9607.c @@ -26,7 +26,6 @@ enum { P_XO, - P_BIMC, P_GPLL0, P_GPLL1, P_GPLL2, @@ -121,7 +120,7 @@ static struct clk_alpha_pll gpll2_early = { .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x45000, - .enable_mask = BIT(3), /* Yeah, apparently it's not 2 */ + .enable_mask = BIT(3), /* BIT(2) is used for BIMC PLL */ .hw.init = &(struct clk_init_data) { .name = "gpll2_early", @@ -158,20 +157,6 @@ static const struct clk_parent_data gcc_xo_gpll0_gpll2[] = { { .hw = &gpll2.clkr.hw }, }; -static const struct parent_map gcc_xo_gpll0_gpll1_gpll2_map[] = { - { P_XO, 0 }, - { P_GPLL0, 1 }, - { P_GPLL1, 2 }, - { P_GPLL2, 3 }, -}; - -static const struct clk_parent_data gcc_xo_gpll0_gpll1_gpll2[] = { - { .fw_name = "xo" }, - { .hw = &gpll0.clkr.hw }, - { .hw = &gpll1_vote.hw }, - { .hw = &gpll2.clkr.hw }, -}; - static const struct freq_tbl ftbl_apss_ahb_clk[] = { F(19200000, P_XO, 1, 0, 0), F(50000000, P_GPLL0, 16, 0, 0), @@ -192,80 +177,6 @@ static struct clk_rcg2 apss_ahb_clk_src = { }, }; -static struct clk_pll bimc_pll = { - .l_reg = 0x23004, - .m_reg = 0x23008, - .n_reg = 0x2300c, - .config_reg = 0x23010, - .mode_reg = 0x23000, - .status_reg = 0x2301c, - .status_bit = 17, - .clkr.hw.init = &(struct clk_init_data){ - .name = "bimc_pll", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo", - }, - .num_parents = 1, - .ops = &clk_pll_ops, - }, -}; - -static struct clk_regmap bimc_pll_vote = { - .enable_reg = 0x45000, - .enable_mask = BIT(3), - .hw.init = &(struct clk_init_data){ - .name = "bimc_pll_vote", - .parent_hws = (const struct clk_hw *[]){ &bimc_pll.clkr.hw }, - .num_parents = 1, - .ops = &clk_pll_vote_ops, - }, -}; - -static const struct parent_map gcc_xo_gpll0_bimc_map[] = { - { P_XO, 0 }, - { P_GPLL0, 1 }, - { P_BIMC, 2 }, -}; - -static const struct clk_parent_data gcc_xo_gpll0_bimc[] = { - { .fw_name = "xo" }, - { .hw = &gpll0.clkr.hw }, - { .hw = &bimc_pll_vote.hw }, -}; - -static const struct freq_tbl ftbl_pcnoc_bfdcd_clk_src[] = { - F(19200000, P_XO, 1, 0, 0), - F(50000000, P_GPLL0, 16, 0, 0), - F(100000000, P_GPLL0, 8, 0, 0), - { } -}; - -static struct clk_rcg2 pcnoc_bfdcd_clk_src = { - .cmd_rcgr = 0x27000, - .freq_tbl = ftbl_pcnoc_bfdcd_clk_src, - .hid_width = 5, - .parent_map = gcc_xo_gpll0_bimc_map, - .clkr.hw.init = &(struct clk_init_data){ - .name = "pcnoc_bfdcd_clk_src", - .parent_data = gcc_xo_gpll0_bimc, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc), - .ops = &clk_rcg2_ops, - .flags = CLK_IS_CRITICAL, - }, -}; - -static struct clk_rcg2 system_noc_bfdcd_clk_src = { - .cmd_rcgr = 0x26004, - .hid_width = 5, - .parent_map = gcc_xo_gpll0_bimc_map, - .clkr.hw.init = &(struct clk_init_data){ - .name = "system_noc_bfdcd_clk_src", - .parent_data = gcc_xo_gpll0_bimc, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc), - .ops = &clk_rcg2_ops, - }, -}; - static const struct freq_tbl ftbl_gcc_blsp1_qup1_6_i2c_apps_clk[] = { F(19200000, P_XO, 1, 0, 0), F(50000000, P_GPLL0, 16, 0, 0), @@ -674,26 +585,6 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { }, }; -static const struct freq_tbl ftbl_gcc_apss_tcu_clk[] = { - F(155000000, P_GPLL2, 6, 0, 0), - F(310000000, P_GPLL2, 3, 0, 0), - F(400000000, P_GPLL0, 2, 0, 0), - { } -}; - -static struct clk_rcg2 apss_tcu_clk_src = { - .cmd_rcgr = 0x1207c, - .hid_width = 5, - .parent_map = gcc_xo_gpll0_gpll1_gpll2_map, - .freq_tbl = ftbl_gcc_apss_tcu_clk, - .clkr.hw.init = &(struct clk_init_data){ - .name = "apss_tcu_clk_src", - .parent_data = gcc_xo_gpll0_gpll1_gpll2, - .num_parents = 4, - .ops = &clk_rcg2_ops, - }, -}; - static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = { F(19200000, P_XO, 1, 0, 0), F(57140000, P_GPLL0, 14, 0, 0), @@ -781,8 +672,6 @@ static struct clk_branch gcc_blsp1_ahb_clk = { .enable_mask = BIT(10), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -790,9 +679,10 @@ static struct clk_branch gcc_blsp1_ahb_clk = { static struct clk_branch gcc_blsp1_sleep_clk = { .halt_reg = 0x1004, + .halt_check = BRANCH_HALT_VOTED, .clkr = { - .enable_reg = 0x1004, - .enable_mask = BIT(0), + .enable_reg = 0x45004, + .enable_mask = BIT(9), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_sleep_clk", .parent_data = &(const struct clk_parent_data){ @@ -1083,8 +973,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = { .enable_mask = BIT(7), .hw.init = &(struct clk_init_data){ .name = "gcc_boot_rom_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -1098,9 +986,6 @@ static struct clk_branch gcc_crypto_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_crypto_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1114,9 +999,6 @@ static struct clk_branch gcc_crypto_axi_clk = { .enable_mask = BIT(1), .hw.init = &(struct clk_init_data){ .name = "gcc_crypto_axi_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1190,9 +1072,6 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_mss_cfg_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1220,9 +1099,6 @@ static struct clk_branch gcc_pdm_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pdm_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1236,9 +1112,6 @@ static struct clk_branch gcc_prng_ahb_clk = { .enable_mask = BIT(8), .hw.init = &(struct clk_init_data){ .name = "gcc_prng_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1251,9 +1124,6 @@ static struct clk_branch gcc_sdcc1_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sdcc1_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1281,9 +1151,6 @@ static struct clk_branch gcc_sdcc2_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sdcc2_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1304,19 +1171,6 @@ static struct clk_branch gcc_sdcc2_apps_clk = { }, }; -static struct clk_rcg2 bimc_ddr_clk_src = { - .cmd_rcgr = 0x32004, - .hid_width = 5, - .parent_map = gcc_xo_gpll0_bimc_map, - .clkr.hw.init = &(struct clk_init_data){ - .name = "bimc_ddr_clk_src", - .parent_data = gcc_xo_gpll0_bimc, - .num_parents = 3, - .ops = &clk_rcg2_ops, - .flags = CLK_GET_RATE_NOCACHE, - }, -}; - static struct clk_branch gcc_mss_q6_bimc_axi_clk = { .halt_reg = 0x49004, .clkr = { @@ -1324,9 +1178,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_mss_q6_bimc_axi_clk", - .parent_hws = (const struct clk_hw *[]){ &bimc_ddr_clk_src.clkr.hw }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1340,8 +1191,6 @@ static struct clk_branch gcc_apss_tcu_clk = { .enable_mask = BIT(1), .hw.init = &(struct clk_init_data){ .name = "gcc_apss_tcu_clk", - .parent_hws = (const struct clk_hw *[]){ &bimc_ddr_clk_src.clkr.hw }, - .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -1355,9 +1204,6 @@ static struct clk_branch gcc_smmu_cfg_clk = { .enable_mask = BIT(12), .hw.init = &(struct clk_init_data){ .name = "gcc_smmu_cfg_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1405,9 +1251,6 @@ static struct clk_branch gcc_usb_hs_phy_cfg_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb_hs_phy_cfg_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1420,9 +1263,6 @@ static struct clk_branch gcc_usb_hs_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb_hs_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1451,23 +1291,19 @@ static struct clk_branch gcc_apss_ahb_clk = { .enable_mask = BIT(14), .hw.init = &(struct clk_init_data){ .name = "gcc_apss_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, .ops = &clk_branch2_ops, }, }, }; static struct clk_branch gcc_apss_axi_clk = { - .halt_reg = 0x4601c, + .halt_reg = 0x46020, .halt_check = BRANCH_HALT_VOTED, .clkr = { .enable_reg = 0x45004, .enable_mask = BIT(13), .hw.init = &(struct clk_init_data){ .name = "gcc_apss_axi_clk", - .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, - .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -1480,11 +1316,6 @@ static struct clk_regmap *gcc_mdm9607_clocks[] = { [GPLL1_VOTE] = &gpll1_vote, [GPLL2] = &gpll2.clkr, [GPLL2_EARLY] = &gpll2_early.clkr, - [BIMC_PLL] = &bimc_pll.clkr, - [BIMC_PLL_VOTE] = &bimc_pll_vote, - [BIMC_DDR_CLK_SRC] = &bimc_ddr_clk_src.clkr, - [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr, - [SYSTEM_NOC_BFDCD_CLK_SRC] = &system_noc_bfdcd_clk_src.clkr, [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr, [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, @@ -1511,7 +1342,6 @@ static struct clk_regmap *gcc_mdm9607_clocks[] = { [PDM2_CLK_SRC] = &pdm2_clk_src.clkr, [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr, - [APSS_TCU_CLK_SRC] = &apss_tcu_clk_src.clkr, [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr, [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, [GCC_BLSP1_SLEEP_CLK] = &gcc_blsp1_sleep_clk.clkr, @@ -1567,7 +1397,7 @@ static const struct qcom_reset_map gcc_mdm9607_resets[] = { [USB_HS_HSIC_BCR] = { 0x3d05c }, [GCC_MSS_RESTART] = { 0x3e000 }, [USB_HS_BCR] = { 0x41000 }, - [USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, + [USB2_HS_PHY_ONLY_BCR] = { .reg = 0x41034, .udelay = 15 }, [QUSB2_PHY_BCR] = { 0x4103c }, }; @@ -1595,16 +1425,7 @@ MODULE_DEVICE_TABLE(of, gcc_mdm9607_match_table); static int gcc_mdm9607_probe(struct platform_device *pdev) { - struct regmap *regmap; - - regmap = qcom_cc_map(pdev, &gcc_mdm9607_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - /* Vote for GPLL0 to turn on. Needed by acpuclock. */ - regmap_update_bits(regmap, 0x45000, BIT(0), BIT(0)); - - return qcom_cc_really_probe(&pdev->dev, &gcc_mdm9607_desc, regmap); + return qcom_cc_probe(pdev, &gcc_mdm9607_desc); } static struct platform_driver gcc_mdm9607_driver = { diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c index 9c7c6b23ce32..e91406e6f527 100644 --- a/drivers/clk/qcom/gcc-msm8916.c +++ b/drivers/clk/qcom/gcc-msm8916.c @@ -1589,9 +1589,10 @@ static struct clk_branch gcc_blsp1_ahb_clk = { static struct clk_branch gcc_blsp1_sleep_clk = { .halt_reg = 0x01004, + .halt_check = BRANCH_HALT_VOTED, .clkr = { - .enable_reg = 0x01004, - .enable_mask = BIT(0), + .enable_reg = 0x45004, + .enable_mask = BIT(9), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_sleep_clk", .parent_data = &(const struct clk_parent_data){ diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c index 45193b3d714b..ffd7f14fcbaf 100644 --- a/drivers/clk/qcom/gcc-msm8939.c +++ b/drivers/clk/qcom/gcc-msm8939.c @@ -1929,9 +1929,10 @@ static struct clk_branch gcc_blsp1_ahb_clk = { static struct clk_branch gcc_blsp1_sleep_clk = { .halt_reg = 0x01004, + .halt_check = BRANCH_HALT_VOTED, .clkr = { - .enable_reg = 0x01004, - .enable_mask = BIT(0), + .enable_reg = 0x45004, + .enable_mask = BIT(9), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_sleep_clk", .ops = &clk_branch2_ops, diff --git a/drivers/clk/qcom/gcc-nord.c b/drivers/clk/qcom/gcc-nord.c index 7c7c2171ac96..5c9d25f53a6d 100644 --- a/drivers/clk/qcom/gcc-nord.c +++ b/drivers/clk/qcom/gcc-nord.c @@ -701,7 +701,7 @@ static struct clk_branch gcc_pcie_a_phy_rchng_clk = { static struct clk_branch gcc_pcie_a_pipe_clk = { .halt_reg = 0x49068, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x49068, .hwcg_bit = 1, .clkr = { @@ -850,7 +850,7 @@ static struct clk_branch gcc_pcie_b_phy_rchng_clk = { static struct clk_branch gcc_pcie_b_pipe_clk = { .halt_reg = 0x4a068, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9d008, .enable_mask = BIT(24), @@ -995,7 +995,7 @@ static struct clk_branch gcc_pcie_c_phy_rchng_clk = { static struct clk_branch gcc_pcie_c_pipe_clk = { .halt_reg = 0x4b068, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9d010, .enable_mask = BIT(1), @@ -1140,7 +1140,7 @@ static struct clk_branch gcc_pcie_d_phy_rchng_clk = { static struct clk_branch gcc_pcie_d_pipe_clk = { .halt_reg = 0x4c068, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9d010, .enable_mask = BIT(10), @@ -1184,34 +1184,6 @@ static struct clk_branch gcc_pcie_d_slv_q2a_axi_clk = { }, }; -static struct clk_branch gcc_pcie_link_ahb_clk = { - .halt_reg = 0x52464, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x52464, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "gcc_pcie_link_ahb_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch gcc_pcie_link_xo_clk = { - .halt_reg = 0x52468, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x52468, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x52468, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "gcc_pcie_link_xo_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_pcie_noc_async_bridge_clk = { .halt_reg = 0x52048, .halt_check = BRANCH_HALT_SKIP, @@ -1757,8 +1729,6 @@ static struct clk_regmap *gcc_nord_clocks[] = { [GCC_PCIE_D_PIPE_CLK_SRC] = &gcc_pcie_d_pipe_clk_src.clkr, [GCC_PCIE_D_SLV_AXI_CLK] = &gcc_pcie_d_slv_axi_clk.clkr, [GCC_PCIE_D_SLV_Q2A_AXI_CLK] = &gcc_pcie_d_slv_q2a_axi_clk.clkr, - [GCC_PCIE_LINK_AHB_CLK] = &gcc_pcie_link_ahb_clk.clkr, - [GCC_PCIE_LINK_XO_CLK] = &gcc_pcie_link_xo_clk.clkr, [GCC_PCIE_NOC_ASYNC_BRIDGE_CLK] = &gcc_pcie_noc_async_bridge_clk.clkr, [GCC_PCIE_NOC_CNOC_SF_QX_CLK] = &gcc_pcie_noc_cnoc_sf_qx_clk.clkr, [GCC_PCIE_NOC_M_CFG_CLK] = &gcc_pcie_noc_m_cfg_clk.clkr, @@ -1849,9 +1819,16 @@ static const struct regmap_config gcc_nord_regmap_config = { .fast_io = true, }; +static const u32 gcc_nord_critical_cbcrs[] = { + 0x52464, /* GCC_PCIE_LINK_AHB_CLK */ + 0x52468, /* GCC_PCIE_LINK_XO_CLK */ +}; + static const struct qcom_cc_driver_data gcc_nord_driver_data = { .dfs_rcgs = gcc_nord_dfs_clocks, .num_dfs_rcgs = ARRAY_SIZE(gcc_nord_dfs_clocks), + .clk_cbcrs = gcc_nord_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_nord_critical_cbcrs), }; static const struct qcom_cc_desc gcc_nord_desc = { diff --git a/drivers/clk/qcom/gcc-qcm2290.c b/drivers/clk/qcom/gcc-qcm2290.c index 6684cab63ae1..2532c0b36bc5 100644 --- a/drivers/clk/qcom/gcc-qcm2290.c +++ b/drivers/clk/qcom/gcc-qcm2290.c @@ -116,7 +116,7 @@ static const struct alpha_pll_config gpll10_config = { .vco_mask = GENMASK(21, 20), .main_output_mask = BIT(0), .config_ctl_val = 0x4001055B, - .test_ctl_hi1_val = 0x1, + .test_ctl_hi_val = 0x1, }; static struct clk_alpha_pll gpll10 = { @@ -148,7 +148,7 @@ static const struct alpha_pll_config gpll11_config = { .vco_mask = GENMASK(21, 20), .main_output_mask = BIT(0), .config_ctl_val = 0x4001055B, - .test_ctl_hi1_val = 0x1, + .test_ctl_hi_val = 0x1, }; static struct clk_alpha_pll gpll11 = { @@ -309,7 +309,7 @@ static const struct alpha_pll_config gpll8_config = { .post_div_val = 0x1 << 8, .post_div_mask = GENMASK(11, 8), .config_ctl_val = 0x4001055B, - .test_ctl_hi1_val = 0x1, + .test_ctl_hi_val = 0x1, }; static struct clk_alpha_pll gpll8 = { @@ -1082,7 +1082,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { .name = "gcc_qupv3_wrap0_s0_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { @@ -1098,7 +1098,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { .name = "gcc_qupv3_wrap0_s1_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { @@ -1114,7 +1114,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { .name = "gcc_qupv3_wrap0_s2_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { @@ -1130,7 +1130,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { .name = "gcc_qupv3_wrap0_s3_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { @@ -1146,7 +1146,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { .name = "gcc_qupv3_wrap0_s4_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { @@ -1162,7 +1162,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { .name = "gcc_qupv3_wrap0_s5_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { @@ -1397,36 +1397,6 @@ static struct clk_branch gcc_cam_throttle_rt_clk = { }, }; -static struct clk_branch gcc_camera_ahb_clk = { - .halt_reg = 0x17008, - .halt_check = BRANCH_HALT_DELAY, - .hwcg_reg = 0x17008, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x17008, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_ahb_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch gcc_camera_xo_clk = { - .halt_reg = 0x17028, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x17028, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_xo_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_camss_axi_clk = { .halt_reg = 0x58044, .halt_check = BRANCH_HALT, @@ -1825,22 +1795,6 @@ static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { }, }; -static struct clk_branch gcc_disp_ahb_clk = { - .halt_reg = 0x1700c, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0x1700c, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x1700c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_ahb_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_regmap_div gcc_disp_gpll0_clk_src = { .reg = 0x17058, .shift = 0, @@ -1899,20 +1853,6 @@ static struct clk_branch gcc_disp_throttle_core_clk = { }, }; -static struct clk_branch gcc_disp_xo_clk = { - .halt_reg = 0x1702c, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x1702c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_xo_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gp1_clk = { .halt_reg = 0x4d000, .halt_check = BRANCH_HALT, @@ -1964,22 +1904,6 @@ static struct clk_branch gcc_gp3_clk = { }, }; -static struct clk_branch gcc_gpu_cfg_ahb_clk = { - .halt_reg = 0x36004, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0x36004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x36004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_gpu_cfg_ahb_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gpu_gpll0_clk_src = { .halt_check = BRANCH_HALT_DELAY, .clkr = { @@ -2439,22 +2363,6 @@ static struct clk_branch gcc_sdcc2_apps_clk = { }, }; -static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = { - .halt_reg = 0x2b06c, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x2b06c, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x79004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_sys_noc_cpuss_ahb_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_sys_noc_usb3_prim_axi_clk = { .halt_reg = 0x1a080, .halt_check = BRANCH_HALT, @@ -2775,8 +2683,6 @@ static struct clk_regmap *gcc_qcm2290_clocks[] = { [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, [GCC_CAM_THROTTLE_NRT_CLK] = &gcc_cam_throttle_nrt_clk.clkr, [GCC_CAM_THROTTLE_RT_CLK] = &gcc_cam_throttle_rt_clk.clkr, - [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr, - [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, [GCC_CAMSS_AXI_CLK] = &gcc_camss_axi_clk.clkr, [GCC_CAMSS_AXI_CLK_SRC] = &gcc_camss_axi_clk_src.clkr, [GCC_CAMSS_CAMNOC_ATB_CLK] = &gcc_camss_camnoc_atb_clk.clkr, @@ -2817,19 +2723,16 @@ static struct clk_regmap *gcc_qcm2290_clocks[] = { [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr, [GCC_CAMSS_TOP_AHB_CLK_SRC] = &gcc_camss_top_ahb_clk_src.clkr, [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, - [GCC_DISP_AHB_CLK] = &gcc_disp_ahb_clk.clkr, [GCC_DISP_GPLL0_CLK_SRC] = &gcc_disp_gpll0_clk_src.clkr, [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr, [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, [GCC_DISP_THROTTLE_CORE_CLK] = &gcc_disp_throttle_core_clk.clkr, - [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr, [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, - [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr, [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, [GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr, @@ -2870,7 +2773,6 @@ static struct clk_regmap *gcc_qcm2290_clocks[] = { [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, - [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr, [GCC_SYS_NOC_USB3_PRIM_AXI_CLK] = &gcc_sys_noc_usb3_prim_axi_clk.clkr, [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, @@ -2943,6 +2845,15 @@ static struct gdsc *gcc_qcm2290_gdscs[] = { [HLOS1_VOTE_MM_SNOC_MMU_TBU_NRT_GDSC] = &hlos1_vote_mm_snoc_mmu_tbu_nrt_gdsc, }; +static const u32 gcc_qcm2290_critical_cbcrs[] = { + 0x17008, /* GCC_CAMERA_AHB_CLK */ + 0x17028, /* GCC_CAMERA_XO_CLK */ + 0x1700c, /* GCC_DISP_AHB_CLK */ + 0x1702c, /* GCC_DISP_XO_CLK */ + 0x36004, /* GCC_GPU_CFG_AHB_CLK */ + 0x79004, /* GCC_SYS_NOC_CPUSS_AHB_CLK */ +}; + static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src), DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src), @@ -2960,6 +2871,11 @@ static const struct regmap_config gcc_qcm2290_regmap_config = { .fast_io = true, }; +static const struct qcom_cc_driver_data gcc_qcm2290_driver_data = { + .clk_cbcrs = gcc_qcm2290_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_qcm2290_critical_cbcrs), +}; + static const struct qcom_cc_desc gcc_qcm2290_desc = { .config = &gcc_qcm2290_regmap_config, .clks = gcc_qcm2290_clocks, @@ -2968,6 +2884,7 @@ static const struct qcom_cc_desc gcc_qcm2290_desc = { .num_resets = ARRAY_SIZE(gcc_qcm2290_resets), .gdscs = gcc_qcm2290_gdscs, .num_gdscs = ARRAY_SIZE(gcc_qcm2290_gdscs), + .driver_data = &gcc_qcm2290_driver_data, }; static const struct of_device_id gcc_qcm2290_match_table[] = { diff --git a/drivers/clk/qcom/gcc-qcs8300.c b/drivers/clk/qcom/gcc-qcs8300.c index 07218d9c96a7..31fd870b10f7 100644 --- a/drivers/clk/qcom/gcc-qcs8300.c +++ b/drivers/clk/qcom/gcc-qcs8300.c @@ -3267,7 +3267,7 @@ static struct gdsc gcc_pcie_0_gdsc = { .pd = { .name = "gcc_pcie_0_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; @@ -3281,7 +3281,7 @@ static struct gdsc gcc_pcie_1_gdsc = { .pd = { .name = "gcc_pcie_1_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; @@ -3305,7 +3305,7 @@ static struct gdsc gcc_usb20_prim_gdsc = { .pd = { .name = "gcc_usb20_prim_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; @@ -3317,7 +3317,7 @@ static struct gdsc gcc_usb30_prim_gdsc = { .pd = { .name = "gcc_usb30_prim_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; diff --git a/drivers/clk/qcom/gcc-shikra.c b/drivers/clk/qcom/gcc-shikra.c new file mode 100644 index 000000000000..2a1c1fc253aa --- /dev/null +++ b/drivers/clk/qcom/gcc-shikra.c @@ -0,0 +1,4432 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "clk-regmap-phy-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_SLEEP_CLK, + DT_EMAC0_SGMIIPHY_RCLK, + DT_EMAC0_SGMIIPHY_TCLK, + DT_EMAC1_SGMIIPHY_RCLK, + DT_EMAC1_SGMIIPHY_TCLK, + DT_PCIE_PIPE_CLK, + DT_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, +}; + +enum { + P_BI_TCXO, + P_EMAC0_SGMIIPHY_RCLK, + P_EMAC0_SGMIIPHY_TCLK, + P_EMAC1_SGMIIPHY_RCLK, + P_EMAC1_SGMIIPHY_TCLK, + P_GPLL0_OUT_AUX2, + P_GPLL0_OUT_EARLY, + P_GPLL10_OUT_MAIN, + P_GPLL11_OUT_AUX, + P_GPLL11_OUT_AUX2, + P_GPLL11_OUT_MAIN, + P_GPLL12_OUT_AUX2, + P_GPLL12_OUT_EARLY, + P_GPLL3_OUT_EARLY, + P_GPLL3_OUT_MAIN, + P_GPLL4_OUT_MAIN, + P_GPLL5_OUT_MAIN, + P_GPLL6_OUT_EARLY, + P_GPLL6_OUT_MAIN, + P_GPLL7_OUT_MAIN, + P_GPLL8_OUT_EARLY, + P_GPLL8_OUT_MAIN, + P_GPLL9_OUT_EARLY, + P_GPLL9_OUT_MAIN, + P_PCIE_PIPE_CLK, + P_SLEEP_CLK, + P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, +}; + +static const struct pll_vco brammo_vco[] = { + { 500000000, 1250000000, 0 }, +}; + +static const struct pll_vco default_vco[] = { + { 500000000, 1000000000, 2 }, +}; + +static const struct pll_vco spark_vco[] = { + { 750000000, 1500000000, 1 }, +}; + +static struct clk_alpha_pll gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll0_out_aux2[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll0_out_aux2 = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll0_out_aux2, + .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_aux2), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll0_out_aux2", + .parent_hws = (const struct clk_hw*[]) { + &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +/* 1152.0 MHz Configuration */ +static const struct alpha_pll_config gpll10_config = { + .l = 0x3c, + .alpha = 0x0, + .vco_val = BIT(20), + .vco_mask = GENMASK(21, 20), + .main_output_mask = BIT(0), + .config_ctl_val = 0x4001055b, + .test_ctl_hi_val = 0x1, +}; + +static struct clk_alpha_pll gpll10 = { + .offset = 0xa000, + .config = &gpll10_config, + .vco_table = spark_vco, + .num_vco = ARRAY_SIZE(spark_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gpll10", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +/* 600.0 MHz Configuration */ +static const struct alpha_pll_config gpll11_config = { + .l = 0x1f, + .alpha = 0x0, + .alpha_hi = 0x40, + .alpha_en_mask = BIT(24), + .vco_val = BIT(21), + .vco_mask = GENMASK(21, 20), + .main_output_mask = BIT(0), + .config_ctl_val = 0x4001055b, + .test_ctl_hi_val = 0x1, +}; + +static struct clk_alpha_pll gpll11 = { + .offset = 0xb000, + .config = &gpll11_config, + .vco_table = default_vco, + .num_vco = ARRAY_SIZE(default_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .flags = SUPPORTS_DYNAMIC_UPDATE, + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gpll11", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll12 = { + .offset = 0xc000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gpll12", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll12_out_aux2[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll12_out_aux2 = { + .offset = 0xc000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll12_out_aux2, + .num_post_div = ARRAY_SIZE(post_div_table_gpll12_out_aux2), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll12_out_aux2", + .parent_hws = (const struct clk_hw*[]) { + &gpll12.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static struct clk_alpha_pll gpll3 = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gpll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll3_out_main[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll3_out_main = { + .offset = 0x3000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll3_out_main, + .num_post_div = ARRAY_SIZE(post_div_table_gpll3_out_main), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll3_out_main", + .parent_hws = (const struct clk_hw*[]) { + &gpll3.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static struct clk_alpha_pll gpll4 = { + .offset = 0x4000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gpll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll5 = { + .offset = 0x5000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gpll5", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll6 = { + .offset = 0x6000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gpll6", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll6_out_main[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll6_out_main = { + .offset = 0x6000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll6_out_main, + .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll6_out_main", + .parent_hws = (const struct clk_hw*[]) { + &gpll6.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static struct clk_alpha_pll gpll7 = { + .offset = 0x7000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gpll7", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +/* 533.2 MHz Configuration */ +static const struct alpha_pll_config gpll8_config = { + .l = 0x1b, + .alpha = 0x55555555, + .alpha_hi = 0xc5, + .alpha_en_mask = BIT(24), + .vco_val = BIT(21), + .vco_mask = GENMASK(21, 20), + .main_output_mask = BIT(0), + .early_output_mask = BIT(3), + .post_div_val = BIT(8), + .post_div_mask = GENMASK(11, 8), + .config_ctl_val = 0x4001055b, + .test_ctl_hi_val = 0x1, +}; + +static struct clk_alpha_pll gpll8 = { + .offset = 0x8000, + .config = &gpll8_config, + .vco_table = default_vco, + .num_vco = ARRAY_SIZE(default_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .flags = SUPPORTS_DYNAMIC_UPDATE, + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gpll8", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll8_out_main[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll8_out_main = { + .offset = 0x8000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll8_out_main, + .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll8_out_main", + .parent_hws = (const struct clk_hw*[]) { + &gpll8.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +/* 1152.0 MHz Configuration */ +static const struct alpha_pll_config gpll9_config = { + .l = 0x3c, + .alpha = 0x0, + .post_div_val = BIT(8), + .post_div_mask = GENMASK(9, 8), + .main_output_mask = BIT(0), + .early_output_mask = BIT(3), + .config_ctl_val = 0x00004289, + .test_ctl_val = 0x08000000, +}; + +static struct clk_alpha_pll gpll9 = { + .offset = 0x9000, + .config = &gpll9_config, + .vco_table = brammo_vco, + .num_vco = ARRAY_SIZE(brammo_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gpll9", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll9_out_main[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll9_out_main = { + .offset = 0x9000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll9_out_main, + .num_post_div = ARRAY_SIZE(post_div_table_gpll9_out_main), + .width = 2, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll9_out_main", + .parent_hws = (const struct clk_hw*[]) { + &gpll9.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL6_OUT_MAIN, 4 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll6_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL9_OUT_EARLY, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL9_OUT_MAIN, 5 }, + { P_GPLL3_OUT_MAIN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll9_out_main.clkr.hw }, + { .hw = &gpll3_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL3_OUT_MAIN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll3_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL8_OUT_EARLY, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL8_OUT_MAIN, 4 }, + { P_GPLL9_OUT_MAIN, 5 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll8.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll8_out_main.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL8_OUT_EARLY, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL8_OUT_MAIN, 4 }, + { P_GPLL9_OUT_MAIN, 5 }, + { P_GPLL3_OUT_MAIN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll8.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll8_out_main.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll3_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_9[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL8_OUT_EARLY, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL6_OUT_MAIN, 4 }, + { P_GPLL9_OUT_MAIN, 5 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_9[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll8.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll6_out_main.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_10[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_10[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_11[] = { + { P_BI_TCXO, 0 }, + { P_GPLL12_OUT_EARLY, 1 }, + { P_GPLL12_OUT_AUX2, 4 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_11[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll12.clkr.hw }, + { .hw = &gpll12_out_aux2.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_12[] = { + { P_BI_TCXO, 0 }, + { P_GPLL12_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL12_OUT_AUX2, 4 }, +}; + +static const struct clk_parent_data gcc_parent_data_12[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll12.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll12_out_aux2.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_13[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, +}; + +static const struct clk_parent_data gcc_parent_data_13[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_14[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL8_OUT_MAIN, 4 }, + { P_GPLL9_OUT_MAIN, 5 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_14[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll8_out_main.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_15[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL8_OUT_EARLY, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL6_OUT_EARLY, 5 }, + { P_GPLL3_OUT_MAIN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_15[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll8.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll6.clkr.hw }, + { .hw = &gpll3_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_21[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL7_OUT_MAIN, 3 }, + { P_GPLL4_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_21[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll7.clkr.hw }, + { .hw = &gpll4.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_22[] = { + { P_BI_TCXO, 0 }, + { P_GPLL12_OUT_EARLY, 1 }, + { P_GPLL5_OUT_MAIN, 3 }, + { P_GPLL12_OUT_AUX2, 4 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_22[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll12.clkr.hw }, + { .hw = &gpll5.clkr.hw }, + { .hw = &gpll12_out_aux2.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_24[] = { + { P_BI_TCXO, 0 }, + { P_GPLL11_OUT_MAIN, 1 }, + { P_GPLL11_OUT_AUX, 2 }, + { P_GPLL11_OUT_AUX2, 3 }, +}; + +static const struct clk_parent_data gcc_parent_data_24[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll11.clkr.hw }, + { .hw = &gpll11.clkr.hw }, + { .hw = &gpll11.clkr.hw }, +}; + +static struct clk_regmap_phy_mux gcc_emac0_cc_sgmiiphy_rx_clk_src = { + .reg = 0xad048, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_cc_sgmiiphy_rx_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_EMAC0_SGMIIPHY_RCLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_emac0_cc_sgmiiphy_tx_clk_src = { + .reg = 0xad040, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_cc_sgmiiphy_tx_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_EMAC0_SGMIIPHY_TCLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_emac1_cc_sgmiiphy_rx_clk_src = { + .reg = 0xae048, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_cc_sgmiiphy_rx_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_EMAC1_SGMIIPHY_RCLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_emac1_cc_sgmiiphy_tx_clk_src = { + .reg = 0xae040, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_cc_sgmiiphy_tx_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_EMAC1_SGMIIPHY_TCLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_pcie_pipe_clk_src = { + .reg = 0xaf058, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_pipe_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_PCIE_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb3_prim_phy_pipe_clk_src = { + .reg = 0x1a05c, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_axi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(150000000, P_GPLL0_OUT_AUX2, 2, 0, 0), + F(200000000, P_GPLL0_OUT_AUX2, 1.5, 0, 0), + F(300000000, P_GPLL0_OUT_AUX2, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_axi_clk_src = { + .cmd_rcgr = 0x5802c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_camss_axi_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_axi_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_cci_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_GPLL0_OUT_AUX2, 8, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_cci_clk_src = { + .cmd_rcgr = 0x56000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_14, + .freq_tbl = ftbl_gcc_camss_cci_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_cci_clk_src", + .parent_data = gcc_parent_data_14, + .num_parents = ARRAY_SIZE(gcc_parent_data_14), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_csi0phytimer_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(200000000, P_GPLL0_OUT_AUX2, 1.5, 0, 0), + F(268800000, P_GPLL4_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_csi0phytimer_clk_src = { + .cmd_rcgr = 0x45000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_csi0phytimer_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_csi1phytimer_clk_src = { + .cmd_rcgr = 0x4501c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_csi1phytimer_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_mclk0_clk_src[] = { + F(19200000, P_GPLL9_OUT_EARLY, 1, 1, 60), + F(24000000, P_GPLL9_OUT_MAIN, 1, 1, 24), + F(64000000, P_GPLL9_OUT_EARLY, 9, 1, 2), + { } +}; + +static struct clk_rcg2 gcc_camss_mclk0_clk_src = { + .cmd_rcgr = 0x51000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk0_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_mclk1_clk_src = { + .cmd_rcgr = 0x5101c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk1_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_mclk2_clk_src = { + .cmd_rcgr = 0x51038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk2_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_mclk3_clk_src = { + .cmd_rcgr = 0x51054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk3_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_ope_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(171428571, P_GPLL0_OUT_EARLY, 3.5, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_ope_ahb_clk_src = { + .cmd_rcgr = 0x55024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gcc_camss_ope_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_ope_ahb_clk_src", + .parent_data = gcc_parent_data_7, + .num_parents = ARRAY_SIZE(gcc_parent_data_7), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_ope_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_GPLL8_OUT_MAIN, 2, 0, 0), + F(266600000, P_GPLL8_OUT_MAIN, 1, 0, 0), + F(465000000, P_GPLL8_OUT_MAIN, 1, 0, 0), + F(580000000, P_GPLL8_OUT_EARLY, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_ope_clk_src = { + .cmd_rcgr = 0x55004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gcc_camss_ope_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_ope_clk_src", + .parent_data = gcc_parent_data_7, + .num_parents = ARRAY_SIZE(gcc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_tfe_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(128000000, P_GPLL10_OUT_MAIN, 9, 0, 0), + F(135529412, P_GPLL10_OUT_MAIN, 8.5, 0, 0), + F(144000000, P_GPLL10_OUT_MAIN, 8, 0, 0), + F(153600000, P_GPLL10_OUT_MAIN, 7.5, 0, 0), + F(164571429, P_GPLL10_OUT_MAIN, 7, 0, 0), + F(177230769, P_GPLL10_OUT_MAIN, 6.5, 0, 0), + F(192000000, P_GPLL10_OUT_MAIN, 6, 0, 0), + F(209454545, P_GPLL10_OUT_MAIN, 5.5, 0, 0), + F(230400000, P_GPLL10_OUT_MAIN, 5, 0, 0), + F(256000000, P_GPLL10_OUT_MAIN, 4.5, 0, 0), + F(288000000, P_GPLL10_OUT_MAIN, 4, 0, 0), + F(329142857, P_GPLL10_OUT_MAIN, 3.5, 0, 0), + F(384000000, P_GPLL10_OUT_MAIN, 3, 0, 0), + F(460800000, P_GPLL10_OUT_MAIN, 2.5, 0, 0), + F(576000000, P_GPLL10_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_tfe_0_clk_src = { + .cmd_rcgr = 0x52004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_camss_tfe_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_0_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_tfe_0_csid_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(120000000, P_GPLL0_OUT_EARLY, 5, 0, 0), + F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0), + F(426400000, P_GPLL3_OUT_EARLY, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_tfe_0_csid_clk_src = { + .cmd_rcgr = 0x52094, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_gcc_camss_tfe_0_csid_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_0_csid_clk_src", + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_tfe_1_clk_src = { + .cmd_rcgr = 0x52024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_camss_tfe_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_1_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_tfe_1_csid_clk_src = { + .cmd_rcgr = 0x520b4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_gcc_camss_tfe_0_csid_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_1_csid_clk_src", + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_tfe_cphy_rx_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + F(341333333, P_GPLL6_OUT_EARLY, 1, 4, 9), + F(384000000, P_GPLL6_OUT_EARLY, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_tfe_cphy_rx_clk_src = { + .cmd_rcgr = 0x52064, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_15, + .freq_tbl = ftbl_gcc_camss_tfe_cphy_rx_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_cphy_rx_clk_src", + .parent_data = gcc_parent_data_15, + .num_parents = ARRAY_SIZE(gcc_parent_data_15), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_top_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(40000000, P_GPLL0_OUT_AUX2, 7.5, 0, 0), + F(80000000, P_GPLL0_OUT_EARLY, 7.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_top_ahb_clk_src = { + .cmd_rcgr = 0x58010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_camss_top_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_top_ahb_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac0_axi_clk_src[] = { + F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0), + F(120000000, P_GPLL0_OUT_AUX2, 2.5, 0, 0), + F(150000000, P_GPLL0_OUT_AUX2, 2, 0, 0), + F(200000000, P_GPLL0_OUT_AUX2, 1.5, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac0_axi_clk_src = { + .cmd_rcgr = 0x109dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_emac0_axi_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_axi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac0_phy_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac0_phy_aux_clk_src = { + .cmd_rcgr = 0xad01c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_10, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_phy_aux_clk_src", + .parent_data = gcc_parent_data_10, + .num_parents = ARRAY_SIZE(gcc_parent_data_10), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac0_ptp_clk_src[] = { + F(250000000, P_GPLL12_OUT_AUX2, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac0_ptp_clk_src = { + .cmd_rcgr = 0xad064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_11, + .freq_tbl = ftbl_gcc_emac0_ptp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_ptp_clk_src", + .parent_data = gcc_parent_data_11, + .num_parents = ARRAY_SIZE(gcc_parent_data_11), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac0_rgmii_clk_src[] = { + F(2500000, P_GPLL0_OUT_AUX2, 10, 1, 12), + F(25000000, P_GPLL0_OUT_AUX2, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(125000000, P_GPLL12_OUT_AUX2, 4, 0, 0), + F(250000000, P_GPLL12_OUT_EARLY, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac0_rgmii_clk_src = { + .cmd_rcgr = 0xad04c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_12, + .freq_tbl = ftbl_gcc_emac0_rgmii_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_rgmii_clk_src", + .parent_data = gcc_parent_data_12, + .num_parents = ARRAY_SIZE(gcc_parent_data_12), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_emac1_axi_clk_src = { + .cmd_rcgr = 0x109fc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_emac0_axi_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_axi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_emac1_phy_aux_clk_src = { + .cmd_rcgr = 0xae01c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_10, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_phy_aux_clk_src", + .parent_data = gcc_parent_data_10, + .num_parents = ARRAY_SIZE(gcc_parent_data_10), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_emac1_ptp_clk_src = { + .cmd_rcgr = 0xae064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_11, + .freq_tbl = ftbl_gcc_emac0_ptp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_ptp_clk_src", + .parent_data = gcc_parent_data_11, + .num_parents = ARRAY_SIZE(gcc_parent_data_11), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_emac1_rgmii_clk_src = { + .cmd_rcgr = 0xae04c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_12, + .freq_tbl = ftbl_gcc_emac0_rgmii_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_rgmii_clk_src", + .parent_data = gcc_parent_data_12, + .num_parents = ARRAY_SIZE(gcc_parent_data_12), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(25000000, P_GPLL0_OUT_AUX2, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(200000000, P_GPLL0_OUT_AUX2, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x4d004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp1_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x4e004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp2_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x4f004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_aux_clk_src = { + .cmd_rcgr = 0xaf074, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_aux_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_aux_phy_clk_src = { + .cmd_rcgr = 0xaf05c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_aux_phy_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_rchng_phy_clk_src[] = { + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_rchng_phy_clk_src = { + .cmd_rcgr = 0xaf028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_rchng_phy_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_rchng_phy_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_GPLL0_OUT_AUX2, 5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x20010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pdm2_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, P_GPLL0_OUT_AUX2, 1, 384, 15625), + F(14745600, P_GPLL0_OUT_AUX2, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GPLL0_OUT_AUX2, 1, 1536, 15625), + F(32000000, P_GPLL0_OUT_AUX2, 1, 8, 75), + F(48000000, P_GPLL0_OUT_AUX2, 1, 4, 25), + F(64000000, P_GPLL0_OUT_AUX2, 1, 16, 75), + F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0), + F(80000000, P_GPLL0_OUT_AUX2, 1, 4, 15), + F(96000000, P_GPLL0_OUT_AUX2, 1, 8, 25), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(102400000, P_GPLL0_OUT_AUX2, 1, 128, 375), + F(112000000, P_GPLL0_OUT_AUX2, 1, 28, 75), + F(117964800, P_GPLL0_OUT_AUX2, 1, 6144, 15625), + F(120000000, P_GPLL0_OUT_AUX2, 2.5, 0, 0), + F(128000000, P_GPLL6_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { + .cmd_rcgr = 0x1f148, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { + .cmd_rcgr = 0x1f278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { + .cmd_rcgr = 0x1f3a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { + .cmd_rcgr = 0x1f4d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { + .cmd_rcgr = 0x1f608, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { + .cmd_rcgr = 0x1f738, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = { + .name = "gcc_qupv3_wrap0_s6_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { + .cmd_rcgr = 0x1f868, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = { + .name = "gcc_qupv3_wrap0_s7_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { + .cmd_rcgr = 0x1f998, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s8_clk_src_init = { + .name = "gcc_qupv3_wrap0_s8_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s8_clk_src = { + .cmd_rcgr = 0x1fac8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s8_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s9_clk_src_init = { + .name = "gcc_qupv3_wrap0_s9_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s9_clk_src = { + .cmd_rcgr = 0x1fbf8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s9_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = { + F(144000, P_BI_TCXO, 16, 3, 25), + F(400000, P_BI_TCXO, 12, 1, 4), + F(20000000, P_GPLL0_OUT_AUX2, 5, 1, 3), + F(25000000, P_GPLL0_OUT_AUX2, 6, 1, 2), + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0), + F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { + .cmd_rcgr = 0x38028, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_apps_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_shared_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = { + F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(150000000, P_GPLL0_OUT_AUX2, 2, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + F(300000000, P_GPLL0_OUT_AUX2, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x38010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_shared_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_AUX2, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(202000000, P_GPLL7_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1e00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_21, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_21, + .num_parents = ARRAY_SIZE(gcc_parent_data_21), + .ops = &clk_rcg2_shared_floor_ops, + }, +}; + +static struct clk_rcg2 gcc_tscss_clk_src = { + .cmd_rcgr = 0xac004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_22, + .freq_tbl = ftbl_gcc_emac0_ptp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_tscss_clk_src", + .parent_data = gcc_parent_data_22, + .num_parents = ARRAY_SIZE(gcc_parent_data_22), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb20_master_clk_src[] = { + F(60000000, P_GPLL0_OUT_AUX2, 5, 0, 0), + F(120000000, P_GPLL0_OUT_EARLY, 5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb20_master_clk_src = { + .cmd_rcgr = 0xb003c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb20_master_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_usb20_mock_utmi_clk_src = { + .cmd_rcgr = 0xb0020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_13, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_mock_utmi_clk_src", + .parent_data = gcc_parent_data_13, + .num_parents = ARRAY_SIZE(gcc_parent_data_13), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { + F(66666667, P_GPLL0_OUT_AUX2, 4.5, 0, 0), + F(133333333, P_GPLL0_OUT_EARLY, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0x1a01c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0x1a034, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0x1a060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_video_venus_clk_src[] = { + F(133333333, P_GPLL11_OUT_MAIN, 4.5, 0, 0), + F(240000000, P_GPLL11_OUT_MAIN, 2.5, 0, 0), + F(300000000, P_GPLL11_OUT_MAIN, 2, 0, 0), + F(384000000, P_GPLL11_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_video_venus_clk_src = { + .cmd_rcgr = 0x6d000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_24, + .freq_tbl = ftbl_gcc_video_venus_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_video_venus_clk_src", + .parent_data = gcc_parent_data_24, + .num_parents = ARRAY_SIZE(gcc_parent_data_24), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div gcc_disp_gpll0_clk_src = { + .reg = 0x17058, + .shift = 0, + .width = 2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_gpll0_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div gcc_usb20_mock_utmi_postdiv_clk_src = { + .reg = 0xb0038, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = { + .reg = 0x1a04c, + .shift = 0, + .width = 2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gcc_ahb2phy_csi_clk = { + .halt_reg = 0x1d004, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x1d004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1d004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ahb2phy_csi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ahb2phy_usb_clk = { + .halt_reg = 0x1d008, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1d008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1d008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ahb2phy_usb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x23004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cam_throttle_nrt_clk = { + .halt_reg = 0x17070, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17070, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cam_throttle_nrt_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cam_throttle_rt_clk = { + .halt_reg = 0x1706c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1706c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cam_throttle_rt_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_axi_clk = { + .halt_reg = 0x58044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x58044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_camnoc_atb_clk = { + .halt_reg = 0x5804c, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x5804c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x5804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_camnoc_atb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_camnoc_dragonlink_atb_clk = { + .halt_reg = 0x58060, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x58060, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x58060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_camnoc_dragonlink_atb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_camnoc_nts_xo_clk = { + .halt_reg = 0x58050, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x58050, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x58050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_camnoc_nts_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cci_0_clk = { + .halt_reg = 0x56018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x56018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_cci_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_cci_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cphy_0_clk = { + .halt_reg = 0x52088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x52088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_cphy_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cphy_1_clk = { + .halt_reg = 0x5208c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5208c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_cphy_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0phytimer_clk = { + .halt_reg = 0x45018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x45018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_csi0phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_csi0phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1phytimer_clk = { + .halt_reg = 0x45034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x45034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_csi1phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_csi1phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk0_clk = { + .halt_reg = 0x51018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x51018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk1_clk = { + .halt_reg = 0x51034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x51034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk2_clk = { + .halt_reg = 0x51050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x51050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk3_clk = { + .halt_reg = 0x5106c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5106c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_nrt_axi_clk = { + .halt_reg = 0x58054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x58054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_nrt_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_ope_ahb_clk = { + .halt_reg = 0x5503c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5503c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_ope_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_ope_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_ope_clk = { + .halt_reg = 0x5501c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5501c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_ope_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_ope_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_rt_axi_clk = { + .halt_reg = 0x5805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_rt_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_0_clk = { + .halt_reg = 0x5201c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5201c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_0_cphy_rx_clk = { + .halt_reg = 0x5207c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5207c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_0_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_0_csid_clk = { + .halt_reg = 0x520ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x520ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_0_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_0_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_1_clk = { + .halt_reg = 0x5203c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5203c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_1_cphy_rx_clk = { + .halt_reg = 0x52080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x52080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_1_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_1_csid_clk = { + .halt_reg = 0x520cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x520cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_1_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_1_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_top_ahb_clk = { + .halt_reg = 0x58028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x58028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_top_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb2_prim_axi_clk = { + .halt_reg = 0x111c4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x111c4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x111c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb2_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0x1a07c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1a07c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1a07c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_gpu_axi_clk = { + .halt_reg = 0x71000, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x71000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ddrss_gpu_axi_clk", + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_memnoc_pcie_sf_clk = { + .halt_reg = 0x29044, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x29044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x29044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ddrss_memnoc_pcie_sf_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_disp_gpll0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0x17020, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x17020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x17020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_throttle_core_clk = { + .halt_reg = 0x17064, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17064, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_throttle_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_ahb_clk = { + .halt_reg = 0xad010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xad010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xad010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_axi_clk = { + .halt_reg = 0xad014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xad014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xad014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_axi_sys_noc_clk = { + .halt_reg = 0x109d4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x109d4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x109d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_axi_sys_noc_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_cc_sgmiiphy_rx_clk = { + .halt_reg = 0xad044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xad044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_cc_sgmiiphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_cc_sgmiiphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_cc_sgmiiphy_tx_clk = { + .halt_reg = 0xad03c, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0xad03c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xad03c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_cc_sgmiiphy_tx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_cc_sgmiiphy_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_phy_aux_clk = { + .halt_reg = 0xad018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xad018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_ptp_clk = { + .halt_reg = 0xad034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xad034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_ptp_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_ptp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_rgmii_clk = { + .halt_reg = 0xad038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xad038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_rgmii_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_rgmii_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_ahb_clk = { + .halt_reg = 0xae010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xae010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xae010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_axi_clk = { + .halt_reg = 0xae014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xae014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xae014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_axi_sys_noc_clk = { + .halt_reg = 0x109f4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x109f4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x109f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_axi_sys_noc_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_cc_sgmiiphy_rx_clk = { + .halt_reg = 0xae044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xae044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_cc_sgmiiphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_cc_sgmiiphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_cc_sgmiiphy_tx_clk = { + .halt_reg = 0xae03c, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0xae03c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xae03c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_cc_sgmiiphy_tx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_cc_sgmiiphy_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_phy_aux_clk = { + .halt_reg = 0xae018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xae018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_ptp_clk = { + .halt_reg = 0xae034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xae034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_ptp_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_ptp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_rgmii_clk = { + .halt_reg = 0xae038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xae038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_rgmii_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_rgmii_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x4d000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x4e000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4e000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x4f000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4f000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpll0_out_aux2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_memnoc_gfx_clk = { + .halt_reg = 0x3600c, + .halt_check = BRANCH_VOTED, + .hwcg_reg = 0x3600c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3600c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_memnoc_gfx_clk", + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_smmu_vote_clk = { + .halt_reg = 0x7d000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_smmu_vote_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = { + .halt_reg = 0x36018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_snoc_dvm_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_throttle_core_clk = { + .halt_reg = 0x36048, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x36048, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_throttle_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmu_tcu_vote_clk = { + .halt_reg = 0x7d06c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d06c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_mmu_tcu_vote_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_aux_clk = { + .halt_reg = 0xaf044, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_cfg_ahb_clk = { + .halt_reg = 0xaf010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_clkref_en = { + .halt_reg = 0xb8000, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xb8000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_mstr_axi_clk = { + .halt_reg = 0xaf020, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_pipe_clk = { + .halt_reg = 0xaf050, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0xaf050, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_rchng_phy_clk = { + .halt_reg = 0xaf040, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_rchng_phy_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_rchng_phy_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_sleep_clk = { + .halt_reg = 0xaf04c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf04c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_sleep_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_aux_phy_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_slv_axi_clk = { + .halt_reg = 0xaf018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_slv_q2a_axi_clk = { + .halt_reg = 0xaf014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_tbu_clk = { + .halt_reg = 0xaf098, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf098, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_throttle_core_clk = { + .halt_reg = 0xaf094, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf094, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_throttle_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_throttle_xo_clk = { + .halt_reg = 0xaf090, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_throttle_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_tile_axi_sys_noc_clk = { + .halt_reg = 0x10f2c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x10f2c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x10f2c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_tile_axi_sys_noc_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x2000c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2000c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pdm2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x20004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x20004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x20004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_xo4_clk = { + .halt_reg = 0x20008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm_xo4_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pwm0_xo512_clk = { + .halt_reg = 0x2002c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2002c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pwm0_xo512_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = { + .halt_reg = 0x17014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_nrt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_rt_ahb_clk = { + .halt_reg = 0x17060, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17060, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_rt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_disp_ahb_clk = { + .halt_reg = 0x17018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_disp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_gpu_cfg_ahb_clk = { + .halt_reg = 0x36040, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x36040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_gpu_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_pcie_cfg_ahb_clk = { + .halt_reg = 0xaf08c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf08c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_pcie_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = { + .halt_reg = 0x17010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_vcodec_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = { + .halt_reg = 0x1f014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_clk = { + .halt_reg = 0x1f00c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s0_clk = { + .halt_reg = 0x1f144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s1_clk = { + .halt_reg = 0x1f274, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s2_clk = { + .halt_reg = 0x1f3a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s3_clk = { + .halt_reg = 0x1f4d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s4_clk = { + .halt_reg = 0x1f604, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s5_clk = { + .halt_reg = 0x1f734, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s6_clk = { + .halt_reg = 0x1f864, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s7_clk = { + .halt_reg = 0x1f994, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s7_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s8_clk = { + .halt_reg = 0x1fac4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s8_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s8_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s9_clk = { + .halt_reg = 0x1fbf4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s9_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s9_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = { + .halt_reg = 0x1f004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1f004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_0_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = { + .halt_reg = 0x1f008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1f008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_0_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x38008, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x38008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x38008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x38004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc1_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x3800c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x3800c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3800c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_ice_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc1_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x1e008, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1e008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1e008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x1e004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1e004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_usb2_prim_axi_clk = { + .halt_reg = 0x10a14, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x10a14, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x10a14, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sys_noc_usb2_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_usb3_prim_axi_clk = { + .halt_reg = 0x1a078, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1a078, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1a078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sys_noc_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tscss_ahb_clk = { + .halt_reg = 0xac024, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xac024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xac024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_tscss_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tscss_cntr_clk = { + .halt_reg = 0xac020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xac020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_tscss_cntr_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_tscss_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tscss_etu_clk = { + .halt_reg = 0xac01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xac01c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_tscss_etu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_tscss_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_clkref_en = { + .halt_reg = 0x8c000, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x8c000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_master_clk = { + .halt_reg = 0xb0010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xb0010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb0010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_mock_utmi_clk = { + .halt_reg = 0xb001c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb001c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_sleep_clk = { + .halt_reg = 0xb0018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb0018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0x1a010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1a010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1a010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { + .halt_reg = 0x1a018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_sleep_clk = { + .halt_reg = 0x1a014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_clkref_en = { + .halt_reg = 0x9f000, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x9f000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + .halt_reg = 0x1a054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_com_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0x1a058, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x1a058, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1a058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_vcodec0_axi_clk = { + .halt_reg = 0x6e008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6e008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_vcodec0_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_venus_ahb_clk = { + .halt_reg = 0x6e010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6e010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_venus_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_venus_ctl_axi_clk = { + .halt_reg = 0x6e004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6e004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_venus_ctl_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi0_clk = { + .halt_reg = 0x1701c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1701c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1701c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_throttle_core_clk = { + .halt_reg = 0x17068, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17068, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_throttle_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_vcodec0_sys_clk = { + .halt_reg = 0x6d044, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x6d044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x6d044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_vcodec0_sys_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_video_venus_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_venus_ctl_clk = { + .halt_reg = 0x6d02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6d02c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_venus_ctl_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_video_venus_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gcc_camss_top_gdsc = { + .gdscr = 0x58004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_camss_top_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_emac0_gdsc = { + .gdscr = 0xad004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_emac0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_emac1_gdsc = { + .gdscr = 0xae004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_emac1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_pcie_gdsc = { + .gdscr = 0xaf004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_pcie_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb20_gdsc = { + .gdscr = 0xb0004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb20_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb30_prim_gdsc = { + .gdscr = 0x1a004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_venus_gdsc = { + .gdscr = 0x6d01c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_venus_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_vcodec0_gdsc = { + .gdscr = 0x6d038, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_vcodec0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &gcc_venus_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gcc_shikra_clocks[] = { + [GCC_AHB2PHY_CSI_CLK] = &gcc_ahb2phy_csi_clk.clkr, + [GCC_AHB2PHY_USB_CLK] = &gcc_ahb2phy_usb_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAM_THROTTLE_NRT_CLK] = &gcc_cam_throttle_nrt_clk.clkr, + [GCC_CAM_THROTTLE_RT_CLK] = &gcc_cam_throttle_rt_clk.clkr, + [GCC_CAMSS_AXI_CLK] = &gcc_camss_axi_clk.clkr, + [GCC_CAMSS_AXI_CLK_SRC] = &gcc_camss_axi_clk_src.clkr, + [GCC_CAMSS_CAMNOC_ATB_CLK] = &gcc_camss_camnoc_atb_clk.clkr, + [GCC_CAMSS_CAMNOC_DRAGONLINK_ATB_CLK] = &gcc_camss_camnoc_dragonlink_atb_clk.clkr, + [GCC_CAMSS_CAMNOC_NTS_XO_CLK] = &gcc_camss_camnoc_nts_xo_clk.clkr, + [GCC_CAMSS_CCI_0_CLK] = &gcc_camss_cci_0_clk.clkr, + [GCC_CAMSS_CCI_CLK_SRC] = &gcc_camss_cci_clk_src.clkr, + [GCC_CAMSS_CPHY_0_CLK] = &gcc_camss_cphy_0_clk.clkr, + [GCC_CAMSS_CPHY_1_CLK] = &gcc_camss_cphy_1_clk.clkr, + [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr, + [GCC_CAMSS_CSI0PHYTIMER_CLK_SRC] = &gcc_camss_csi0phytimer_clk_src.clkr, + [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr, + [GCC_CAMSS_CSI1PHYTIMER_CLK_SRC] = &gcc_camss_csi1phytimer_clk_src.clkr, + [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr, + [GCC_CAMSS_MCLK0_CLK_SRC] = &gcc_camss_mclk0_clk_src.clkr, + [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr, + [GCC_CAMSS_MCLK1_CLK_SRC] = &gcc_camss_mclk1_clk_src.clkr, + [GCC_CAMSS_MCLK2_CLK] = &gcc_camss_mclk2_clk.clkr, + [GCC_CAMSS_MCLK2_CLK_SRC] = &gcc_camss_mclk2_clk_src.clkr, + [GCC_CAMSS_MCLK3_CLK] = &gcc_camss_mclk3_clk.clkr, + [GCC_CAMSS_MCLK3_CLK_SRC] = &gcc_camss_mclk3_clk_src.clkr, + [GCC_CAMSS_NRT_AXI_CLK] = &gcc_camss_nrt_axi_clk.clkr, + [GCC_CAMSS_OPE_AHB_CLK] = &gcc_camss_ope_ahb_clk.clkr, + [GCC_CAMSS_OPE_AHB_CLK_SRC] = &gcc_camss_ope_ahb_clk_src.clkr, + [GCC_CAMSS_OPE_CLK] = &gcc_camss_ope_clk.clkr, + [GCC_CAMSS_OPE_CLK_SRC] = &gcc_camss_ope_clk_src.clkr, + [GCC_CAMSS_RT_AXI_CLK] = &gcc_camss_rt_axi_clk.clkr, + [GCC_CAMSS_TFE_0_CLK] = &gcc_camss_tfe_0_clk.clkr, + [GCC_CAMSS_TFE_0_CLK_SRC] = &gcc_camss_tfe_0_clk_src.clkr, + [GCC_CAMSS_TFE_0_CPHY_RX_CLK] = &gcc_camss_tfe_0_cphy_rx_clk.clkr, + [GCC_CAMSS_TFE_0_CSID_CLK] = &gcc_camss_tfe_0_csid_clk.clkr, + [GCC_CAMSS_TFE_0_CSID_CLK_SRC] = &gcc_camss_tfe_0_csid_clk_src.clkr, + [GCC_CAMSS_TFE_1_CLK] = &gcc_camss_tfe_1_clk.clkr, + [GCC_CAMSS_TFE_1_CLK_SRC] = &gcc_camss_tfe_1_clk_src.clkr, + [GCC_CAMSS_TFE_1_CPHY_RX_CLK] = &gcc_camss_tfe_1_cphy_rx_clk.clkr, + [GCC_CAMSS_TFE_1_CSID_CLK] = &gcc_camss_tfe_1_csid_clk.clkr, + [GCC_CAMSS_TFE_1_CSID_CLK_SRC] = &gcc_camss_tfe_1_csid_clk_src.clkr, + [GCC_CAMSS_TFE_CPHY_RX_CLK_SRC] = &gcc_camss_tfe_cphy_rx_clk_src.clkr, + [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr, + [GCC_CAMSS_TOP_AHB_CLK_SRC] = &gcc_camss_top_ahb_clk_src.clkr, + [GCC_CFG_NOC_USB2_PRIM_AXI_CLK] = &gcc_cfg_noc_usb2_prim_axi_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, + [GCC_DDRSS_MEMNOC_PCIE_SF_CLK] = &gcc_ddrss_memnoc_pcie_sf_clk.clkr, + [GCC_DISP_GPLL0_CLK_SRC] = &gcc_disp_gpll0_clk_src.clkr, + [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_DISP_THROTTLE_CORE_CLK] = &gcc_disp_throttle_core_clk.clkr, + [GCC_EMAC0_AHB_CLK] = &gcc_emac0_ahb_clk.clkr, + [GCC_EMAC0_AXI_CLK] = &gcc_emac0_axi_clk.clkr, + [GCC_EMAC0_AXI_CLK_SRC] = &gcc_emac0_axi_clk_src.clkr, + [GCC_EMAC0_AXI_SYS_NOC_CLK] = &gcc_emac0_axi_sys_noc_clk.clkr, + [GCC_EMAC0_CC_SGMIIPHY_RX_CLK] = &gcc_emac0_cc_sgmiiphy_rx_clk.clkr, + [GCC_EMAC0_CC_SGMIIPHY_RX_CLK_SRC] = &gcc_emac0_cc_sgmiiphy_rx_clk_src.clkr, + [GCC_EMAC0_CC_SGMIIPHY_TX_CLK] = &gcc_emac0_cc_sgmiiphy_tx_clk.clkr, + [GCC_EMAC0_CC_SGMIIPHY_TX_CLK_SRC] = &gcc_emac0_cc_sgmiiphy_tx_clk_src.clkr, + [GCC_EMAC0_PHY_AUX_CLK] = &gcc_emac0_phy_aux_clk.clkr, + [GCC_EMAC0_PHY_AUX_CLK_SRC] = &gcc_emac0_phy_aux_clk_src.clkr, + [GCC_EMAC0_PTP_CLK] = &gcc_emac0_ptp_clk.clkr, + [GCC_EMAC0_PTP_CLK_SRC] = &gcc_emac0_ptp_clk_src.clkr, + [GCC_EMAC0_RGMII_CLK] = &gcc_emac0_rgmii_clk.clkr, + [GCC_EMAC0_RGMII_CLK_SRC] = &gcc_emac0_rgmii_clk_src.clkr, + [GCC_EMAC1_AHB_CLK] = &gcc_emac1_ahb_clk.clkr, + [GCC_EMAC1_AXI_CLK] = &gcc_emac1_axi_clk.clkr, + [GCC_EMAC1_AXI_CLK_SRC] = &gcc_emac1_axi_clk_src.clkr, + [GCC_EMAC1_AXI_SYS_NOC_CLK] = &gcc_emac1_axi_sys_noc_clk.clkr, + [GCC_EMAC1_CC_SGMIIPHY_RX_CLK] = &gcc_emac1_cc_sgmiiphy_rx_clk.clkr, + [GCC_EMAC1_CC_SGMIIPHY_RX_CLK_SRC] = &gcc_emac1_cc_sgmiiphy_rx_clk_src.clkr, + [GCC_EMAC1_CC_SGMIIPHY_TX_CLK] = &gcc_emac1_cc_sgmiiphy_tx_clk.clkr, + [GCC_EMAC1_CC_SGMIIPHY_TX_CLK_SRC] = &gcc_emac1_cc_sgmiiphy_tx_clk_src.clkr, + [GCC_EMAC1_PHY_AUX_CLK] = &gcc_emac1_phy_aux_clk.clkr, + [GCC_EMAC1_PHY_AUX_CLK_SRC] = &gcc_emac1_phy_aux_clk_src.clkr, + [GCC_EMAC1_PTP_CLK] = &gcc_emac1_ptp_clk.clkr, + [GCC_EMAC1_PTP_CLK_SRC] = &gcc_emac1_ptp_clk_src.clkr, + [GCC_EMAC1_RGMII_CLK] = &gcc_emac1_rgmii_clk.clkr, + [GCC_EMAC1_RGMII_CLK_SRC] = &gcc_emac1_rgmii_clk_src.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, + [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr, + [GCC_GPU_SMMU_VOTE_CLK] = &gcc_gpu_smmu_vote_clk.clkr, + [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr, + [GCC_GPU_THROTTLE_CORE_CLK] = &gcc_gpu_throttle_core_clk.clkr, + [GCC_MMU_TCU_VOTE_CLK] = &gcc_mmu_tcu_vote_clk.clkr, + [GCC_PCIE_AUX_CLK] = &gcc_pcie_aux_clk.clkr, + [GCC_PCIE_AUX_CLK_SRC] = &gcc_pcie_aux_clk_src.clkr, + [GCC_PCIE_AUX_PHY_CLK_SRC] = &gcc_pcie_aux_phy_clk_src.clkr, + [GCC_PCIE_CFG_AHB_CLK] = &gcc_pcie_cfg_ahb_clk.clkr, + [GCC_PCIE_CLKREF_EN] = &gcc_pcie_clkref_en.clkr, + [GCC_PCIE_MSTR_AXI_CLK] = &gcc_pcie_mstr_axi_clk.clkr, + [GCC_PCIE_PIPE_CLK] = &gcc_pcie_pipe_clk.clkr, + [GCC_PCIE_PIPE_CLK_SRC] = &gcc_pcie_pipe_clk_src.clkr, + [GCC_PCIE_RCHNG_PHY_CLK] = &gcc_pcie_rchng_phy_clk.clkr, + [GCC_PCIE_RCHNG_PHY_CLK_SRC] = &gcc_pcie_rchng_phy_clk_src.clkr, + [GCC_PCIE_SLEEP_CLK] = &gcc_pcie_sleep_clk.clkr, + [GCC_PCIE_SLV_AXI_CLK] = &gcc_pcie_slv_axi_clk.clkr, + [GCC_PCIE_SLV_Q2A_AXI_CLK] = &gcc_pcie_slv_q2a_axi_clk.clkr, + [GCC_PCIE_TBU_CLK] = &gcc_pcie_tbu_clk.clkr, + [GCC_PCIE_THROTTLE_CORE_CLK] = &gcc_pcie_throttle_core_clk.clkr, + [GCC_PCIE_THROTTLE_XO_CLK] = &gcc_pcie_throttle_xo_clk.clkr, + [GCC_PCIE_TILE_AXI_SYS_NOC_CLK] = &gcc_pcie_tile_axi_sys_noc_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, + [GCC_PWM0_XO512_CLK] = &gcc_pwm0_xo512_clk.clkr, + [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr, + [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr, + [GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr, + [GCC_QMIP_GPU_CFG_AHB_CLK] = &gcc_qmip_gpu_cfg_ahb_clk.clkr, + [GCC_QMIP_PCIE_CFG_AHB_CLK] = &gcc_qmip_pcie_cfg_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr, + [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr, + [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr, + [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr, + [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr, + [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr, + [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr, + [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr, + [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr, + [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr, + [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr, + [GCC_QUPV3_WRAP0_S6_CLK] = &gcc_qupv3_wrap0_s6_clk.clkr, + [GCC_QUPV3_WRAP0_S6_CLK_SRC] = &gcc_qupv3_wrap0_s6_clk_src.clkr, + [GCC_QUPV3_WRAP0_S7_CLK] = &gcc_qupv3_wrap0_s7_clk.clkr, + [GCC_QUPV3_WRAP0_S7_CLK_SRC] = &gcc_qupv3_wrap0_s7_clk_src.clkr, + [GCC_QUPV3_WRAP0_S8_CLK] = &gcc_qupv3_wrap0_s8_clk.clkr, + [GCC_QUPV3_WRAP0_S8_CLK_SRC] = &gcc_qupv3_wrap0_s8_clk_src.clkr, + [GCC_QUPV3_WRAP0_S9_CLK] = &gcc_qupv3_wrap0_s9_clk.clkr, + [GCC_QUPV3_WRAP0_S9_CLK_SRC] = &gcc_qupv3_wrap0_s9_clk_src.clkr, + [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_SYS_NOC_USB2_PRIM_AXI_CLK] = &gcc_sys_noc_usb2_prim_axi_clk.clkr, + [GCC_SYS_NOC_USB3_PRIM_AXI_CLK] = &gcc_sys_noc_usb3_prim_axi_clk.clkr, + [GCC_TSCSS_AHB_CLK] = &gcc_tscss_ahb_clk.clkr, + [GCC_TSCSS_CLK_SRC] = &gcc_tscss_clk_src.clkr, + [GCC_TSCSS_CNTR_CLK] = &gcc_tscss_cntr_clk.clkr, + [GCC_TSCSS_ETU_CLK] = &gcc_tscss_etu_clk.clkr, + [GCC_UFS_CLKREF_EN] = &gcc_ufs_clkref_en.clkr, + [GCC_USB20_MASTER_CLK] = &gcc_usb20_master_clk.clkr, + [GCC_USB20_MASTER_CLK_SRC] = &gcc_usb20_master_clk_src.clkr, + [GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr, + [GCC_USB20_MOCK_UTMI_CLK_SRC] = &gcc_usb20_mock_utmi_clk_src.clkr, + [GCC_USB20_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb20_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB20_SLEEP_CLK] = &gcc_usb20_sleep_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB3_PRIM_CLKREF_EN] = &gcc_usb3_prim_clkref_en.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb3_prim_phy_pipe_clk_src.clkr, + [GCC_VCODEC0_AXI_CLK] = &gcc_vcodec0_axi_clk.clkr, + [GCC_VENUS_AHB_CLK] = &gcc_venus_ahb_clk.clkr, + [GCC_VENUS_CTL_AXI_CLK] = &gcc_venus_ctl_axi_clk.clkr, + [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, + [GCC_VIDEO_THROTTLE_CORE_CLK] = &gcc_video_throttle_core_clk.clkr, + [GCC_VIDEO_VCODEC0_SYS_CLK] = &gcc_video_vcodec0_sys_clk.clkr, + [GCC_VIDEO_VENUS_CLK_SRC] = &gcc_video_venus_clk_src.clkr, + [GCC_VIDEO_VENUS_CTL_CLK] = &gcc_video_venus_ctl_clk.clkr, + [GPLL0] = &gpll0.clkr, + [GPLL0_OUT_AUX2] = &gpll0_out_aux2.clkr, + [GPLL10] = &gpll10.clkr, + [GPLL11] = &gpll11.clkr, + [GPLL12] = &gpll12.clkr, + [GPLL12_OUT_AUX2] = &gpll12_out_aux2.clkr, + [GPLL3] = &gpll3.clkr, + [GPLL3_OUT_MAIN] = &gpll3_out_main.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL5] = &gpll5.clkr, + [GPLL6] = &gpll6.clkr, + [GPLL6_OUT_MAIN] = &gpll6_out_main.clkr, + [GPLL7] = &gpll7.clkr, + [GPLL8] = &gpll8.clkr, + [GPLL8_OUT_MAIN] = &gpll8_out_main.clkr, + [GPLL9] = &gpll9.clkr, + [GPLL9_OUT_MAIN] = &gpll9_out_main.clkr, +}; + +static struct gdsc *gcc_shikra_gdscs[] = { + [GCC_CAMSS_TOP_GDSC] = &gcc_camss_top_gdsc, + [GCC_EMAC0_GDSC] = &gcc_emac0_gdsc, + [GCC_EMAC1_GDSC] = &gcc_emac1_gdsc, + [GCC_PCIE_GDSC] = &gcc_pcie_gdsc, + [GCC_USB20_GDSC] = &gcc_usb20_gdsc, + [GCC_USB30_PRIM_GDSC] = &gcc_usb30_prim_gdsc, + [GCC_VCODEC0_GDSC] = &gcc_vcodec0_gdsc, + [GCC_VENUS_GDSC] = &gcc_venus_gdsc, +}; + +static const struct qcom_reset_map gcc_shikra_resets[] = { + [GCC_CAMSS_OPE_BCR] = { 0x55000 }, + [GCC_CAMSS_TFE_BCR] = { 0x52000 }, + [GCC_CAMSS_TOP_BCR] = { 0x58000 }, + [GCC_EMAC0_BCR] = { 0xad000 }, + [GCC_EMAC1_BCR] = { 0xae000 }, + [GCC_GPU_BCR] = { 0x36000 }, + [GCC_MMSS_BCR] = { 0x17000 }, + [GCC_PCIE_BCR] = { 0xaf000 }, + [GCC_PCIE_PHY_BCR] = { 0xb1000 }, + [GCC_PDM_BCR] = { 0x20000 }, + [GCC_QUPV3_WRAPPER_0_BCR] = { 0x1f000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0x1c000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x1c004 }, + [GCC_SDCC1_BCR] = { 0x38000 }, + [GCC_SDCC2_BCR] = { 0x1e000 }, + [GCC_TSCSS_BCR] = { 0xac000 }, + [GCC_USB20_BCR] = { 0xb0000 }, + [GCC_USB30_PRIM_BCR] = { 0x1a000 }, + [GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x1b008 }, + [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x1b020 }, + [GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x1b000 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x1d000 }, + [GCC_VCODEC0_BCR] = { 0x6d034 }, + [GCC_VENUS_BCR] = { 0x6d018 }, + [GCC_VIDEO_INTERFACE_BCR] = { 0x6e000 }, +}; + +static struct clk_alpha_pll *gcc_shikra_plls[] = { + &gpll10, + &gpll11, + &gpll8, + &gpll9, +}; + +static const u32 gcc_shikra_critical_cbcrs[] = { + 0x17008, /* GCC_CAMERA_AHB_CLK */ + 0x17028, /* GCC_CAMERA_XO_CLK */ + 0x1700c, /* GCC_DISP_AHB_CLK */ + 0x1702c, /* GCC_DISP_XO_CLK */ + 0x36004, /* GCC_GPU_CFG_AHB_CLK */ + 0x36100, /* GCC_GPU_IREF_CLK */ + 0x3a00c, /* GCC_LPASS_CONFIG_CLK */ + 0x3a008, /* GCC_LPASS_CORE_AXIM_CLK */ + 0x79004, /* GCC_SYS_NOC_CPUSS_AHB_CLK */ + 0x17004, /* GCC_VIDEO_AHB_CLK */ + 0x17024, /* GCC_VIDEO_XO_CLK */ +}; + +static const struct clk_rcg_dfs_data gcc_shikra_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s8_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s9_clk_src), +}; + +static const struct regmap_config gcc_shikra_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xc7000, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data gcc_shikra_driver_data = { + .alpha_plls = gcc_shikra_plls, + .num_alpha_plls = ARRAY_SIZE(gcc_shikra_plls), + .clk_cbcrs = gcc_shikra_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_shikra_critical_cbcrs), + .dfs_rcgs = gcc_shikra_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_shikra_dfs_clocks), +}; + +static const struct qcom_cc_desc gcc_shikra_desc = { + .config = &gcc_shikra_regmap_config, + .clks = gcc_shikra_clocks, + .num_clks = ARRAY_SIZE(gcc_shikra_clocks), + .resets = gcc_shikra_resets, + .num_resets = ARRAY_SIZE(gcc_shikra_resets), + .gdscs = gcc_shikra_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_shikra_gdscs), + .driver_data = &gcc_shikra_driver_data, +}; + +static const struct of_device_id gcc_shikra_match_table[] = { + { .compatible = "qcom,shikra-gcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_shikra_match_table); + +static int gcc_shikra_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gcc_shikra_desc); +} + +static struct platform_driver gcc_shikra_driver = { + .probe = gcc_shikra_probe, + .driver = { + .name = "gcc-shikra", + .of_match_table = gcc_shikra_match_table, + }, +}; + +static int __init gcc_shikra_init(void) +{ + return platform_driver_register(&gcc_shikra_driver); +} +subsys_initcall(gcc_shikra_init); + +static void __exit gcc_shikra_exit(void) +{ + platform_driver_unregister(&gcc_shikra_driver); +} +module_exit(gcc_shikra_exit); + +MODULE_DESCRIPTION("QTI GCC Shikra Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-sm6115.c b/drivers/clk/qcom/gcc-sm6115.c index 4c3804701e24..a3c9dbe3a48a 100644 --- a/drivers/clk/qcom/gcc-sm6115.c +++ b/drivers/clk/qcom/gcc-sm6115.c @@ -120,7 +120,7 @@ static const struct alpha_pll_config gpll10_config = { .vco_mask = GENMASK(21, 20), .main_output_mask = BIT(0), .config_ctl_val = 0x4001055b, - .test_ctl_hi1_val = 0x1, + .test_ctl_hi_val = 0x1, .test_ctl_hi_mask = 0x1, }; @@ -173,7 +173,7 @@ static const struct alpha_pll_config gpll11_config = { .vco_val = 0x2 << 20, .vco_mask = GENMASK(21, 20), .config_ctl_val = 0x4001055b, - .test_ctl_hi1_val = 0x1, + .test_ctl_hi_val = 0x1, .test_ctl_hi_mask = 0x1, }; @@ -367,7 +367,7 @@ static const struct alpha_pll_config gpll8_config = { .post_div_val = 0x1 << 8, .post_div_mask = GENMASK(11, 8), .config_ctl_val = 0x4001055b, - .test_ctl_hi1_val = 0x1, + .test_ctl_hi_val = 0x1, .test_ctl_hi_mask = 0x1, }; @@ -3218,6 +3218,7 @@ static struct gdsc gcc_vcodec0_gdsc = { .pd = { .name = "gcc_vcodec0", }, + .flags = HW_CTRL_TRIGGER, .pwrsts = PWRSTS_OFF_ON, }; diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index ee5f86ca50cb..b99d70149af3 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -104,14 +104,21 @@ static int gdsc_hwctrl(struct gdsc *sc, bool en) static int gdsc_poll_status(struct gdsc *sc, enum gdsc_status status) { ktime_t start; + int ret; start = ktime_get(); do { - if (gdsc_check_status(sc, status)) + ret = gdsc_check_status(sc, status); + if (ret < 0) + return ret; + if (ret) return 0; } while (ktime_us_delta(ktime_get(), start) < STATUS_POLL_TIMEOUT_US); - if (gdsc_check_status(sc, status)) + ret = gdsc_check_status(sc, status); + if (ret < 0) + return ret; + if (ret) return 0; return -ETIMEDOUT; @@ -493,7 +500,9 @@ static int gdsc_init(struct gdsc *sc) } else if (sc->flags & ALWAYS_ON) { /* If ALWAYS_ON GDSCs are not ON, turn them ON */ - gdsc_enable(&sc->pd); + ret = gdsc_enable(&sc->pd); + if (ret) + return ret; on = true; } @@ -669,10 +678,18 @@ err_pm_subdomain_remove: void gdsc_unregister(struct gdsc_desc *desc) { struct device *dev = desc->dev; + struct gdsc **scs = desc->scs; size_t num = desc->num; + int i; - gdsc_pm_subdomain_remove(desc, num); of_genpd_del_provider(dev->of_node); + gdsc_pm_subdomain_remove(desc, num); + + for (i = 0; i < num; i++) { + if (!scs[i]) + continue; + pm_genpd_remove(&scs[i]->pd); + } } /* @@ -708,3 +725,25 @@ int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain) return ret; } EXPORT_SYMBOL_GPL(gdsc_gx_do_nothing_enable); + +/* + * GX GDSC is a special power domain. Normally, its disable sequence + * is managed by the GMU firmware, and high level OS must not attempt + * to disable it. The only exception is during GMU recovery, where the + * GMU driver can set GenPD’s synced_poweroff flag to allow explicitly + * disable GX GDSC in hardware. + */ +int gdsc_gx_disable(struct generic_pm_domain *domain) +{ + struct gdsc *sc = domain_to_gdsc(domain); + + if (domain->synced_poweroff) + return gdsc_disable(domain); + + /* Remove parent-supply placed in enable */ + if (sc->rsupply) + return regulator_disable(sc->rsupply); + + return 0; +} +EXPORT_SYMBOL_GPL(gdsc_gx_disable); diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index 92ff6bcce7b1..2f9665b664e6 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -93,6 +93,7 @@ int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *, struct regmap *); void gdsc_unregister(struct gdsc_desc *desc); int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain); +int gdsc_gx_disable(struct generic_pm_domain *domain); #else static inline int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *rcdev, diff --git a/drivers/clk/qcom/gpu2cc-nord.c b/drivers/clk/qcom/gpu2cc-nord.c new file mode 100644 index 000000000000..a05ff9fa1506 --- /dev/null +++ b/drivers/clk/qcom/gpu2cc-nord.c @@ -0,0 +1,545 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_GPLL0_OUT_MAIN, + DT_GPLL0_OUT_MAIN_DIV, +}; + +enum { + P_BI_TCXO, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_2_CC_PLL0_OUT_MAIN, + P_GPU_2_CC_PLL1_OUT_MAIN, +}; + +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + +/* 934.0 MHz Configuration */ +static const struct alpha_pll_config gpu_2_cc_pll0_config = { + .l = 0x30, + .alpha = 0xa555, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll gpu_2_cc_pll0 = { + .offset = 0x0, + .config = &gpu_2_cc_pll0_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +/* 1100.0 MHz Configuration */ +static const struct alpha_pll_config gpu_2_cc_pll1_config = { + .l = 0x39, + .alpha = 0x4aaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll gpu_2_cc_pll1 = { + .offset = 0x1000, + .config = &gpu_2_cc_pll1_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct parent_map gpu_2_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_2_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct parent_map gpu_2_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_2_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_2_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_2_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpu_2_cc_pll0.clkr.hw }, + { .hw = &gpu_2_cc_pll1.clkr.hw }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct parent_map gpu_2_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GPU_2_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_2_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpu_2_cc_pll1.clkr.hw }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct freq_tbl ftbl_gpu_2_cc_ff_clk_src[] = { + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_2_cc_ff_clk_src = { + .cmd_rcgr = 0x91c4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_2_cc_parent_map_0, + .freq_tbl = ftbl_gpu_2_cc_ff_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_ff_clk_src", + .parent_data = gpu_2_cc_parent_data_0, + .num_parents = ARRAY_SIZE(gpu_2_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_2_cc_gmu_clk_src[] = { + F(550000000, P_GPU_2_CC_PLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_2_cc_gmu_clk_src = { + .cmd_rcgr = 0x9174, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_2_cc_parent_map_1, + .freq_tbl = ftbl_gpu_2_cc_gmu_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_gmu_clk_src", + .parent_data = gpu_2_cc_parent_data_1, + .num_parents = ARRAY_SIZE(gpu_2_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gpu_2_cc_hub_clk_src = { + .cmd_rcgr = 0x91a8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_2_cc_parent_map_2, + .freq_tbl = ftbl_gpu_2_cc_ff_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_hub_clk_src", + .parent_data = gpu_2_cc_parent_data_2, + .num_parents = ARRAY_SIZE(gpu_2_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch gpu_2_cc_ahb_clk = { + .halt_reg = 0x90cc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_2_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_crc_ahb_clk = { + .halt_reg = 0x90d0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_crc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_2_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_cx_accu_shift_clk = { + .halt_reg = 0x9114, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9114, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_cx_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_cx_ff_clk = { + .halt_reg = 0x9100, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9100, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_cx_ff_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_2_cc_ff_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_cx_gmu_clk = { + .halt_reg = 0x90e8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_cx_gmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_2_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_cxo_clk = { + .halt_reg = 0x90f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x90f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_cxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_freq_measure_clk = { + .halt_reg = 0x9008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_freq_measure_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_gpu_smmu_vote_clk = { + .halt_reg = 0x7000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_gpu_smmu_vote_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_hub_aon_clk = { + .halt_reg = 0x91a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x91a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_hub_aon_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_2_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_hub_cx_int_clk = { + .halt_reg = 0x90fc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_hub_cx_int_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_2_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_memnoc_gfx_clk = { + .halt_reg = 0x9104, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9104, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_mnd1x_0_gfx3d_clk = { + .halt_reg = 0x9164, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9164, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_mnd1x_0_gfx3d_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_mnd1x_1_gfx3d_clk = { + .halt_reg = 0x9168, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9168, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_mnd1x_1_gfx3d_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_2_cc_sleep_clk = { + .halt_reg = 0x90e0, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x90e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_2_cc_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gpu_2_cc_cx_gdsc = { + .gdscr = 0x9090, + .gds_hw_ctrl = 0x90a4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gpu_2_cc_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE, +}; + +static struct gdsc gpu_2_cc_gx_gdsc = { + .gdscr = 0x9034, + .clamp_io_ctrl = 0x9504, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gpu_2_cc_gx_gdsc", + .power_on = gdsc_gx_do_nothing_enable, + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = CLAMP_IO | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gpu_2_cc_nord_clocks[] = { + [GPU_2_CC_AHB_CLK] = &gpu_2_cc_ahb_clk.clkr, + [GPU_2_CC_CRC_AHB_CLK] = &gpu_2_cc_crc_ahb_clk.clkr, + [GPU_2_CC_CX_ACCU_SHIFT_CLK] = &gpu_2_cc_cx_accu_shift_clk.clkr, + [GPU_2_CC_CX_FF_CLK] = &gpu_2_cc_cx_ff_clk.clkr, + [GPU_2_CC_CX_GMU_CLK] = &gpu_2_cc_cx_gmu_clk.clkr, + [GPU_2_CC_CXO_CLK] = &gpu_2_cc_cxo_clk.clkr, + [GPU_2_CC_FF_CLK_SRC] = &gpu_2_cc_ff_clk_src.clkr, + [GPU_2_CC_FREQ_MEASURE_CLK] = &gpu_2_cc_freq_measure_clk.clkr, + [GPU_2_CC_GMU_CLK_SRC] = &gpu_2_cc_gmu_clk_src.clkr, + [GPU_2_CC_GPU_SMMU_VOTE_CLK] = &gpu_2_cc_gpu_smmu_vote_clk.clkr, + [GPU_2_CC_HUB_AON_CLK] = &gpu_2_cc_hub_aon_clk.clkr, + [GPU_2_CC_HUB_CLK_SRC] = &gpu_2_cc_hub_clk_src.clkr, + [GPU_2_CC_HUB_CX_INT_CLK] = &gpu_2_cc_hub_cx_int_clk.clkr, + [GPU_2_CC_MEMNOC_GFX_CLK] = &gpu_2_cc_memnoc_gfx_clk.clkr, + [GPU_2_CC_MND1X_0_GFX3D_CLK] = &gpu_2_cc_mnd1x_0_gfx3d_clk.clkr, + [GPU_2_CC_MND1X_1_GFX3D_CLK] = &gpu_2_cc_mnd1x_1_gfx3d_clk.clkr, + [GPU_2_CC_PLL0] = &gpu_2_cc_pll0.clkr, + [GPU_2_CC_PLL1] = &gpu_2_cc_pll1.clkr, + [GPU_2_CC_SLEEP_CLK] = &gpu_2_cc_sleep_clk.clkr, +}; + +static struct gdsc *gpu_2_cc_nord_gdscs[] = { + [GPU_2_CC_CX_GDSC] = &gpu_2_cc_cx_gdsc, + [GPU_2_CC_GX_GDSC] = &gpu_2_cc_gx_gdsc, +}; + +static const struct qcom_reset_map gpu_2_cc_nord_resets[] = { + [GPU_2_CC_ACD_BCR] = { 0x918c }, + [GPU_2_CC_CB_BCR] = { 0x9198 }, + [GPU_2_CC_CX_BCR] = { 0x908c }, + [GPU_2_CC_FAST_HUB_BCR] = { 0x91a0 }, + [GPU_2_CC_FF_BCR] = { 0x91c0 }, + [GPU_2_CC_GFX3D_AON_BCR] = { 0x9118 }, + [GPU_2_CC_GMU_BCR] = { 0x9170 }, + [GPU_2_CC_GX_BCR] = { 0x9030 }, + [GPU_2_CC_XO_BCR] = { 0x9000 }, +}; + +static struct clk_alpha_pll *gpu_2_cc_nord_plls[] = { + &gpu_2_cc_pll0, + &gpu_2_cc_pll1, +}; + +static const u32 gpu_2_cc_nord_critical_cbcrs[] = { + 0x9004, /* GPU_2_CC_CXO_AON_CLK */ + 0x900c, /* GPU_2_CC_DEMET_CLK */ +}; + +static const struct regmap_config gpu_2_cc_nord_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9ff0, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data gpu_2_cc_nord_driver_data = { + .alpha_plls = gpu_2_cc_nord_plls, + .num_alpha_plls = ARRAY_SIZE(gpu_2_cc_nord_plls), + .clk_cbcrs = gpu_2_cc_nord_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_2_cc_nord_critical_cbcrs), +}; + +static const struct qcom_cc_desc gpu_2_cc_nord_desc = { + .config = &gpu_2_cc_nord_regmap_config, + .clks = gpu_2_cc_nord_clocks, + .num_clks = ARRAY_SIZE(gpu_2_cc_nord_clocks), + .resets = gpu_2_cc_nord_resets, + .num_resets = ARRAY_SIZE(gpu_2_cc_nord_resets), + .gdscs = gpu_2_cc_nord_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_2_cc_nord_gdscs), + .use_rpm = true, + .driver_data = &gpu_2_cc_nord_driver_data, +}; + +static const struct of_device_id gpu_2_cc_nord_match_table[] = { + { .compatible = "qcom,nord-gpu2cc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_2_cc_nord_match_table); + +static int gpu_2_cc_nord_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gpu_2_cc_nord_desc); +} + +static struct platform_driver gpu_2_cc_nord_driver = { + .probe = gpu_2_cc_nord_probe, + .driver = { + .name = "gpu2cc-nord", + .of_match_table = gpu_2_cc_nord_match_table, + }, +}; + +module_platform_driver(gpu_2_cc_nord_driver); + +MODULE_DESCRIPTION("QTI GPU2CC Nord Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gpucc-nord.c b/drivers/clk/qcom/gpucc-nord.c new file mode 100644 index 000000000000..f37bc32e80ff --- /dev/null +++ b/drivers/clk/qcom/gpucc-nord.c @@ -0,0 +1,593 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_GPLL0_OUT_MAIN, + DT_GPLL0_OUT_MAIN_DIV, +}; + +enum { + P_BI_TCXO, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL1_OUT_MAIN, +}; + +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + +/* 936.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x30, + .alpha = 0xc000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .config = &gpu_cc_pll0_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +/* 1250.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x41, + .alpha = 0x1aaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll gpu_cc_pll1 = { + .offset = 0x1000, + .config = &gpu_cc_pll1_config, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct parent_map gpu_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct freq_tbl ftbl_gpu_cc_ff_clk_src[] = { + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_ff_clk_src = { + .cmd_rcgr = 0x93d4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .freq_tbl = ftbl_gpu_cc_ff_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_ff_clk_src", + .parent_data = gpu_cc_parent_data_0, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(416666667, P_GPU_CC_PLL1_OUT_MAIN, 3, 0, 0), + F(625000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x92b8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_1, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gmu_clk_src", + .parent_data = gpu_cc_parent_data_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = { + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_hub_clk_src = { + .cmd_rcgr = 0x938c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_2, + .freq_tbl = ftbl_gpu_cc_hub_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_clk_src", + .parent_data = gpu_cc_parent_data_2, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div gpu_cc_hub_div_clk_src = { + .reg = 0x93cc, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gpu_cc_acd_gfx3d_clk = { + .halt_reg = 0x92a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x92a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_acd_gfx3d_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_acmu_clk = { + .halt_reg = 0x9294, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9294, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_acmu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_ahb_clk = { + .halt_reg = 0x9150, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x9150, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_crc_ahb_clk = { + .halt_reg = 0x9154, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9154, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_crc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_accu_shift_clk = { + .halt_reg = 0x91a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x91a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_ff_clk = { + .halt_reg = 0x9184, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9184, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_ff_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_ff_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gmu_clk = { + .halt_reg = 0x916c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x916c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_gmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_clk = { + .halt_reg = 0x917c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x917c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_dpm_clk = { + .halt_reg = 0x91a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x91a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_dpm_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_freq_measure_clk = { + .halt_reg = 0x9008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_freq_measure_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gpu_smmu_vote_clk = { + .halt_reg = 0x7000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gpu_smmu_vote_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_aon_clk = { + .halt_reg = 0x9388, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9388, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_aon_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_cx_int_clk = { + .halt_reg = 0x9180, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9180, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_cx_int_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_memnoc_gfx_clk = { + .halt_reg = 0x9188, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9188, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_mnd1x_gfx3d_clk = { + .halt_reg = 0x92ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x92ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_mnd1x_gfx3d_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_sleep_clk = { + .halt_reg = 0x9164, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9164, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gpu_cc_cx_gdsc = { + .gdscr = 0x90e8, + .gds_hw_ctrl = 0x9128, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gpu_cc_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE, +}; + +static struct gdsc gpu_cc_gx_gdsc = { + .gdscr = 0x905c, + .clamp_io_ctrl = 0x9504, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gpu_cc_gx_gdsc", + .power_on = gdsc_gx_do_nothing_enable, + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = CLAMP_IO | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gpu_cc_nord_clocks[] = { + [GPU_CC_ACD_GFX3D_CLK] = &gpu_cc_acd_gfx3d_clk.clkr, + [GPU_CC_ACMU_CLK] = &gpu_cc_acmu_clk.clkr, + [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, + [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, + [GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr, + [GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr, + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, + [GPU_CC_DPM_CLK] = &gpu_cc_dpm_clk.clkr, + [GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr, + [GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr, + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_GPU_SMMU_VOTE_CLK] = &gpu_cc_gpu_smmu_vote_clk.clkr, + [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, + [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr, + [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr, + [GPU_CC_HUB_DIV_CLK_SRC] = &gpu_cc_hub_div_clk_src.clkr, + [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr, + [GPU_CC_MND1X_GFX3D_CLK] = &gpu_cc_mnd1x_gfx3d_clk.clkr, + [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, + [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, + [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, +}; + +static struct gdsc *gpu_cc_nord_gdscs[] = { + [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc, + [GPU_CC_GX_GDSC] = &gpu_cc_gx_gdsc, +}; + +static const struct qcom_reset_map gpu_cc_nord_resets[] = { + [GPU_CC_ACD_BCR] = { 0x92f8 }, + [GPU_CC_CB_BCR] = { 0x9340 }, + [GPU_CC_CX_BCR] = { 0x90e4 }, + [GPU_CC_FAST_HUB_BCR] = { 0x9384 }, + [GPU_CC_GFX3D_AON_BCR] = { 0x91ac }, + [GPU_CC_GX_BCR] = { 0x9058 }, + [GPU_CC_XO_BCR] = { 0x9000 }, +}; + +static struct clk_alpha_pll *gpu_cc_nord_plls[] = { + &gpu_cc_pll0, + &gpu_cc_pll1, +}; + +static const u32 gpu_cc_nord_critical_cbcrs[] = { + 0x9004, /* GPU_CC_CXO_AON_CLK */ + 0x900c, /* GPU_CC_DEMET_CLK */ +}; + +static const struct regmap_config gpu_cc_nord_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9660, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data gpu_cc_nord_driver_data = { + .alpha_plls = gpu_cc_nord_plls, + .num_alpha_plls = ARRAY_SIZE(gpu_cc_nord_plls), + .clk_cbcrs = gpu_cc_nord_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_nord_critical_cbcrs), +}; + +static const struct qcom_cc_desc gpu_cc_nord_desc = { + .config = &gpu_cc_nord_regmap_config, + .clks = gpu_cc_nord_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_nord_clocks), + .resets = gpu_cc_nord_resets, + .num_resets = ARRAY_SIZE(gpu_cc_nord_resets), + .gdscs = gpu_cc_nord_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_nord_gdscs), + .use_rpm = true, + .driver_data = &gpu_cc_nord_driver_data, +}; + +static const struct of_device_id gpu_cc_nord_match_table[] = { + { .compatible = "qcom,nord-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_nord_match_table); + +static int gpu_cc_nord_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gpu_cc_nord_desc); +} + +static struct platform_driver gpu_cc_nord_driver = { + .probe = gpu_cc_nord_probe, + .driver = { + .name = "gpucc-nord", + .of_match_table = gpu_cc_nord_match_table, + }, +}; + +module_platform_driver(gpu_cc_nord_driver); + +MODULE_DESCRIPTION("QTI GPUCC Nord Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gpucc-qcm2290.c b/drivers/clk/qcom/gpucc-qcm2290.c index 66dea9d2a0e5..ece567c533e8 100644 --- a/drivers/clk/qcom/gpucc-qcm2290.c +++ b/drivers/clk/qcom/gpucc-qcm2290.c @@ -2,13 +2,12 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. * Copyright (c) 2024, Linaro Limited + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include #include #include -#include -#include #include #include @@ -20,6 +19,7 @@ #include "clk-regmap-divider.h" #include "clk-regmap-mux.h" #include "clk-regmap-phy-mux.h" +#include "common.h" #include "gdsc.h" #include "reset.h" @@ -56,6 +56,7 @@ static const struct alpha_pll_config gpu_cc_pll0_config = { static struct clk_alpha_pll gpu_cc_pll0 = { .offset = 0x0, + .config = &gpu_cc_pll0_config, .vco_table = huayra_vco, .num_vco = ARRAY_SIZE(huayra_vco), .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_2290], @@ -132,6 +133,17 @@ static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = { { } }; +static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src_shikra[] = { + F(355200000, P_GPU_CC_PLL0_OUT_AUX, 2, 0, 0), + F(537600000, P_GPU_CC_PLL0_OUT_AUX, 2, 0, 0), + F(672000000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(844800000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(921600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(1017600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(1142400000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + { } +}; + static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = { .cmd_rcgr = 0x101c, .mnd_width = 0, @@ -143,21 +155,7 @@ static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = { .parent_data = gpu_cc_parent_data_1, .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, - }, -}; - -static struct clk_branch gpu_cc_ahb_clk = { - .halt_reg = 0x1078, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x1078, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gpu_cc_ahb_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, + .ops = &clk_rcg2_shared_ops, }, }; @@ -296,11 +294,14 @@ static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { static struct gdsc gpu_cx_gdsc = { .gdscr = 0x106c, .gds_hw_ctrl = 0x1540, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, .pd = { .name = "gpu_cx_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = VOTABLE, + .flags = RETAIN_FF_ENABLE | VOTABLE, }; static struct gdsc gpu_gx_gdsc = { @@ -308,16 +309,18 @@ static struct gdsc gpu_gx_gdsc = { .clamp_io_ctrl = 0x1508, .resets = (unsigned int []){ GPU_GX_BCR }, .reset_count = 1, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, .pd = { .name = "gpu_gx_gdsc", }, .parent = &gpu_cx_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, - .flags = CLAMP_IO | AON_RESET | SW_RESET, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR | CLAMP_IO | AON_RESET | SW_RESET, }; static struct clk_regmap *gpu_cc_qcm2290_clocks[] = { - [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, [GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr, [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, @@ -341,6 +344,15 @@ static struct gdsc *gpu_cc_qcm2290_gdscs[] = { [GPU_GX_GDSC] = &gpu_gx_gdsc, }; +static struct clk_alpha_pll *gpu_cc_qcm2290_plls[] = { + &gpu_cc_pll0, +}; + +static const u32 gpu_cc_qcm2290_critical_cbcrs[] = { + 0x1078, /* GPU_CC_AHB_CLK */ + 0x1060, /* GPU_CC_GX_CXO_CLK */ +}; + static const struct regmap_config gpu_cc_qcm2290_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -349,6 +361,12 @@ static const struct regmap_config gpu_cc_qcm2290_regmap_config = { .fast_io = true, }; +static const struct qcom_cc_driver_data gpu_cc_qcm2290_driver_data = { + .alpha_plls = gpu_cc_qcm2290_plls, + .num_alpha_plls = ARRAY_SIZE(gpu_cc_qcm2290_plls), + .clk_cbcrs = gpu_cc_qcm2290_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_qcm2290_critical_cbcrs), +}; static const struct qcom_cc_desc gpu_cc_qcm2290_desc = { .config = &gpu_cc_qcm2290_regmap_config, @@ -358,55 +376,23 @@ static const struct qcom_cc_desc gpu_cc_qcm2290_desc = { .num_resets = ARRAY_SIZE(gpu_cc_qcm2290_resets), .gdscs = gpu_cc_qcm2290_gdscs, .num_gdscs = ARRAY_SIZE(gpu_cc_qcm2290_gdscs), + .use_rpm = true, + .driver_data = &gpu_cc_qcm2290_driver_data, }; static const struct of_device_id gpu_cc_qcm2290_match_table[] = { { .compatible = "qcom,qcm2290-gpucc" }, + { .compatible = "qcom,shikra-gpucc" }, { } }; MODULE_DEVICE_TABLE(of, gpu_cc_qcm2290_match_table); static int gpu_cc_qcm2290_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; + if (device_is_compatible(&pdev->dev, "qcom,shikra-gpucc")) + gpu_cc_gx_gfx3d_clk_src.freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src_shikra; - regmap = qcom_cc_map(pdev, &gpu_cc_qcm2290_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - ret = devm_pm_runtime_enable(&pdev->dev); - if (ret) - return ret; - - ret = devm_pm_clk_create(&pdev->dev); - if (ret) - return ret; - - ret = pm_clk_add(&pdev->dev, NULL); - if (ret < 0) { - dev_err(&pdev->dev, "failed to acquire ahb clock\n"); - return ret; - } - - ret = pm_runtime_resume_and_get(&pdev->dev); - if (ret) - return ret; - - clk_huayra_2290_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); - - regmap_update_bits(regmap, 0x1060, BIT(0), BIT(0)); /* GPU_CC_GX_CXO_CLK */ - - ret = qcom_cc_really_probe(&pdev->dev, &gpu_cc_qcm2290_desc, regmap); - if (ret) { - dev_err(&pdev->dev, "Failed to register display clock controller\n"); - goto out_pm_runtime_put; - } - -out_pm_runtime_put: - pm_runtime_put_sync(&pdev->dev); - - return 0; + return qcom_cc_probe(pdev, &gpu_cc_qcm2290_desc); } static struct platform_driver gpu_cc_qcm2290_driver = { diff --git a/drivers/clk/qcom/gxclkctl-kaanapali.c b/drivers/clk/qcom/gxclkctl-kaanapali.c index 10c1a8976c56..8b71dc66ebbd 100644 --- a/drivers/clk/qcom/gxclkctl-kaanapali.c +++ b/drivers/clk/qcom/gxclkctl-kaanapali.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -25,6 +26,7 @@ static struct gdsc gx_clkctl_gx_gdsc = { .pd = { .name = "gx_clkctl_gx_gdsc", .power_on = gdsc_gx_do_nothing_enable, + .power_off = gdsc_gx_disable, }, .pwrsts = PWRSTS_OFF_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, @@ -60,7 +62,15 @@ MODULE_DEVICE_TABLE(of, gx_clkctl_kaanapali_match_table); static int gx_clkctl_kaanapali_probe(struct platform_device *pdev) { - return qcom_cc_probe(pdev, &gx_clkctl_kaanapali_desc); + int ret; + + ret = qcom_cc_probe(pdev, &gx_clkctl_kaanapali_desc); + if (ret) + return ret; + + pm_runtime_disable(&pdev->dev); + + return ret; } static struct platform_driver gx_clkctl_kaanapali_driver = { diff --git a/drivers/clk/qcom/negcc-nord.c b/drivers/clk/qcom/negcc-nord.c index 355850a875ac..0db284edc4e4 100644 --- a/drivers/clk/qcom/negcc-nord.c +++ b/drivers/clk/qcom/negcc-nord.c @@ -16,7 +16,6 @@ #include "clk-rcg.h" #include "clk-regmap.h" #include "clk-regmap-divider.h" -#include "clk-regmap-mux.h" #include "clk-regmap-phy-mux.h" #include "common.h" #include "gdsc.h" @@ -41,8 +40,6 @@ enum { P_UFS_PHY_RX_SYMBOL_0_CLK, P_UFS_PHY_RX_SYMBOL_1_CLK, P_UFS_PHY_TX_SYMBOL_0_CLK, - P_USB3_PHY_SEC_WRAPPER_NE_GCC_USB31_PIPE_CLK, - P_USB3_PHY_WRAPPER_NE_GCC_USB31_PIPE_CLK, }; static struct clk_alpha_pll ne_gcc_gpll0 = { @@ -165,26 +162,6 @@ static const struct clk_parent_data ne_gcc_parent_data_5[] = { { .index = DT_BI_TCXO }, }; -static const struct parent_map ne_gcc_parent_map_6[] = { - { P_USB3_PHY_WRAPPER_NE_GCC_USB31_PIPE_CLK, 0 }, - { P_BI_TCXO, 2 }, -}; - -static const struct clk_parent_data ne_gcc_parent_data_6[] = { - { .index = DT_USB3_PHY_WRAPPER_NE_GCC_USB31_PIPE_CLK }, - { .index = DT_BI_TCXO }, -}; - -static const struct parent_map ne_gcc_parent_map_7[] = { - { P_USB3_PHY_SEC_WRAPPER_NE_GCC_USB31_PIPE_CLK, 0 }, - { P_BI_TCXO, 2 }, -}; - -static const struct clk_parent_data ne_gcc_parent_data_7[] = { - { .index = DT_USB3_PHY_SEC_WRAPPER_NE_GCC_USB31_PIPE_CLK }, - { .index = DT_BI_TCXO }, -}; - static struct clk_regmap_phy_mux ne_gcc_ufs_phy_rx_symbol_0_clk_src = { .reg = 0x33068, .clkr = { @@ -227,32 +204,30 @@ static struct clk_regmap_phy_mux ne_gcc_ufs_phy_tx_symbol_0_clk_src = { }, }; -static struct clk_regmap_mux ne_gcc_usb3_prim_phy_pipe_clk_src = { +static struct clk_regmap_phy_mux ne_gcc_usb3_prim_phy_pipe_clk_src = { .reg = 0x2a078, - .shift = 0, - .width = 2, - .parent_map = ne_gcc_parent_map_6, .clkr = { .hw.init = &(const struct clk_init_data) { .name = "ne_gcc_usb3_prim_phy_pipe_clk_src", - .parent_data = ne_gcc_parent_data_6, - .num_parents = ARRAY_SIZE(ne_gcc_parent_data_6), - .ops = &clk_regmap_mux_closest_ops, + .parent_data = &(const struct clk_parent_data){ + .index = DT_USB3_PHY_WRAPPER_NE_GCC_USB31_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, }, }, }; -static struct clk_regmap_mux ne_gcc_usb3_sec_phy_pipe_clk_src = { +static struct clk_regmap_phy_mux ne_gcc_usb3_sec_phy_pipe_clk_src = { .reg = 0x2c078, - .shift = 0, - .width = 2, - .parent_map = ne_gcc_parent_map_7, .clkr = { .hw.init = &(const struct clk_init_data) { .name = "ne_gcc_usb3_sec_phy_pipe_clk_src", - .parent_data = ne_gcc_parent_data_7, - .num_parents = ARRAY_SIZE(ne_gcc_parent_data_7), - .ops = &clk_regmap_mux_closest_ops, + .parent_data = &(const struct clk_parent_data){ + .index = DT_USB3_PHY_SEC_WRAPPER_NE_GCC_USB31_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, }, }, }; @@ -951,21 +926,6 @@ static struct clk_branch ne_gcc_gp2_clk = { }, }; -static struct clk_branch ne_gcc_gpu_2_cfg_clk = { - .halt_reg = 0x34004, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x34004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x34004, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "ne_gcc_gpu_2_cfg_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch ne_gcc_gpu_2_gpll0_clk_src = { .halt_check = BRANCH_HALT_DELAY, .clkr = { @@ -1641,7 +1601,7 @@ static struct clk_branch ne_gcc_usb3_prim_phy_com_aux_clk = { static struct clk_branch ne_gcc_usb3_prim_phy_pipe_clk = { .halt_reg = 0x2a074, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x2a074, .hwcg_bit = 1, .clkr = { @@ -1697,7 +1657,7 @@ static struct clk_branch ne_gcc_usb3_sec_phy_com_aux_clk = { static struct clk_branch ne_gcc_usb3_sec_phy_pipe_clk = { .halt_reg = 0x2c074, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x2c074, .hwcg_bit = 1, .clkr = { @@ -1816,7 +1776,6 @@ static struct clk_regmap *ne_gcc_nord_clocks[] = { [NE_GCC_GPLL0] = &ne_gcc_gpll0.clkr, [NE_GCC_GPLL0_OUT_EVEN] = &ne_gcc_gpll0_out_even.clkr, [NE_GCC_GPLL2] = &ne_gcc_gpll2.clkr, - [NE_GCC_GPU_2_CFG_CLK] = &ne_gcc_gpu_2_cfg_clk.clkr, [NE_GCC_GPU_2_GPLL0_CLK_SRC] = &ne_gcc_gpu_2_gpll0_clk_src.clkr, [NE_GCC_GPU_2_GPLL0_DIV_CLK_SRC] = &ne_gcc_gpu_2_gpll0_div_clk_src.clkr, [NE_GCC_GPU_2_HSCNOC_GFX_CLK] = &ne_gcc_gpu_2_hscnoc_gfx_clk.clkr, @@ -1945,10 +1904,16 @@ static void clk_nord_regs_configure(struct device *dev, struct regmap *regmap) qcom_branch_set_force_mem_core(regmap, ne_gcc_ufs_phy_axi_clk, true); } +static const u32 ne_gcc_nord_critical_cbcrs[] = { + 0x34004, /* NE_GCC_GPU_2_CFG_CLK */ +}; + static const struct qcom_cc_driver_data ne_gcc_nord_driver_data = { .dfs_rcgs = ne_gcc_nord_dfs_clocks, .num_dfs_rcgs = ARRAY_SIZE(ne_gcc_nord_dfs_clocks), .clk_regs_configure = clk_nord_regs_configure, + .clk_cbcrs = ne_gcc_nord_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(ne_gcc_nord_critical_cbcrs), }; static const struct qcom_cc_desc ne_gcc_nord_desc = { diff --git a/drivers/clk/qcom/tcsrcc-glymur.c b/drivers/clk/qcom/tcsrcc-glymur.c index b44fccb795c6..1791e23739ed 100644 --- a/drivers/clk/qcom/tcsrcc-glymur.c +++ b/drivers/clk/qcom/tcsrcc-glymur.c @@ -4,262 +4,98 @@ */ #include +#include #include +#include #include #include #include -#include "clk-alpha-pll.h" -#include "clk-branch.h" -#include "clk-pll.h" -#include "clk-rcg.h" -#include "clk-regmap.h" -#include "clk-regmap-divider.h" -#include "clk-regmap-mux.h" -#include "common.h" -#include "gdsc.h" -#include "reset.h" - -enum { - DT_BI_TCXO_PAD, +struct tcsrcc_glymur_data { + const struct qcom_clk_ref_desc * const *descs; + size_t num_descs; }; -static struct clk_branch tcsr_edp_clkref_en = { - .halt_reg = 0x60, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x60, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_edp_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, +static const char * const glymur_tcsr_tx0_rx5_regulators[] = { + "vdda-refgen3-0p9", + "vdda-refgen3-1p2", + "vdda-qrefrx5-0p9", + "vdda-qreftx0-0p9", + "vdda-qreftx0-1p2", }; -static struct clk_branch tcsr_pcie_1_clkref_en = { - .halt_reg = 0x48, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x48, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_pcie_1_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, +static const char * const glymur_tcsr_tx1_rpt0_rx0_regulators[] = { + "vdda-refgen4-0p9", + "vdda-refgen4-1p2", + "vdda-qreftx1-0p9", + "vdda-qrefrpt0-0p9", + "vdda-qrefrx0-0p9", }; -static struct clk_branch tcsr_pcie_2_clkref_en = { - .halt_reg = 0x4c, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x4c, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_pcie_2_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, +static const char * const glymur_tcsr_tx1_rpt01_rx1_regulators[] = { + "vdda-refgen4-0p9", + "vdda-refgen4-1p2", + "vdda-qreftx1-0p9", + "vdda-qrefrpt0-0p9", + "vdda-qrefrpt1-0p9", + "vdda-qrefrx1-0p9", }; -static struct clk_branch tcsr_pcie_3_clkref_en = { - .halt_reg = 0x54, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x54, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_pcie_3_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, +static const char * const glymur_tcsr_tx1_rpt012_rx2_regulators[] = { + "vdda-refgen4-0p9", + "vdda-refgen4-1p2", + "vdda-qreftx1-0p9", + "vdda-qrefrpt0-0p9", + "vdda-qrefrpt1-0p9", + "vdda-qrefrpt2-0p9", + "vdda-qrefrx2-0p9", }; -static struct clk_branch tcsr_pcie_4_clkref_en = { - .halt_reg = 0x58, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x58, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_pcie_4_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, +static const char * const glymur_tcsr_tx1_rpt34_rx4_regulators[] = { + "vdda-refgen4-0p9", + "vdda-refgen4-1p2", + "vdda-qreftx1-0p9", + "vdda-qrefrpt3-0p9", + "vdda-qrefrpt4-0p9", + "vdda-qrefrx4-0p9", }; -static struct clk_branch tcsr_usb2_1_clkref_en = { - .halt_reg = 0x6c, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x6c, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_usb2_1_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, +static const char * const mahua_tcsr_tx1_rpt01_rx1_regulators[] = { + "vdda-refgen3-0p9", + "vdda-refgen3-1p2", + "vdda-qreftx1-0p9", + "vdda-qrefrpt0-0p9", + "vdda-qrefrpt1-0p9", + "vdda-qrefrx1-0p9", }; -static struct clk_branch tcsr_usb2_2_clkref_en = { - .halt_reg = 0x70, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x70, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_usb2_2_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, +static const char * const mahua_tcsr_tx1_rpt012_rx2_regulators[] = { + "vdda-refgen3-0p9", + "vdda-refgen3-1p2", + "vdda-qreftx1-0p9", + "vdda-qrefrpt0-0p9", + "vdda-qrefrpt1-0p9", + "vdda-qrefrpt2-0p9", + "vdda-qrefrx2-0p9", }; -static struct clk_branch tcsr_usb2_3_clkref_en = { - .halt_reg = 0x74, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x74, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_usb2_3_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, +static const char * const mahua_tcsr_tx1_rpt0_rx0_regulators[] = { + "vdda-refgen3-0p9", + "vdda-refgen3-1p2", + "vdda-qreftx1-0p9", + "vdda-qrefrpt0-0p9", + "vdda-qrefrx0-0p9", }; -static struct clk_branch tcsr_usb2_4_clkref_en = { - .halt_reg = 0x88, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x88, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_usb2_4_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch tcsr_usb3_0_clkref_en = { - .halt_reg = 0x64, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x64, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_usb3_0_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch tcsr_usb3_1_clkref_en = { - .halt_reg = 0x68, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x68, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_usb3_1_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch tcsr_usb4_1_clkref_en = { - .halt_reg = 0x44, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x44, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_usb4_1_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch tcsr_usb4_2_clkref_en = { - .halt_reg = 0x5c, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x5c, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "tcsr_usb4_2_clkref_en", - .parent_data = &(const struct clk_parent_data){ - .index = DT_BI_TCXO_PAD, - }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_regmap *tcsr_cc_glymur_clocks[] = { - [TCSR_EDP_CLKREF_EN] = &tcsr_edp_clkref_en.clkr, - [TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr, - [TCSR_PCIE_2_CLKREF_EN] = &tcsr_pcie_2_clkref_en.clkr, - [TCSR_PCIE_3_CLKREF_EN] = &tcsr_pcie_3_clkref_en.clkr, - [TCSR_PCIE_4_CLKREF_EN] = &tcsr_pcie_4_clkref_en.clkr, - [TCSR_USB2_1_CLKREF_EN] = &tcsr_usb2_1_clkref_en.clkr, - [TCSR_USB2_2_CLKREF_EN] = &tcsr_usb2_2_clkref_en.clkr, - [TCSR_USB2_3_CLKREF_EN] = &tcsr_usb2_3_clkref_en.clkr, - [TCSR_USB2_4_CLKREF_EN] = &tcsr_usb2_4_clkref_en.clkr, - [TCSR_USB3_0_CLKREF_EN] = &tcsr_usb3_0_clkref_en.clkr, - [TCSR_USB3_1_CLKREF_EN] = &tcsr_usb3_1_clkref_en.clkr, - [TCSR_USB4_1_CLKREF_EN] = &tcsr_usb4_1_clkref_en.clkr, - [TCSR_USB4_2_CLKREF_EN] = &tcsr_usb4_2_clkref_en.clkr, +static const char * const mahua_tcsr_tx1_rpt345_rx3_regulators[] = { + "vdda-refgen3-0p9", + "vdda-refgen3-1p2", + "vdda-qreftx1-0p9", + "vdda-qrefrpt3-0p9", + "vdda-qrefrpt4-0p9", + "vdda-qrefrpt5-0p9", + "vdda-qrefrx3-0p9", }; static const struct regmap_config tcsr_cc_glymur_regmap_config = { @@ -270,21 +106,186 @@ static const struct regmap_config tcsr_cc_glymur_regmap_config = { .fast_io = true, }; -static const struct qcom_cc_desc tcsr_cc_glymur_desc = { - .config = &tcsr_cc_glymur_regmap_config, - .clks = tcsr_cc_glymur_clocks, - .num_clks = ARRAY_SIZE(tcsr_cc_glymur_clocks), +static const struct qcom_clk_ref_desc * const tcsr_cc_glymur_clk_descs[] = { + [TCSR_EDP_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_edp_clkref_en", + .offset = 0x60, + .regulator_names = glymur_tcsr_tx1_rpt0_rx0_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt0_rx0_regulators), + }, + [TCSR_PCIE_1_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_pcie_1_clkref_en", + .offset = 0x48, + .regulator_names = glymur_tcsr_tx0_rx5_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx0_rx5_regulators), + }, + [TCSR_PCIE_2_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_pcie_2_clkref_en", + .offset = 0x4c, + .regulator_names = glymur_tcsr_tx1_rpt012_rx2_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt012_rx2_regulators), + }, + [TCSR_PCIE_3_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_pcie_3_clkref_en", + .offset = 0x54, + .regulator_names = glymur_tcsr_tx1_rpt01_rx1_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt01_rx1_regulators), + }, + [TCSR_PCIE_4_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_pcie_4_clkref_en", + .offset = 0x58, + .regulator_names = glymur_tcsr_tx1_rpt012_rx2_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt012_rx2_regulators), + }, + [TCSR_USB2_1_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb2_1_clkref_en", + .offset = 0x6c, + .regulator_names = glymur_tcsr_tx1_rpt34_rx4_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt34_rx4_regulators), + }, + [TCSR_USB2_2_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb2_2_clkref_en", + .offset = 0x70, + .regulator_names = glymur_tcsr_tx1_rpt01_rx1_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt01_rx1_regulators), + }, + [TCSR_USB2_3_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb2_3_clkref_en", + .offset = 0x74, + .regulator_names = glymur_tcsr_tx1_rpt34_rx4_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt34_rx4_regulators), + }, + [TCSR_USB2_4_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb2_4_clkref_en", + .offset = 0x88, + .regulator_names = glymur_tcsr_tx1_rpt34_rx4_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt34_rx4_regulators), + }, + [TCSR_USB3_0_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb3_0_clkref_en", + .offset = 0x64, + .regulator_names = glymur_tcsr_tx1_rpt34_rx4_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt34_rx4_regulators), + }, + [TCSR_USB3_1_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb3_1_clkref_en", + .offset = 0x68, + .regulator_names = glymur_tcsr_tx1_rpt34_rx4_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt34_rx4_regulators), + }, + [TCSR_USB4_1_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb4_1_clkref_en", + .offset = 0x44, + .regulator_names = glymur_tcsr_tx0_rx5_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx0_rx5_regulators), + }, + [TCSR_USB4_2_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb4_2_clkref_en", + .offset = 0x5c, + .regulator_names = glymur_tcsr_tx1_rpt01_rx1_regulators, + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt01_rx1_regulators), + }, +}; + +static const struct qcom_clk_ref_desc * const tcsr_cc_mahua_clk_descs[] = { + [TCSR_EDP_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_edp_clkref_en", + .offset = 0x60, + .regulator_names = mahua_tcsr_tx1_rpt0_rx0_regulators, + .num_regulators = ARRAY_SIZE(mahua_tcsr_tx1_rpt0_rx0_regulators), + }, + [TCSR_PCIE_2_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_pcie_2_clkref_en", + .offset = 0x4c, + .regulator_names = mahua_tcsr_tx1_rpt01_rx1_regulators, + .num_regulators = ARRAY_SIZE(mahua_tcsr_tx1_rpt01_rx1_regulators), + }, + [TCSR_PCIE_3_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_pcie_3_clkref_en", + .offset = 0x54, + .regulator_names = mahua_tcsr_tx1_rpt012_rx2_regulators, + .num_regulators = ARRAY_SIZE(mahua_tcsr_tx1_rpt012_rx2_regulators), + }, + [TCSR_PCIE_4_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_pcie_4_clkref_en", + .offset = 0x58, + .regulator_names = mahua_tcsr_tx1_rpt012_rx2_regulators, + .num_regulators = ARRAY_SIZE(mahua_tcsr_tx1_rpt012_rx2_regulators), + }, + [TCSR_USB2_1_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb2_1_clkref_en", + .offset = 0x6c, + .regulator_names = mahua_tcsr_tx1_rpt345_rx3_regulators, + .num_regulators = ARRAY_SIZE(mahua_tcsr_tx1_rpt345_rx3_regulators), + }, + [TCSR_USB2_2_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb2_2_clkref_en", + .offset = 0x70, + .regulator_names = mahua_tcsr_tx1_rpt345_rx3_regulators, + .num_regulators = ARRAY_SIZE(mahua_tcsr_tx1_rpt345_rx3_regulators), + }, + [TCSR_USB2_3_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb2_3_clkref_en", + .offset = 0x74, + .regulator_names = mahua_tcsr_tx1_rpt345_rx3_regulators, + .num_regulators = ARRAY_SIZE(mahua_tcsr_tx1_rpt345_rx3_regulators), + }, + [TCSR_USB2_4_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb2_4_clkref_en", + .offset = 0x88, + .regulator_names = mahua_tcsr_tx1_rpt0_rx0_regulators, + .num_regulators = ARRAY_SIZE(mahua_tcsr_tx1_rpt0_rx0_regulators), + }, + [TCSR_USB3_0_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb3_0_clkref_en", + .offset = 0x64, + .regulator_names = mahua_tcsr_tx1_rpt345_rx3_regulators, + .num_regulators = ARRAY_SIZE(mahua_tcsr_tx1_rpt345_rx3_regulators), + }, + [TCSR_USB3_1_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb3_1_clkref_en", + .offset = 0x68, + .regulator_names = mahua_tcsr_tx1_rpt345_rx3_regulators, + .num_regulators = ARRAY_SIZE(mahua_tcsr_tx1_rpt345_rx3_regulators), + }, + [TCSR_USB4_1_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb4_1_clkref_en", + .offset = 0x44, + }, + [TCSR_USB4_2_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb4_2_clkref_en", + .offset = 0x5c, + .regulator_names = mahua_tcsr_tx1_rpt01_rx1_regulators, + .num_regulators = ARRAY_SIZE(mahua_tcsr_tx1_rpt01_rx1_regulators), + }, +}; + +static const struct tcsrcc_glymur_data tcsr_cc_glymur_data = { + .descs = tcsr_cc_glymur_clk_descs, + .num_descs = ARRAY_SIZE(tcsr_cc_glymur_clk_descs), +}; + +static const struct tcsrcc_glymur_data tcsr_cc_mahua_data = { + .descs = tcsr_cc_mahua_clk_descs, + .num_descs = ARRAY_SIZE(tcsr_cc_mahua_clk_descs), }; static const struct of_device_id tcsr_cc_glymur_match_table[] = { - { .compatible = "qcom,glymur-tcsr" }, + { .compatible = "qcom,glymur-tcsr", .data = &tcsr_cc_glymur_data }, + { .compatible = "qcom,mahua-tcsr", .data = &tcsr_cc_mahua_data }, { } }; MODULE_DEVICE_TABLE(of, tcsr_cc_glymur_match_table); static int tcsr_cc_glymur_probe(struct platform_device *pdev) { - return qcom_cc_probe(pdev, &tcsr_cc_glymur_desc); + const struct tcsrcc_glymur_data *data = device_get_match_data(&pdev->dev); + + if (!data) + return -ENODEV; + + return qcom_clk_ref_probe(pdev, &tcsr_cc_glymur_regmap_config, + data->descs, data->num_descs); } static struct platform_driver tcsr_cc_glymur_driver = { diff --git a/drivers/clk/qcom/videocc-hawi.c b/drivers/clk/qcom/videocc-hawi.c new file mode 100644 index 000000000000..318270105dfe --- /dev/null +++ b/drivers/clk/qcom/videocc-hawi.c @@ -0,0 +1,839 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_AHB_CLK, +}; + +enum { + P_BI_TCXO, + P_VIDEO_CC_PLL0_OUT_EVEN, + P_VIDEO_CC_PLL0_OUT_MAIN, + P_VIDEO_CC_PLL1_OUT_MAIN, + P_VIDEO_CC_PLL2_OUT_MAIN, + P_VIDEO_CC_PLL3_OUT_MAIN, +}; + +static const struct pll_vco taycan_eha_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 360.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll0_config = { + .l = 0x12, + .cal_l = 0x48, + .alpha = 0xc000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll0 = { + .offset = 0x0, + .config = &video_cc_pll0_config, + .vco_table = taycan_eha_t_vco, + .num_vco = ARRAY_SIZE(taycan_eha_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eha_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_video_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv video_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_video_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_video_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eha_t_ops, + }, +}; + +/* 300.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll1_config = { + .l = 0xf, + .cal_l = 0x48, + .alpha = 0xa000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll1 = { + .offset = 0x1000, + .config = &video_cc_pll1_config, + .vco_table = taycan_eha_t_vco, + .num_vco = ARRAY_SIZE(taycan_eha_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eha_t_ops, + }, + }, +}; + +/* 300.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll2_config = { + .l = 0xf, + .cal_l = 0x48, + .alpha = 0xa000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll2 = { + .offset = 0x2000, + .config = &video_cc_pll2_config, + .vco_table = taycan_eha_t_vco, + .num_vco = ARRAY_SIZE(taycan_eha_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eha_t_ops, + }, + }, +}; + +/* 300.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll3_config = { + .l = 0xf, + .cal_l = 0x48, + .alpha = 0xa000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll3 = { + .offset = 0x3000, + .config = &video_cc_pll3_config, + .vco_table = taycan_eha_t_vco, + .num_vco = ARRAY_SIZE(taycan_eha_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eha_t_ops, + }, + }, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map video_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL1_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll1.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL3_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll3.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL2_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll2.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, + { P_VIDEO_CC_PLL0_OUT_EVEN, 2 }, +}; + +static const struct clk_parent_data video_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll0.clkr.hw }, + { .hw = &video_cc_pll0_out_even.clkr.hw }, +}; + +static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_ahb_clk_src = { + .cmd_rcgr = 0x8060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_ahb_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { + F(150000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(240000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(285000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(311000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(714000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0_clk_src = { + .cmd_rcgr = 0x8030, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_1, + .freq_tbl = ftbl_video_cc_mvs0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk_src", + .parent_data = video_cc_parent_data_1, + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0a_clk_src[] = { + F(150000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(240000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(710000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0a_clk_src = { + .cmd_rcgr = 0x8000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_2, + .freq_tbl = ftbl_video_cc_mvs0a_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0a_clk_src", + .parent_data = video_cc_parent_data_2, + .num_parents = ARRAY_SIZE(video_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0b_clk_src[] = { + F(150000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(240000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(311000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(667000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0b_clk_src = { + .cmd_rcgr = 0x8018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_3, + .freq_tbl = ftbl_video_cc_mvs0b_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_clk_src", + .parent_data = video_cc_parent_data_3, + .num_parents = ARRAY_SIZE(video_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0c_clk_src[] = { + F(225000000, P_VIDEO_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(360000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(430000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(557000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(634000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(782000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(928000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1060000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0c_clk_src = { + .cmd_rcgr = 0x8048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_4, + .freq_tbl = ftbl_video_cc_mvs0c_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk_src", + .parent_data = video_cc_parent_data_4, + .num_parents = ARRAY_SIZE(video_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 video_cc_xo_clk_src = { + .cmd_rcgr = 0x8180, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_xo_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch video_cc_cx_axi0_clk = { + .halt_reg = 0x81e8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x81e8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x81e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_cx_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_clk = { + .halt_reg = 0x80cc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80cc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_shift_clk = { + .halt_reg = 0x81a4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x81a4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x81a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp0_clk = { + .halt_reg = 0x811c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x811c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x811c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp0_vpp1_gating_clk = { + .halt_reg = 0x80c8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80c8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp0_vpp1_gating_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp1_clk = { + .halt_reg = 0x80f4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80f4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0a_clk = { + .halt_reg = 0x8090, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0a_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0a_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0b_clk = { + .halt_reg = 0x80b8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80b8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0b_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_clk = { + .halt_reg = 0x814c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x814c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x814c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_ctl_freerun_clk = { + .halt_reg = 0x8160, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8160, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_ctl_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_debug_clk = { + .halt_reg = 0x8148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8148, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_debug_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_freerun_clk = { + .halt_reg = 0x815c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x815c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_shift_clk = { + .halt_reg = 0x81a8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x81a8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x81a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc video_cc_mvs0c_gdsc = { + .gdscr = 0x8130, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0c_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_axi0_cx_int_gdsc = { + .gdscr = 0x81cc, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_axi0_cx_int_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_mvs0c_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mm_int_gdsc = { + .gdscr = 0x81b4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "video_cc_mm_int_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_axi0_cx_int_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_gdsc = { + .gdscr = 0x80a4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_mm_int_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_vpp0_gdsc = { + .gdscr = 0x8108, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0_vpp0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_mvs0_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_vpp1_gdsc = { + .gdscr = 0x80e0, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0_vpp1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_mvs0_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0a_gdsc = { + .gdscr = 0x807c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0a_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_mm_int_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *video_cc_hawi_clocks[] = { + [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, + [VIDEO_CC_CX_AXI0_CLK] = &video_cc_cx_axi0_clk.clkr, + [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, + [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, + [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, + [VIDEO_CC_MVS0_VPP0_CLK] = &video_cc_mvs0_vpp0_clk.clkr, + [VIDEO_CC_MVS0_VPP0_VPP1_GATING_CLK] = &video_cc_mvs0_vpp0_vpp1_gating_clk.clkr, + [VIDEO_CC_MVS0_VPP1_CLK] = &video_cc_mvs0_vpp1_clk.clkr, + [VIDEO_CC_MVS0A_CLK] = &video_cc_mvs0a_clk.clkr, + [VIDEO_CC_MVS0A_CLK_SRC] = &video_cc_mvs0a_clk_src.clkr, + [VIDEO_CC_MVS0B_CLK] = &video_cc_mvs0b_clk.clkr, + [VIDEO_CC_MVS0B_CLK_SRC] = &video_cc_mvs0b_clk_src.clkr, + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, + [VIDEO_CC_MVS0C_CLK_SRC] = &video_cc_mvs0c_clk_src.clkr, + [VIDEO_CC_MVS0C_CTL_FREERUN_CLK] = &video_cc_mvs0c_ctl_freerun_clk.clkr, + [VIDEO_CC_MVS0C_DEBUG_CLK] = &video_cc_mvs0c_debug_clk.clkr, + [VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr, + [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr, + [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, + [VIDEO_CC_PLL0_OUT_EVEN] = &video_cc_pll0_out_even.clkr, + [VIDEO_CC_PLL1] = &video_cc_pll1.clkr, + [VIDEO_CC_PLL2] = &video_cc_pll2.clkr, + [VIDEO_CC_PLL3] = &video_cc_pll3.clkr, + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, +}; + +static struct gdsc *video_cc_hawi_gdscs[] = { + [VIDEO_CC_AXI0_CX_INT_GDSC] = &video_cc_axi0_cx_int_gdsc, + [VIDEO_CC_MM_INT_GDSC] = &video_cc_mm_int_gdsc, + [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, + [VIDEO_CC_MVS0_VPP0_GDSC] = &video_cc_mvs0_vpp0_gdsc, + [VIDEO_CC_MVS0_VPP1_GDSC] = &video_cc_mvs0_vpp1_gdsc, + [VIDEO_CC_MVS0A_GDSC] = &video_cc_mvs0a_gdsc, + [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, +}; + +static const struct qcom_reset_map video_cc_hawi_resets[] = { + [VIDEO_CC_AXI0_CX_INT_BCR] = { 0x81c8 }, + [VIDEO_CC_INTERFACE_BCR] = { 0x8164 }, + [VIDEO_CC_MM_INT_BCR] = { 0x81b0 }, + [VIDEO_CC_MVS0_BCR] = { 0x80a0 }, + [VIDEO_CC_MVS0_VPP0_BCR] = { 0x8104 }, + [VIDEO_CC_MVS0_VPP1_BCR] = { 0x80dc }, + [VIDEO_CC_MVS0A_BCR] = { 0x8078 }, + [VIDEO_CC_MVS0C_CLK_ARES] = { 0x814c, 2 }, + [VIDEO_CC_MVS0C_BCR] = { 0x812c }, + [VIDEO_CC_MVS0C_CTL_FREERUN_CLK_ARES] = { 0x8160, 2 }, + [VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x815c, 2 }, + [VIDEO_CC_XO_CLK_ARES] = { 0x8198, 2 }, +}; + +static struct clk_alpha_pll *video_cc_hawi_plls[] = { + &video_cc_pll0, + &video_cc_pll1, + &video_cc_pll2, + &video_cc_pll3, +}; + +static const u32 video_cc_hawi_critical_cbcrs[] = { + 0x8168, /* VIDEO_CC_AHB_CLK */ + 0x81e4, /* VIDEO_CC_CX_DBGCH_XO_CLK */ + 0x81e0, /* VIDEO_CC_CX_XO_CLK */ + 0x81a0, /* VIDEO_CC_DBGCH_XO_CLK */ + 0x81ac, /* VIDEO_CC_SLEEP_CLK */ + 0x819c, /* VIDEO_CC_TS_XO_CLK */ + 0x8198, /* VIDEO_CC_XO_CLK */ +}; + +static const struct regmap_config video_cc_hawi_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xa018, + .fast_io = true, +}; + +static struct qcom_cc_driver_data video_cc_hawi_driver_data = { + .alpha_plls = video_cc_hawi_plls, + .num_alpha_plls = ARRAY_SIZE(video_cc_hawi_plls), + .clk_cbcrs = video_cc_hawi_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_hawi_critical_cbcrs), +}; + +static const struct qcom_cc_desc video_cc_hawi_desc = { + .config = &video_cc_hawi_regmap_config, + .clks = video_cc_hawi_clocks, + .num_clks = ARRAY_SIZE(video_cc_hawi_clocks), + .resets = video_cc_hawi_resets, + .num_resets = ARRAY_SIZE(video_cc_hawi_resets), + .gdscs = video_cc_hawi_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_hawi_gdscs), + .use_rpm = true, + .driver_data = &video_cc_hawi_driver_data, +}; + +static const struct of_device_id video_cc_hawi_match_table[] = { + { .compatible = "qcom,hawi-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_hawi_match_table); + +static int video_cc_hawi_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &video_cc_hawi_desc); +} + +static struct platform_driver video_cc_hawi_driver = { + .probe = video_cc_hawi_probe, + .driver = { + .name = "videocc-hawi", + .of_match_table = video_cc_hawi_match_table, + }, +}; + +module_platform_driver(video_cc_hawi_driver); + +MODULE_DESCRIPTION("QTI VIDEOCC Hawi Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/videocc-maili.c b/drivers/clk/qcom/videocc-maili.c new file mode 100644 index 000000000000..a7044009f078 --- /dev/null +++ b/drivers/clk/qcom/videocc-maili.c @@ -0,0 +1,660 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +#define ACCU_CFG_MASK GENMASK(25, 21) + +enum { + DT_BI_TCXO, + DT_AHB_CLK, +}; + +enum { + P_BI_TCXO, + P_VIDEO_CC_PLL0_OUT_MAIN, + P_VIDEO_CC_PLL1_OUT_MAIN, + P_VIDEO_CC_PLL2_OUT_MAIN, +}; + +static const struct pll_vco taycan_eha_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 360.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll0_config = { + .l = 0x12, + .cal_l = 0x42, + .alpha = 0xc000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a806160, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll0 = { + .offset = 0x0, + .config = &video_cc_pll0_config, + .vco_table = taycan_eha_t_vco, + .num_vco = ARRAY_SIZE(taycan_eha_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eha_t_ops, + }, + }, +}; + +/* 480.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll1_config = { + .l = 0x19, + .cal_l = 0x42, + .alpha = 0x0, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a806160, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll1 = { + .offset = 0x1000, + .config = &video_cc_pll1_config, + .vco_table = taycan_eha_t_vco, + .num_vco = ARRAY_SIZE(taycan_eha_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eha_t_ops, + }, + }, +}; + +/* 480.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll2_config = { + .l = 0x19, + .cal_l = 0x42, + .alpha = 0x0, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a806160, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll2 = { + .offset = 0x2000, + .config = &video_cc_pll2_config, + .vco_table = taycan_eha_t_vco, + .num_vco = ARRAY_SIZE(taycan_eha_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eha_t_ops, + }, + }, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map video_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL1_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll1.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL2_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll2.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll0.clkr.hw }, +}; + +static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_ahb_clk_src = { + .cmd_rcgr = 0x8060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_ahb_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { + F(240000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(600000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(800000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(1000000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0_clk_src = { + .cmd_rcgr = 0x8030, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_1, + .freq_tbl = ftbl_video_cc_mvs0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk_src", + .parent_data = video_cc_parent_data_1, + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0b_clk_src[] = { + F(240000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(800000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0b_clk_src = { + .cmd_rcgr = 0x8018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_2, + .freq_tbl = ftbl_video_cc_mvs0b_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_clk_src", + .parent_data = video_cc_parent_data_2, + .num_parents = ARRAY_SIZE(video_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0c_clk_src[] = { + F(360000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(507000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(630000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(666000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(800000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1104000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1260000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0c_clk_src = { + .cmd_rcgr = 0x8048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_3, + .freq_tbl = ftbl_video_cc_mvs0c_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk_src", + .parent_data = video_cc_parent_data_3, + .num_parents = ARRAY_SIZE(video_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 video_cc_xo_clk_src = { + .cmd_rcgr = 0x8194, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_xo_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch video_cc_mvs0_clk = { + .halt_reg = 0x80d0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80d0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_mem_branch video_cc_mvs0_freerun_clk = { + .mem_enable_reg = 0x80e4, + .mem_ack_reg = 0x80e4, + .mem_enable_mask = BIT(3), + .mem_enable_ack_mask = GENMASK(11, 10), + .mem_enable_invert = true, + .branch = { + .halt_reg = 0x80e0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_mem_ops, + }, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_shift_clk = { + .halt_reg = 0x81b4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x81b4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x81b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp0_clk = { + .halt_reg = 0x8134, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8134, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp0_freerun_clk = { + .halt_reg = 0x8144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp0_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0b_clk = { + .halt_reg = 0x80bc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80bc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0b_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0b_freerun_clk = { + .halt_reg = 0x80cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0b_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_clk = { + .halt_reg = 0x8164, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8164, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8164, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_debug_clk = { + .halt_reg = 0x81c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x81c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_debug_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_freerun_clk = { + .halt_reg = 0x8174, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8174, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_shift_clk = { + .halt_reg = 0x81b8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x81b8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x81b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc video_cc_mvs0c_gdsc = { + .gdscr = 0x814c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0c_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_gdsc = { + .gdscr = 0x80a8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0_gdsc", + }, + .parent = &video_cc_mvs0c_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_vpp0_gdsc = { + .gdscr = 0x8120, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0_vpp0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *video_cc_maili_clocks[] = { + [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, + [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, + [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, + [VIDEO_CC_MVS0_FREERUN_CLK] = &video_cc_mvs0_freerun_clk.branch.clkr, + [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, + [VIDEO_CC_MVS0_VPP0_CLK] = &video_cc_mvs0_vpp0_clk.clkr, + [VIDEO_CC_MVS0_VPP0_FREERUN_CLK] = &video_cc_mvs0_vpp0_freerun_clk.clkr, + [VIDEO_CC_MVS0B_CLK] = &video_cc_mvs0b_clk.clkr, + [VIDEO_CC_MVS0B_CLK_SRC] = &video_cc_mvs0b_clk_src.clkr, + [VIDEO_CC_MVS0B_FREERUN_CLK] = &video_cc_mvs0b_freerun_clk.clkr, + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, + [VIDEO_CC_MVS0C_CLK_SRC] = &video_cc_mvs0c_clk_src.clkr, + [VIDEO_CC_MVS0C_DEBUG_CLK] = &video_cc_mvs0c_debug_clk.clkr, + [VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr, + [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr, + [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, + [VIDEO_CC_PLL1] = &video_cc_pll1.clkr, + [VIDEO_CC_PLL2] = &video_cc_pll2.clkr, + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, +}; + +static struct gdsc *video_cc_maili_gdscs[] = { + [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, + [VIDEO_CC_MVS0_VPP0_GDSC] = &video_cc_mvs0_vpp0_gdsc, + [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, +}; + +static const struct qcom_reset_map video_cc_maili_resets[] = { + [VIDEO_CC_INTERFACE_BCR] = { 0x8178 }, + [VIDEO_CC_MVS0_BCR] = { 0x80a4 }, + [VIDEO_CC_MVS0_CLK_ARES] = { 0x80d0, 2 }, + [VIDEO_CC_MVS0_FREERUN_CLK_ARES] = { 0x80e0, 2 }, + [VIDEO_CC_MVS0_VPP0_BCR] = { 0x811c }, + [VIDEO_CC_MVS0C_BCR] = { 0x8148 }, + [VIDEO_CC_MVS0C_CLK_ARES] = { 0x8164, 2 }, + [VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x8174, 2 }, + [VIDEO_CC_XO_CLK_ARES] = { 0x81ac, 2 }, +}; + +static struct clk_alpha_pll *video_cc_maili_plls[] = { + &video_cc_pll0, + &video_cc_pll1, + &video_cc_pll2, +}; + +static const u32 video_cc_maili_critical_cbcrs[] = { + 0x817c, /* VIDEO_CC_AHB_CLK */ + 0x81bc, /* VIDEO_CC_SLEEP_CLK */ + 0x81b0, /* VIDEO_CC_TS_XO_CLK */ + 0x81ac, /* VIDEO_CC_XO_CLK */ +}; + +static const struct regmap_config video_cc_maili_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xa010, + .fast_io = true, +}; + +static void clk_maili_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* + * Enable clk_on sync for MVS0 and VPP clocks as per the + * hardware recommendation. + */ + regmap_set_bits(regmap, 0x9f24, BIT(0)); + + /* + * Update ACCU configuration for MVS0 CFG3, MVS0 VPP0 CFG3, + * MVS0C CFG3 GDSCRs as per the hardware recommendation. + */ + regmap_set_bits(regmap, 0x80b4, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x812c, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x8158, ACCU_CFG_MASK); +} + +static const struct qcom_cc_driver_data video_cc_maili_driver_data = { + .alpha_plls = video_cc_maili_plls, + .num_alpha_plls = ARRAY_SIZE(video_cc_maili_plls), + .clk_cbcrs = video_cc_maili_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_maili_critical_cbcrs), + .clk_regs_configure = clk_maili_regs_configure, +}; + +static const struct qcom_cc_desc video_cc_maili_desc = { + .config = &video_cc_maili_regmap_config, + .clks = video_cc_maili_clocks, + .num_clks = ARRAY_SIZE(video_cc_maili_clocks), + .resets = video_cc_maili_resets, + .num_resets = ARRAY_SIZE(video_cc_maili_resets), + .gdscs = video_cc_maili_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_maili_gdscs), + .use_rpm = true, + .driver_data = &video_cc_maili_driver_data, +}; + +static const struct of_device_id video_cc_maili_match_table[] = { + { .compatible = "qcom,maili-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_maili_match_table); + +static int video_cc_maili_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &video_cc_maili_desc); +} + +static struct platform_driver video_cc_maili_driver = { + .probe = video_cc_maili_probe, + .driver = { + .name = "videocc-maili", + .of_match_table = video_cc_maili_match_table, + }, +}; + +module_platform_driver(video_cc_maili_driver); + +MODULE_DESCRIPTION("QTI VIDEOCC Maili Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/videocc-x1p42100.c b/drivers/clk/qcom/videocc-x1p42100.c index 503c03210ec8..6de596908cb7 100644 --- a/drivers/clk/qcom/videocc-x1p42100.c +++ b/drivers/clk/qcom/videocc-x1p42100.c @@ -526,7 +526,7 @@ static struct clk_alpha_pll *video_cc_x1p42100_plls[] = { &video_cc_pll1, }; -static u32 video_cc_x1p42100_critical_cbcrs[] = { +static const u32 video_cc_x1p42100_critical_cbcrs[] = { 0x80f4, /* VIDEO_CC_AHB_CLK */ 0x8150, /* VIDEO_CC_SLEEP_CLK */ 0x8124, /* VIDEO_CC_XO_CLK */ @@ -540,7 +540,7 @@ static const struct regmap_config video_cc_x1p42100_regmap_config = { .fast_io = true, }; -static struct qcom_cc_driver_data video_cc_x1p42100_driver_data = { +static const struct qcom_cc_driver_data video_cc_x1p42100_driver_data = { .alpha_plls = video_cc_x1p42100_plls, .num_alpha_plls = ARRAY_SIZE(video_cc_x1p42100_plls), .clk_cbcrs = video_cc_x1p42100_critical_cbcrs, diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 0203ecbb3882..17b95a2e96fb 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -34,6 +34,7 @@ config CLK_RENESAS select CLK_R8A779F0 if ARCH_R8A779F0 select CLK_R8A779G0 if ARCH_R8A779G0 select CLK_R8A779H0 if ARCH_R8A779H0 + select CLK_R8A78000 if ARCH_R8A78000 select CLK_R9A06G032 if ARCH_R9A06G032 select CLK_R9A07G043 if ARCH_R9A07G043 select CLK_R9A07G044 if ARCH_R9A07G044 @@ -176,6 +177,9 @@ config CLK_R8A779H0 bool "R-Car V4M clock support" if COMPILE_TEST select CLK_RCAR_GEN4_CPG +config CLK_R8A78000 + bool "R-Car X5H clock support" if COMPILE_TEST + config CLK_R9A06G032 bool "RZ/N1D clock support" if COMPILE_TEST @@ -218,10 +222,12 @@ config CLK_R9A09G057 config CLK_R9A09G077 bool "RZ/T2H clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSSR + select CLK_RZV2H_CPG_LIB config CLK_R9A09G087 bool "RZ/N2H clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSSR + select CLK_RZV2H_CPG_LIB config CLK_SH73A0 bool "SH-Mobile AG5 clock support" if COMPILE_TEST @@ -260,8 +266,12 @@ config CLK_RZG2L config CLK_RZV2H bool "RZ/{G3E,V2H(P)} family clock support" if COMPILE_TEST + select CLK_RZV2H_CPG_LIB select RESET_CONTROLLER +config CLK_RZV2H_CPG_LIB + bool "RZV2H CPG library functions" if COMPILE_TEST + config CLK_RENESAS_VBATTB tristate "Renesas VBATTB clock controller" depends on ARCH_RZG2L || COMPILE_TEST diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index bd2bed91ab29..658f8aac5127 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_CLK_R8A779A0) += r8a779a0-cpg-mssr.o obj-$(CONFIG_CLK_R8A779F0) += r8a779f0-cpg-mssr.o obj-$(CONFIG_CLK_R8A779G0) += r8a779g0-cpg-mssr.o obj-$(CONFIG_CLK_R8A779H0) += r8a779h0-cpg-mssr.o +obj-$(CONFIG_CLK_R8A78000) += r8a78000-cpg.o obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o obj-$(CONFIG_CLK_R9A07G043) += r9a07g043-cpg.o obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o @@ -52,6 +53,7 @@ obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o obj-$(CONFIG_CLK_RCAR_GEN4_CPG) += rcar-gen4-cpg.o obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o obj-$(CONFIG_CLK_RZG2L) += rzg2l-cpg.o +obj-$(CONFIG_CLK_RZV2H_CPG_LIB) += rzv2h-cpg-lib.o obj-$(CONFIG_CLK_RZV2H) += rzv2h-cpg.o # Generic diff --git a/drivers/clk/renesas/r8a78000-cpg.c b/drivers/clk/renesas/r8a78000-cpg.c new file mode 100644 index 000000000000..7946f9d0b423 --- /dev/null +++ b/drivers/clk/renesas/r8a78000-cpg.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R-Car X5H Clock Pulse Generator + * + * Copyright (C) 2026 Glider bv + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct clk_map { + int dt_id; /* DT binding clock ID or -1 sentinel */ + u32 fw_id; /* FIXED_CLK() ID */ +}; + +enum fixed_clk { + FIXED_CLK_66M, + FIXED_CLK_266M, + NUM_FIXED_CLKS +}; + +static const unsigned long fixed_clk_rates[NUM_FIXED_CLKS] = { + [FIXED_CLK_66M] = 66666000, + [FIXED_CLK_266M] = 266660000, +}; + +#define FIXED_CLK(rate) FIXED_CLK_ ## rate + +/** + * struct r8a78000_cpg_priv - Clock Pulse Generator Private Data + * + * @dev: CPG device + * @map: Mapping from DT clock IDs to fixed-rate clocks + * @fixed_hws: Fixed rate clocks + */ +struct r8a78000_cpg_priv { + struct device *dev; + const struct clk_map *map; + struct clk_hw *fixed_hws[NUM_FIXED_CLKS]; +}; + +static const struct clk_map *clk_map_find(const struct clk_map *map, u32 id) +{ + if (!map) + return NULL; + + for (; map->dt_id >= 0; map++) { + if (map->dt_id == id) + return map; + } + + return NULL; +} + +static struct clk_hw *r8a78000_clk_get(struct of_phandle_args *spec, + void *data) +{ + struct r8a78000_cpg_priv *priv = data; + struct device *dev = priv->dev; + const struct clk_map *map; + struct clk_hw *hw; + u32 id; + + if (spec->args_count != 1) + return ERR_PTR(-EINVAL); + + id = spec->args[0]; + + map = clk_map_find(priv->map, id); + if (!map) { + dev_err(dev, "Unknown clock %u\n", id); + return ERR_PTR(-ENOENT); + } + + dev_dbg(dev, "Mapping DT clock %u to fixed clock %u\n", id, map->fw_id); + + hw = priv->fixed_hws[map->fw_id]; + + dev_dbg(dev, "clock %u is %s at %lu Hz\n", id, clk_hw_get_name(hw), + clk_hw_get_rate(hw)); + + return hw; +} + +static int register_fixed_clks(struct r8a78000_cpg_priv *priv) +{ + struct device *dev = priv->dev; + unsigned long rate; + struct clk_hw *hw; + const char *name; + + for (unsigned int i = 0; i < ARRAY_SIZE(fixed_clk_rates); i++) { + rate = fixed_clk_rates[i]; + name = devm_kasprintf(dev, GFP_KERNEL, "cpg-%lu", rate); + if (!name) + return -ENOMEM; + + hw = devm_clk_hw_register_fixed_rate(dev, name, NULL, 0, rate); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + priv->fixed_hws[i] = hw; + } + + return 0; +} + +static int r8a78000_cpg_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct r8a78000_cpg_priv *priv; + const struct clk_map *map; + int ret; + + map = of_device_get_match_data(dev); + if (!map) + return -ENODEV; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->map = map; + + ret = register_fixed_clks(priv); + if (ret) + return ret; + + return devm_of_clk_add_hw_provider(dev, r8a78000_clk_get, priv); +} + +static const struct clk_map r8a78000_cpg_default[] = { + { R8A78000_CPG_SGASYNCD4_PERW_BUS, FIXED_CLK(266M) }, + { R8A78000_CPG_SGASYNCD16_PERW_BUS, FIXED_CLK(66M) }, + { -1 } +}; + +static const struct of_device_id r8a78000_cpg_match[] = { + { + .compatible = "renesas,r8a78000-cpg", + .data = &r8a78000_cpg_default, + }, + { /* sentinel */ } +}; + +static struct platform_driver r8a78000_cpg_driver = { + .probe = r8a78000_cpg_probe, + .driver = { + .name = "r8a78000-cpg", + .of_match_table = r8a78000_cpg_match, + .suppress_bind_attrs = true, + }, +}; + +builtin_platform_driver(r8a78000_cpg_driver) + +MODULE_DESCRIPTION("R-Car X5H CPG Driver"); diff --git a/drivers/clk/renesas/r9a08g045-cpg.c b/drivers/clk/renesas/r9a08g045-cpg.c index 624fc5e6fb24..ea2a6a71aebd 100644 --- a/drivers/clk/renesas/r9a08g045-cpg.c +++ b/drivers/clk/renesas/r9a08g045-cpg.c @@ -77,6 +77,7 @@ enum clk_ids { CLK_SEL_PLL4, CLK_P1_DIV2, CLK_P3_DIV2, + CLK_P4_DIV2, CLK_SD0_DIV4, CLK_SD1_DIV4, CLK_SD2_DIV4, @@ -172,6 +173,8 @@ static const struct cpg_core_clk r9a08g045_core_clks[] __initconst = { DEF_G3S_DIV("P3", R9A08G045_CLK_P3, CLK_PLL3_DIV2_4, DIVPL3C, G3S_DIVPL3C_STS, dtable_1_32, 0, 0, 0, NULL), DEF_FIXED("P3_DIV2", CLK_P3_DIV2, R9A08G045_CLK_P3, 1, 2), + DEF_FIXED("P4", R9A08G045_CLK_P4, CLK_PLL2_DIV2, 1, 5), + DEF_FIXED("P4_DIV2", CLK_P4_DIV2, R9A08G045_CLK_P4, 1, 2), DEF_FIXED("P5", R9A08G045_CLK_P5, CLK_PLL2_DIV2, 1, 4), DEF_FIXED("ZT", R9A08G045_CLK_ZT, CLK_PLL3_DIV2_8, 1, 1), DEF_FIXED("S0", R9A08G045_CLK_S0, CLK_SEL_PLL4, 1, 2), @@ -274,6 +277,10 @@ static const struct rzg2l_mod_clk r9a08g045_mod_clks[] = { MSTOP(BUS_MCPU2, BIT(5))), DEF_MOD("scif5_clk_pck", R9A08G045_SCIF5_CLK_PCK, R9A08G045_CLK_P0, 0x584, 5, MSTOP(BUS_MCPU3, BIT(4))), + DEF_MOD("canfd_pclk", R9A08G045_CANFD_PCLK, CLK_P4_DIV2, 0x594, 0, + MSTOP(BUS_MCPU2, BIT(9))), + DEF_MOD("canfd_clk_ram", R9A08G045_CANFD_CLK_RAM, R9A08G045_CLK_P4, 0x594, 1, + MSTOP(BUS_MCPU2, BIT(9))), DEF_MOD("gpio_hclk", R9A08G045_GPIO_HCLK, R9A08G045_OSCCLK, 0x598, 0, MSTOP(BUS_PERI_CPU, BIT(6))), DEF_MOD("adc_adclk", R9A08G045_ADC_ADCLK, R9A08G045_CLK_TSU, 0x5a8, 0, @@ -324,6 +331,8 @@ static const struct rzg2l_reset r9a08g045_resets[] = { DEF_RST(R9A08G045_SCIF3_RST_SYSTEM_N, 0x884, 3), DEF_RST(R9A08G045_SCIF4_RST_SYSTEM_N, 0x884, 4), DEF_RST(R9A08G045_SCIF5_RST_SYSTEM_N, 0x884, 5), + DEF_RST(R9A08G045_CANFD_RSTP_N, 0x894, 0), + DEF_RST(R9A08G045_CANFD_RSTC_N, 0x894, 1), DEF_RST(R9A08G045_GPIO_RSTN, 0x898, 0), DEF_RST(R9A08G045_GPIO_PORT_RESETN, 0x898, 1), DEF_RST(R9A08G045_GPIO_SPARE_RESETN, 0x898, 2), diff --git a/drivers/clk/renesas/r9a08g046-cpg.c b/drivers/clk/renesas/r9a08g046-cpg.c index a57638734ce7..4488bd1988e8 100644 --- a/drivers/clk/renesas/r9a08g046-cpg.c +++ b/drivers/clk/renesas/r9a08g046-cpg.c @@ -17,10 +17,15 @@ /* RZ/G3L Specific registers. */ #define G3L_CPG_PL2_DDIV (0x204) #define G3L_CPG_PL3_DDIV (0x208) +#define G3L_CPG_SDHI_DDIV (0x218) +#define G3L_CPG_GE3D_DDIV (0x224) #define G3L_CPG_CA55CORE_DDIV (0x234) #define G3L_CPG_RSCI_DDIV (0x238) #define G3L_CPG_RSPI_DDIV (0x23c) +#define G3L_CPG_SDHI_DSEL (0x244) #define G3L_CLKDIVSTATUS (0x280) +#define G3L_CLKSELSTATUS (0x284) +#define G3L_CPG_GE3D_SSEL (0x40c) #define G3L_CPG_ETH_SSEL (0x410) #define G3L_CPG_RSCI_SSEL (0x414) #define G3L_CPG_RSPI_SSEL (0x418) @@ -30,6 +35,10 @@ #define G3L_DIVPL2A DDIV_PACK(G3L_CPG_PL2_DDIV, 0, 2) #define G3L_DIVPL2B DDIV_PACK(G3L_CPG_PL2_DDIV, 4, 2) #define G3L_DIVPL3A DDIV_PACK(G3L_CPG_PL3_DDIV, 0, 2) +#define G3L_DIV_SDHI0 DDIV_PACK(G3L_CPG_SDHI_DDIV, 0, 2) +#define G3L_DIV_SDHI1 DDIV_PACK(G3L_CPG_SDHI_DDIV, 4, 2) +#define G3L_DIV_SDHI2 DDIV_PACK(G3L_CPG_SDHI_DDIV, 8, 2) +#define G3L_DIV_GE3D DDIV_PACK(G3L_CPG_GE3D_DDIV, 0, 3) #define G3L_DIV_CA55_CORE0 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 0, 3) #define G3L_DIV_CA55_CORE1 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 4, 3) #define G3L_DIV_CA55_CORE2 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 8, 3) @@ -61,8 +70,19 @@ #define G3L_DIV_RSPI0_STS DDIV_PACK(G3L_CLKDIVSTATUS, 20, 1) #define G3L_DIV_RSPI1_STS DDIV_PACK(G3L_CLKDIVSTATUS, 21, 1) #define G3L_DIV_RSPI2_STS DDIV_PACK(G3L_CLKDIVSTATUS, 22, 1) +#define G3L_DIV_SDHI0_STS DDIV_PACK(G3L_CLKDIVSTATUS, 24, 1) +#define G3L_DIV_SDHI1_STS DDIV_PACK(G3L_CLKDIVSTATUS, 25, 1) +#define G3L_DIV_SDHI2_STS DDIV_PACK(G3L_CLKDIVSTATUS, 26, 1) + +#define G3L_SEL_SDHI0_STS SEL_PLL_PACK(G3L_CLKSELSTATUS, 16, 1) +#define G3L_SEL_SDHI1_STS SEL_PLL_PACK(G3L_CLKSELSTATUS, 17, 1) +#define G3L_SEL_SDHI2_STS SEL_PLL_PACK(G3L_CLKSELSTATUS, 18, 1) +#define G3L_DIV_GE3D_STS DDIV_PACK(G3L_CLKDIVSTATUS, 27, 1) /* RZ/G3L Specific clocks select. */ +#define G3L_SEL_SDHI0 SEL_PLL_PACK(G3L_CPG_SDHI_DSEL, 0, 2) +#define G3L_SEL_SDHI1 SEL_PLL_PACK(G3L_CPG_SDHI_DSEL, 4, 2) +#define G3L_SEL_SDHI2 SEL_PLL_PACK(G3L_CPG_SDHI_DSEL, 8, 2) #define G3L_SEL_ETH0_TX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 0, 1) #define G3L_SEL_ETH0_RX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 1, 1) #define G3L_SEL_ETH0_RM SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 2, 1) @@ -73,6 +93,7 @@ #define G3L_SEL_ETH1_RM SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 10, 1) #define G3L_SEL_ETH1_CLK_TX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 11, 1) #define G3L_SEL_ETH1_CLK_RX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 12, 1) +#define G3L_SEL_GE3D SEL_PLL_PACK(G3L_CPG_GE3D_SSEL, 0, 2) #define G3L_SEL_RSCI0 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 0, 2) #define G3L_SEL_RSCI1 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 2, 2) #define G3L_SEL_RSCI2 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 4, 2) @@ -94,6 +115,7 @@ enum clk_ids { /* Internal Core Clocks */ CLK_PLL1, + CLK_PLL1_DIV2, CLK_PLL2, CLK_PLL2_DIV2, CLK_PLL2_DIV2_4, @@ -102,6 +124,8 @@ enum clk_ids { CLK_PLL2_DIV7, CLK_PLL3, CLK_PLL3_DIV2, + CLK_PLL3_DIV2_2, + CLK_PLL3_DIV3, CLK_PLL6, CLK_PLL6_DIV10, CLK_SEL_ETH0_TX, @@ -110,6 +134,7 @@ enum clk_ids { CLK_SEL_ETH1_TX, CLK_SEL_ETH1_RX, CLK_SEL_ETH1_RM, + CLK_SEL_GE3D, CLK_SEL_RSCI0, CLK_SEL_RSCI1, CLK_SEL_RSCI2, @@ -117,16 +142,29 @@ enum clk_ids { CLK_SEL_RSPI0, CLK_SEL_RSPI1, CLK_SEL_RSPI2, + CLK_SEL_SDHI0, + CLK_SEL_SDHI1, + CLK_SEL_SDHI2, CLK_ETH0_TR, CLK_ETH0_RM, CLK_ETH1_TR, CLK_ETH1_RM, + CLK_SD0_DIV2, + CLK_SD1_DIV2, + CLK_SD2_DIV2, /* Module Clocks */ MOD_CLK_BASE, }; /* Divider tables */ +static const struct clk_div_table dtable_1_4[] = { + { 0, 1 }, + { 1, 2 }, + { 2, 4 }, + { 0, 0 }, +}; + static const struct clk_div_table dtable_1_8[] = { { 0, 1 }, { 1, 2 }, @@ -189,12 +227,17 @@ static const char * const sel_eth0_rm[] = { ".pll6_div10", "eth0_rxc_rx_clk" }; static const char * const sel_eth1_tx[] = { ".div_eth1_tr", "eth1_txc_tx_clk" }; static const char * const sel_eth1_rx[] = { ".div_eth1_tr", "eth1_rxc_rx_clk" }; static const char * const sel_eth1_rm[] = { ".pll6_div10", "eth1_rxc_rx_clk" }; +static const char * const sel_ge3d[] = { ".pll1_div2", ".pll3_div3", ".pll6", ".pll3_div2_2" }; static const char * const sel_rsci_rspi[] = { ".pll2_div5", ".pll2_div6", ".pll2_div7", ".pll2_div2_4" }; +static const char * const sel_sdhi[] = { ".pll2_div2", ".pll1_div2", ".pll6", ".pll2_div6" }; static const char * const sel_eth0_clk_tx_i[] = { ".sel_eth0_tx", ".div_eth0_rm" }; static const char * const sel_eth0_clk_rx_i[] = { ".sel_eth0_rx", ".div_eth0_rm" }; static const char * const sel_eth1_clk_tx_i[] = { ".sel_eth1_tx", ".div_eth1_rm" }; static const char * const sel_eth1_clk_rx_i[] = { ".sel_eth1_rx", ".div_eth1_rm" }; +/* Mux clock indices tables. */ +static const u32 mtable_sd[] = { 0, 1, 2, 3 }; + static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { /* External Clock Inputs */ DEF_INPUT("extal", CLK_EXTAL), @@ -210,13 +253,23 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 200, 3), DEF_G3L_PLL(".pll6", CLK_PLL6, CLK_EXTAL, CPG_PLL_CONF(0x50, 0), 500000000UL), + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 1, 2), DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2), DEF_FIXED(".pll2_div2_4", CLK_PLL2_DIV2_4, CLK_PLL2_DIV2, 1, 4), DEF_FIXED(".pll2_div5", CLK_PLL2_DIV5, CLK_PLL2, 1, 5), DEF_FIXED(".pll2_div6", CLK_PLL2_DIV6, CLK_PLL2, 1, 6), DEF_FIXED(".pll2_div7", CLK_PLL2_DIV7, CLK_PLL2, 1, 7), DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2), + DEF_FIXED(".pll3_div2_2", CLK_PLL3_DIV2_2, CLK_PLL3_DIV2, 1, 2), + DEF_FIXED(".pll3_div3", CLK_PLL3_DIV3, CLK_PLL3, 1, 3), DEF_FIXED(".pll6_div10", CLK_PLL6_DIV10, CLK_PLL6, 1, 10), + DEF_SD_MUX(".sel_sdhi0", CLK_SEL_SDHI0, G3L_SEL_SDHI0, G3L_SEL_SDHI0_STS, sel_sdhi, + mtable_sd, 0, NULL), + DEF_SD_MUX(".sel_sdhi1", CLK_SEL_SDHI1, G3L_SEL_SDHI1, G3L_SEL_SDHI1_STS, sel_sdhi, + mtable_sd, 0, NULL), + DEF_SD_MUX(".sel_sdhi2", CLK_SEL_SDHI2, G3L_SEL_SDHI2, G3L_SEL_SDHI2_STS, sel_sdhi, + mtable_sd, 0, NULL), + DEF_MUX(".sel_ge3d", CLK_SEL_GE3D, G3L_SEL_GE3D, sel_ge3d), DEF_MUX(".sel_rsci0", CLK_SEL_RSCI0, G3L_SEL_RSCI0, sel_rsci_rspi), DEF_MUX(".sel_rsci1", CLK_SEL_RSCI1, G3L_SEL_RSCI1, sel_rsci_rspi), DEF_MUX(".sel_rsci2", CLK_SEL_RSCI2, G3L_SEL_RSCI2, sel_rsci_rspi), @@ -264,6 +317,18 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { dtable_1_8, 0, 200000000UL, 0, NULL), DEF_G3S_DIV("P19", R9A08G046_CLK_P19, CLK_SEL_RSPI2, G3L_DIV_RSPI2, G3L_DIV_RSPI2_STS, dtable_1_8, 0, 200000000UL, 0, NULL), + DEF_G3S_DIV("SD0", R9A08G046_CLK_SD0, CLK_SEL_SDHI0, G3L_DIV_SDHI0, G3L_DIV_SDHI0_STS, + dtable_1_4, 800000000UL, 600000000UL, CLK_SET_RATE_PARENT, + rzg3s_cpg_div_clk_notifier), + DEF_G3S_DIV("SD1", R9A08G046_CLK_SD1, CLK_SEL_SDHI1, G3L_DIV_SDHI1, G3L_DIV_SDHI1_STS, + dtable_1_4, 800000000UL, 600000000UL, CLK_SET_RATE_PARENT, + rzg3s_cpg_div_clk_notifier), + DEF_G3S_DIV("SD2", R9A08G046_CLK_SD2, CLK_SEL_SDHI2, G3L_DIV_SDHI2, G3L_DIV_SDHI2_STS, + dtable_1_4, 800000000UL, 600000000UL, CLK_SET_RATE_PARENT, + rzg3s_cpg_div_clk_notifier), + DEF_FIXED(".sd0_div2", CLK_SD0_DIV2, R9A08G046_CLK_SD0, 1, 2), + DEF_FIXED(".sd1_div2", CLK_SD1_DIV2, R9A08G046_CLK_SD1, 1, 2), + DEF_FIXED(".sd2_div2", CLK_SD2_DIV2, R9A08G046_CLK_SD2, 1, 2), DEF_FIXED("HP", R9A08G046_CLK_HP, CLK_PLL6_DIV10, 1, 1), DEF_MUX_FLAGS("ETHTX01", R9A08G046_CLK_ETHTX01, G3L_SEL_ETH0_CLK_TX_I, sel_eth0_clk_tx_i, CLK_SET_RATE_PARENT), @@ -279,6 +344,8 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { DEF_FIXED("ETHRM1", R9A08G046_CLK_ETHRM1, CLK_SEL_ETH1_RM, 1, 1), DEF_FIXED("ETHTX12", R9A08G046_CLK_ETHTX12, CLK_SEL_ETH1_TX, 1, 1), DEF_FIXED("ETHRX12", R9A08G046_CLK_ETHRX12, CLK_SEL_ETH1_RX, 1, 1), + DEF_G3S_DIV("G", R9A08G046_CLK_G, CLK_SEL_GE3D, G3L_DIV_GE3D, G3L_DIV_GE3D_STS, + dtable_1_32, 0, 0, 0, NULL), DEF_FIXED("OSCCLK", R9A08G046_OSCCLK, CLK_EXTAL, 1, 1), }; @@ -297,6 +364,42 @@ static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = { MSTOP(BUS_REG0, BIT(0))), DEF_MOD("wdt0_clk", R9A08G046_WDT0_CLK, R9A08G046_OSCCLK, 0x548, 1, MSTOP(BUS_REG0, BIT(0))), + DEF_MOD("sdhi0_imclk", R9A08G046_SDHI0_IMCLK, CLK_SD0_DIV2, 0x554, 0, + MSTOP(BUS_PERI_COM, BIT(0))), + DEF_MOD("sdhi0_imclk2", R9A08G046_SDHI0_IMCLK2, CLK_SD0_DIV2, 0x554, 1, + MSTOP(BUS_PERI_COM, BIT(0))), + DEF_MOD("sdhi0_clk_hs", R9A08G046_SDHI0_CLK_HS, R9A08G046_CLK_SD0, 0x554, 2, + MSTOP(BUS_PERI_COM, BIT(0))), + DEF_MOD("sdhi0_iaclks", R9A08G046_SDHI0_IACLKS, R9A08G046_CLK_P1, 0x554, 3, + MSTOP(BUS_PERI_COM, BIT(0))), + DEF_MOD("sdhi0_iaclkm", R9A08G046_SDHI0_IACLKM, R9A08G046_CLK_P1, 0x554, 12, + MSTOP(BUS_PERI_COM, BIT(0))), + DEF_MOD("sdhi1_imclk", R9A08G046_SDHI1_IMCLK, CLK_SD1_DIV2, 0x554, 4, + MSTOP(BUS_PERI_COM, BIT(1))), + DEF_MOD("sdhi1_imclk2", R9A08G046_SDHI1_IMCLK2, CLK_SD1_DIV2, 0x554, 5, + MSTOP(BUS_PERI_COM, BIT(1))), + DEF_MOD("sdhi1_clk_hs", R9A08G046_SDHI1_CLK_HS, R9A08G046_CLK_SD1, 0x554, 6, + MSTOP(BUS_PERI_COM, BIT(1))), + DEF_MOD("sdhi1_iaclks", R9A08G046_SDHI1_IACLKS, R9A08G046_CLK_P1, 0x554, 7, + MSTOP(BUS_PERI_COM, BIT(1))), + DEF_MOD("sdhi1_iaclkm", R9A08G046_SDHI1_IACLKM, R9A08G046_CLK_P1, 0x554, 13, + MSTOP(BUS_PERI_COM, BIT(1))), + DEF_MOD("sdhi2_imclk", R9A08G046_SDHI2_IMCLK, CLK_SD2_DIV2, 0x554, 8, + MSTOP(BUS_PERI_COM, BIT(11))), + DEF_MOD("sdhi2_imclk2", R9A08G046_SDHI2_IMCLK2, CLK_SD2_DIV2, 0x554, 9, + MSTOP(BUS_PERI_COM, BIT(11))), + DEF_MOD("sdhi2_clk_hs", R9A08G046_SDHI2_CLK_HS, R9A08G046_CLK_SD2, 0x554, 10, + MSTOP(BUS_PERI_COM, BIT(11))), + DEF_MOD("sdhi2_iaclks", R9A08G046_SDHI2_IACLKS, R9A08G046_CLK_P1, 0x554, 11, + MSTOP(BUS_PERI_COM, BIT(11))), + DEF_MOD("sdhi2_iaclkm", R9A08G046_SDHI2_IACLKM, R9A08G046_CLK_P1, 0x554, 14, + MSTOP(BUS_PERI_COM, BIT(11))), + DEF_MOD("ge3d_clk", R9A08G046_GE3D_CLK, R9A08G046_CLK_G, 0x558, 0, + MSTOP(BUS_PERI_VIDEO, BIT(12))), + DEF_MOD("ge3d_axi_clk", R9A08G046_GE3D_AXI_CLK, R9A08G046_CLK_P1, 0x558, 1, + MSTOP(BUS_PERI_VIDEO, BIT(12))), + DEF_MOD("ge3d_ace_clk", R9A08G046_GE3D_ACE_CLK, R9A08G046_CLK_P1, 0x558, 2, + MSTOP(BUS_PERI_VIDEO, BIT(12))), DEF_MOD("ssi0_pclk2", R9A08G046_SSI0_PCLK2, R9A08G046_CLK_P0, 0x570, 0, MSTOP(BUS_MCPU1, BIT(10))), DEF_MOD("ssi0_pclk_sfr", R9A08G046_SSI0_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 1, @@ -313,6 +416,16 @@ static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = { MSTOP(BUS_MCPU1, BIT(13))), DEF_MOD("ssi3_pclk_sfr", R9A08G046_SSI3_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 7, MSTOP(BUS_MCPU1, BIT(13))), + DEF_MOD("usb_u2h0_hclk", R9A08G046_USB_U2H0_HCLK, R9A08G046_CLK_P1, 0x578, 0, + MSTOP(BUS_PERI_COM, BIT(5))), + DEF_MOD("usb_u2h1_hclk", R9A08G046_USB_U2H1_HCLK, R9A08G046_CLK_P1, 0x578, 1, + MSTOP(BUS_PERI_COM, BIT(7))), + DEF_MOD("usb_u2p0_exr_cpuclk", R9A08G046_USB_U2P0_EXR_CPUCLK, R9A08G046_CLK_P1, 0x578, 2, + MSTOP(BUS_PERI_COM, BIT(6))), + DEF_MOD("usb_pclk", R9A08G046_USB_PCLK, R9A08G046_CLK_P1, 0x578, 3, + MSTOP(BUS_PERI_COM, BIT(4))), + DEF_MOD("usb_u2p1_exr_cpuclk", R9A08G046_USB_U2P1_EXR_CPUCLK, R9A08G046_CLK_P1, 0x578, 4, + MSTOP(BUS_PERI_COM, BIT(13))), DEF_MOD("eth0_clk_axi", R9A08G046_ETH0_CLK_AXI, R9A08G046_CLK_P1, 0x57c, 0, MSTOP(BUS_PERI_COM, BIT(2))), DEF_MOD("eth1_clk_axi", R9A08G046_ETH1_CLK_AXI, R9A08G046_CLK_P1, 0x57c, 1, @@ -412,10 +525,27 @@ static const struct rzg2l_reset r9a08g046_resets[] = { DEF_RST(R9A08G046_DMAC_ARESETN, 0x82c, 0), DEF_RST(R9A08G046_DMAC_RST_ASYNC, 0x82c, 1), DEF_RST(R9A08G046_WDT0_PRESETN, 0x848, 0), + DEF_RST(R9A08G046_SDHI0_IXRST, 0x854, 0), + DEF_RST(R9A08G046_SDHI1_IXRST, 0x854, 1), + DEF_RST(R9A08G046_SDHI2_IXRST, 0x854, 2), + DEF_RST(R9A08G046_SDHI0_IXRSTAXIM, 0x854, 3), + DEF_RST(R9A08G046_SDHI0_IXRSTAXIS, 0x854, 4), + DEF_RST(R9A08G046_SDHI1_IXRSTAXIM, 0x854, 5), + DEF_RST(R9A08G046_SDHI1_IXRSTAXIS, 0x854, 6), + DEF_RST(R9A08G046_SDHI2_IXRSTAXIM, 0x854, 7), + DEF_RST(R9A08G046_SDHI2_IXRSTAXIS, 0x854, 8), + DEF_RST(R9A08G046_GE3D_RESETN, 0x858, 0), + DEF_RST(R9A08G046_GE3D_AXI_RESETN, 0x858, 1), + DEF_RST(R9A08G046_GE3D_ACE_RESETN, 0x858, 2), DEF_RST(R9A08G046_SSI0_RST_M2_REG, 0x870, 0), DEF_RST(R9A08G046_SSI1_RST_M2_REG, 0x870, 1), DEF_RST(R9A08G046_SSI2_RST_M2_REG, 0x870, 2), DEF_RST(R9A08G046_SSI3_RST_M2_REG, 0x870, 3), + DEF_RST(R9A08G046_USB_U2H0_HRESETN, 0x878, 0), + DEF_RST(R9A08G046_USB_U2H1_HRESETN, 0x878, 1), + DEF_RST(R9A08G046_USB_U2P0_EXL_SYSRST, 0x878, 2), + DEF_RST(R9A08G046_USB_PRESETN, 0x878, 3), + DEF_RST(R9A08G046_USB_U2P1_EXL_SYSRST, 0x878, 4), DEF_RST(R9A08G046_ETH0_ARESET_N, 0x87c, 0), DEF_RST(R9A08G046_ETH1_ARESET_N, 0x87c, 1), DEF_RST(R9A08G046_I2C0_MRST, 0x880, 0), diff --git a/drivers/clk/renesas/r9a09g047-cpg.c b/drivers/clk/renesas/r9a09g047-cpg.c index 94158b6834e6..f576dd441a11 100644 --- a/drivers/clk/renesas/r9a09g047-cpg.c +++ b/drivers/clk/renesas/r9a09g047-cpg.c @@ -23,6 +23,8 @@ enum clk_ids { CLK_AUDIO_EXTAL, CLK_RTXIN, CLK_QEXTAL, + CLK_AUDIO_CLKB, + CLK_AUDIO_CLKC, /* PLL Clocks */ CLK_PLLCM33, @@ -44,6 +46,7 @@ enum clk_ids { CLK_SMUX2_XSPI_CLK1, CLK_PLLCM33_XSPI, CLK_PLLCLN_DIV2, + CLK_PLLCLN_DIV4, CLK_PLLCLN_DIV8, CLK_PLLCLN_DIV16, CLK_PLLCLN_DIV20, @@ -159,6 +162,8 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { DEF_INPUT("audio_extal", CLK_AUDIO_EXTAL), DEF_INPUT("rtxin", CLK_RTXIN), DEF_INPUT("qextal", CLK_QEXTAL), + DEF_INPUT("audio_clkb", CLK_AUDIO_CLKB), + DEF_INPUT("audio_clkc", CLK_AUDIO_CLKC), /* PLL Clocks */ DEF_FIXED(".pllcm33", CLK_PLLCM33, CLK_QEXTAL, 200, 3), @@ -183,6 +188,7 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { DEF_CSDIV(".pllcm33_xspi", CLK_PLLCM33_XSPI, CLK_SMUX2_XSPI_CLK1, CSDIV0_DIVCTL3, dtable_2_16), DEF_FIXED(".pllcln_div2", CLK_PLLCLN_DIV2, CLK_PLLCLN, 1, 2), + DEF_FIXED(".pllcln_div4", CLK_PLLCLN_DIV4, CLK_PLLCLN, 1, 4), DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8), DEF_FIXED(".pllcln_div16", CLK_PLLCLN_DIV16, CLK_PLLCLN, 1, 16), DEF_FIXED(".pllcln_div20", CLK_PLLCLN_DIV20, CLK_PLLCLN, 1, 20), @@ -194,6 +200,7 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2), DEF_FIXED(".plldty_acpu_div4", CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_ACPU, 1, 4), DEF_FIXED(".plldty_div8", CLK_PLLDTY_DIV8, CLK_PLLDTY, 1, 8), + DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16), DEF_FIXED(".plleth_250_fix", CLK_PLLETH_DIV_250_FIX, CLK_PLLETH, 1, 4), DEF_FIXED(".plleth_125_fix", CLK_PLLETH_DIV_125_FIX, CLK_PLLETH_DIV_250_FIX, 1, 2), @@ -205,7 +212,6 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { DEF_SMUX(".smux2_gbe0_rxclk", CLK_SMUX2_GBE0_RXCLK, SSEL0_SELCTL3, smux2_gbe0_rxclk), DEF_SMUX(".smux2_gbe1_txclk", CLK_SMUX2_GBE1_TXCLK, SSEL1_SELCTL0, smux2_gbe1_txclk), DEF_SMUX(".smux2_gbe1_rxclk", CLK_SMUX2_GBE1_RXCLK, SSEL1_SELCTL1, smux2_gbe1_rxclk), - DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16), DEF_DDIV(".plldty_rcpu", CLK_PLLDTY_RCPU, CLK_PLLDTY, CDDIV3_DIVCTL2, dtable_2_64), DEF_FIXED(".plldty_rcpu_div4", CLK_PLLDTY_RCPU_DIV4, CLK_PLLDTY_RCPU, 1, 4), @@ -530,10 +536,110 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = { BUS_MSTOP(3, BIT(4))), DEF_MOD("ge3d_ace_clk", CLK_PLLDTY_ACPU_DIV2, 15, 2, 7, 18, BUS_MSTOP(3, BIT(4))), + DEF_MOD("ssif_0_clk", CLK_PLLCLN_DIV8, 15, 5, 7, 21, + BUS_MSTOP(2, BIT(3) | BIT(4))), + DEF_MOD("scu_0_clk", CLK_PLLCLN_DIV8, 15, 6, 7, 22, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("scu_0_clkx2", CLK_PLLCLN_DIV4, 15, 7, 7, 23, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("dmacpp_0_clk", CLK_PLLCLN_DIV8, 15, 8, 7, 24, + BUS_MSTOP(2, BIT(5))), + DEF_MOD("adg_0_clks1", CLK_PLLCLN_DIV8, 15, 9, 7, 25, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_0_clk_195m", CLK_PLLCLN_DIV8, 15, 10, 7, 26, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_0_audio_clka", CLK_AUDIO_EXTAL, 15, 11, 7, 27, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_0_audio_clkb", CLK_AUDIO_CLKB, 15, 12, 7, 28, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_0_audio_clkc", CLK_AUDIO_CLKC, 15, 13, 7, 29, + BUS_MSTOP(2, BIT(2))), DEF_MOD("tsu_1_pclk", CLK_QEXTAL, 16, 10, 8, 10, BUS_MSTOP(2, BIT(15))), + DEF_MOD("adg_ssi0_clk", CLK_PLLCLN_DIV8, 22, 0, -1, -1, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_ssi1_clk", CLK_PLLCLN_DIV8, 22, 1, -1, -1, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_ssi2_clk", CLK_PLLCLN_DIV8, 22, 2, -1, -1, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_ssi3_clk", CLK_PLLCLN_DIV8, 22, 3, -1, -1, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_ssi4_clk", CLK_PLLCLN_DIV8, 22, 4, -1, -1, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_ssi5_clk", CLK_PLLCLN_DIV8, 22, 5, -1, -1, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_ssi6_clk", CLK_PLLCLN_DIV8, 22, 6, -1, -1, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_ssi7_clk", CLK_PLLCLN_DIV8, 22, 7, -1, -1, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_ssi8_clk", CLK_PLLCLN_DIV8, 22, 8, -1, -1, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("adg_ssi9_clk", CLK_PLLCLN_DIV8, 22, 9, -1, -1, + BUS_MSTOP(2, BIT(2))), + DEF_MOD("dvc0_clk", CLK_PLLCLN_DIV8, 23, 0, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("dvc1_clk", CLK_PLLCLN_DIV8, 23, 1, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("ctu0_mix0_clk", CLK_PLLCLN_DIV8, 23, 2, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("ctu1_mix1_clk", CLK_PLLCLN_DIV8, 23, 3, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("src0_clk", CLK_PLLCLN_DIV8, 23, 4, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("src1_clk", CLK_PLLCLN_DIV8, 23, 5, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("src2_clk", CLK_PLLCLN_DIV8, 23, 6, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("src3_clk", CLK_PLLCLN_DIV8, 23, 7, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("src4_clk", CLK_PLLCLN_DIV8, 23, 8, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("src5_clk", CLK_PLLCLN_DIV8, 23, 9, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("src6_clk", CLK_PLLCLN_DIV8, 23, 10, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("src7_clk", CLK_PLLCLN_DIV8, 23, 11, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("src8_clk", CLK_PLLCLN_DIV8, 23, 12, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("src9_clk", CLK_PLLCLN_DIV8, 23, 13, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("scu_supply_clk", CLK_PLLCLN_DIV8, 23, 14, -1, -1, + BUS_MSTOP(2, BIT(0) | BIT(1))), + DEF_MOD("ssiu_supply_clk", CLK_PLLCLN_DIV8, 24, 0, -1, -1, + BUS_MSTOP(2, BIT(3) | BIT(4))), + DEF_MOD("ssi0_clk", CLK_PLLCLN_DIV8, 24, 1, -1, -1, + BUS_MSTOP(2, BIT(3) | BIT(4))), + DEF_MOD("ssi1_clk", CLK_PLLCLN_DIV8, 24, 2, -1, -1, + BUS_MSTOP(2, BIT(3) | BIT(4))), + DEF_MOD("ssi2_clk", CLK_PLLCLN_DIV8, 24, 3, -1, -1, + BUS_MSTOP(2, BIT(3) | BIT(4))), + DEF_MOD("ssi3_clk", CLK_PLLCLN_DIV8, 24, 4, -1, -1, + BUS_MSTOP(2, BIT(3) | BIT(4))), + DEF_MOD("ssi4_clk", CLK_PLLCLN_DIV8, 24, 5, -1, -1, + BUS_MSTOP(2, BIT(3) | BIT(4))), + DEF_MOD("ssi5_clk", CLK_PLLCLN_DIV8, 24, 6, -1, -1, + BUS_MSTOP(2, BIT(3) | BIT(4))), + DEF_MOD("ssi6_clk", CLK_PLLCLN_DIV8, 24, 7, -1, -1, + BUS_MSTOP(2, BIT(3) | BIT(4))), + DEF_MOD("ssi7_clk", CLK_PLLCLN_DIV8, 24, 8, -1, -1, + BUS_MSTOP(2, BIT(3) | BIT(4))), + DEF_MOD("ssi8_clk", CLK_PLLCLN_DIV8, 24, 9, -1, -1, + BUS_MSTOP(2, BIT(3) | BIT(4))), + DEF_MOD("ssi9_clk", CLK_PLLCLN_DIV8, 24, 10, -1, -1, + BUS_MSTOP(2, BIT(3) | BIT(4))), DEF_MOD("dsi_0_vclk2", CLK_SMUX2_DSI1_CLK, 25, 0, 10, 21, BUS_MSTOP(9, BIT(15) | BIT(14))), + DEF_MOD("lvds_top_clk_ch0", CLK_PLLDSI0, 26, 0, 10, 22, + BUS_MSTOP(13, BIT(0))), + DEF_MOD("lvds_top_clk_ch1", CLK_PLLDSI1, 26, 1, 10, 23, + BUS_MSTOP(13, BIT(0))), + DEF_MOD("lvds_top_clk_dot_ch0", CLK_SMUX2_DSI0_CLK, 26, 2, 10, 24, + BUS_MSTOP(13, BIT(0))), + DEF_MOD("lvds_top_clk_dot_ch1", CLK_SMUX2_DSI1_CLK, 26, 3, 10, 25, + BUS_MSTOP(13, BIT(0))), + DEF_MOD("lvds_top_pclk", CLK_PLLDTY_DIV16, 26, 4, 10, 26, + BUS_MSTOP(13, BIT(0))), DEF_MOD("lcdc_1_clk_a", CLK_PLLDTY_ACPU_DIV2, 26, 8, 10, 30, BUS_MSTOP(13, BIT(5) | BIT(4) | BIT(3))), DEF_MOD("lcdc_1_clk_p", CLK_PLLDTY_DIV16, 26, 9, 10, 31, @@ -621,7 +727,22 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = { DEF_RST(13, 13, 6, 14), /* GE3D_RESETN */ DEF_RST(13, 14, 6, 15), /* GE3D_AXI_RESETN */ DEF_RST(13, 15, 6, 16), /* GE3D_ACE_RESETN */ + DEF_RST(14, 1, 6, 18), /* SSIF_0_ASYNC_RESET_SSI */ + DEF_RST(14, 2, 6, 19), /* SSIF_0_SYNC_RESET_SSI0 */ + DEF_RST(14, 3, 6, 20), /* SSIF_0_SYNC_RESET_SSI1 */ + DEF_RST(14, 4, 6, 21), /* SSIF_0_SYNC_RESET_SSI2 */ + DEF_RST(14, 5, 6, 22), /* SSIF_0_SYNC_RESET_SSI3 */ + DEF_RST(14, 6, 6, 23), /* SSIF_0_SYNC_RESET_SSI4 */ + DEF_RST(14, 7, 6, 24), /* SSIF_0_SYNC_RESET_SSI5 */ + DEF_RST(14, 8, 6, 25), /* SSIF_0_SYNC_RESET_SSI6 */ + DEF_RST(14, 9, 6, 26), /* SSIF_0_SYNC_RESET_SSI7 */ + DEF_RST(14, 10, 6, 27), /* SSIF_0_SYNC_RESET_SSI8 */ + DEF_RST(14, 11, 6, 28), /* SSIF_0_SYNC_RESET_SSI9 */ + DEF_RST(14, 12, 6, 29), /* SCU_0_RESET_SRU */ + DEF_RST(14, 13, 6, 30), /* DMACpp_0_ARST */ + DEF_RST(14, 14, 6, 31), /* ADG_0_RST_RESET_ADG */ DEF_RST(15, 8, 7, 9), /* TSU_1_PRESETN */ + DEF_RST(17, 10, 8, 11), /* LVDS_TOP_RESET_N */ DEF_RST(17, 14, 8, 15), /* LCDC_1_RESET_N */ }; diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index f777601a23b9..5640c2035e5a 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -8,16 +8,23 @@ #include #include +#include #include #include +#include +#include #include #include +#include #include +#include #include #include #include "renesas-cpg-mssr.h" +MODULE_IMPORT_NS("RZV2H_CPG"); + #define RZT2H_REG_BLOCK_SHIFT 11 #define RZT2H_REG_OFFSET_MASK GENMASK(10, 0) #define RZT2H_REG_CONF(block, offset) (((block) << RZT2H_REG_BLOCK_SHIFT) | \ @@ -66,11 +73,26 @@ #define DIVSCI2ASYNC CONF_PACK(SCKCR3, 10, 2) #define DIVSCI3ASYNC CONF_PACK(SCKCR3, 12, 2) #define DIVSCI4ASYNC CONF_PACK(SCKCR3, 14, 2) +#define LCDCDIVSEL CONF_PACK(SCKCR3, 20, 4) + +#define PLL3EN FIELD_PREP_CONST(OFFSET_MASK, (0xc0)) + +#define CPG_PLL_EN_EN BIT(0) +#define CPG_PLL3_VCO_CTR0(x) ((x) + 0x4) +#define CPG_PLL3_VCO_CTR0_PDIV GENMASK(21, 16) +#define CPG_PLL3_VCO_CTR0_MDIV GENMASK(9, 0) +#define CPG_PLL3_VCO_CTR1(x) ((x) + 0x8) +#define CPG_PLL3_VCO_CTR1_KDIV GENMASK(31, 16) +#define CPG_PLL3_VCO_CTR1_SDIV GENMASK(2, 0) +#define CPG_PLL_MON(x) ((x) - 0x10) +#define CPG_PLL_MON_LOCK BIT(0) enum rzt2h_clk_types { CLK_TYPE_RZT2H_DIV = CLK_TYPE_CUSTOM, /* Clock with divider */ CLK_TYPE_RZT2H_MUX, /* Clock with clock source selector */ CLK_TYPE_RZT2H_FSELXSPI, /* Clock with FSELXSPIn source selector */ + CLK_TYPE_RZT2H_PLL3, /* PLL3 Clock */ + CLK_TYPE_RZT2H_LCDCDIV, /* LCDC divider clock */ }; #define DEF_DIV(_name, _id, _parent, _conf, _dtable) \ @@ -83,10 +105,51 @@ enum rzt2h_clk_types { #define DEF_DIV_FSELXSPI(_name, _id, _parent, _conf, _dtable) \ DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_FSELXSPI, .conf = _conf, \ .parent = _parent, .dtable = _dtable, .flag = 0) +#define DEF_PLL3(_name, _id, _parent, _conf) \ + DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_PLL3, .conf = _conf, \ + .parent = _parent) +#define DEF_DIV_LCDC(_name, _id, _parent, _conf, _dtable) \ + DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_LCDCDIV, .conf = _conf, \ + .parent = _parent, .dtable = _dtable, .flag = CLK_SET_RATE_PARENT) + +struct pll_clk { + void __iomem *reg; + const struct rzv2h_pll_limits *limits; + struct device *dev; + struct rzv2h_pll_pars pll_parameters; + struct clk_hw hw; + unsigned long cur_rate; +}; + +#define to_pll(_hw) container_of(_hw, struct pll_clk, hw) + +struct r9a09g077_lcdc_div_clk { + const struct clk_div_table *dtable; + void __iomem *reg; + struct device *dev; + struct clk_hw hw; + u32 conf; + u8 divider; +}; + +#define to_lcdc_div_clk(_hw) \ + container_of(_hw, struct r9a09g077_lcdc_div_clk, hw) + +#define RZT2H_MAX_LCDC_DIV_TABLES 16 + +static const struct rzv2h_pll_limits r9a09g077_cpg_pll3_limits = { + .input_fref = 48 * MEGA, + .fout = { .min = 25 * MEGA, .max = 430 * MEGA }, + .fvco = { .min = 1600 * MEGA, .max = 3200 * MEGA }, + .m = { .min = 0x40, .max = 0x3ff }, + .p = { .min = 0x2, .max = 0x8 }, + .s = { .min = 0x0, .max = 0x6 }, + .k = { .min = -32768, .max = 32767 }, +}; enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G077_PCLKCAN, + LAST_DT_CORE_CLK = R9A09G077_PCLKRTC, /* External Input Clocks */ CLK_EXTAL, @@ -96,10 +159,12 @@ enum clk_ids { CLK_PLL0, CLK_PLL1, CLK_PLL2, + CLK_PLL3, CLK_PLL4, CLK_SEL_CLK_PLL0, CLK_SEL_CLK_PLL1, CLK_SEL_CLK_PLL2, + CLK_SEL_CLK_PLL3, CLK_SEL_CLK_PLL4, CLK_PLL4D1, CLK_PLL4D1_DIV3, @@ -107,6 +172,7 @@ enum clk_ids { CLK_PLL4D3, CLK_PLL4D3_DIV10, CLK_PLL4D3_DIV20, + CLK_PLL4D50, CLK_SCI0ASYNC, CLK_SCI1ASYNC, CLK_SCI2ASYNC, @@ -119,6 +185,7 @@ enum clk_ids { CLK_SPI3ASYNC, CLK_DIVSELXSPI0_SCKCR, CLK_DIVSELXSPI1_SCKCR, + CLK_LCDDIVSEL, /* Module Clocks */ MOD_CLK_BASE, @@ -130,6 +197,26 @@ static const struct clk_div_table dtable_1_2[] = { {0, 0}, }; +static const struct clk_div_table dtable_2_32[] = { + {0, 2}, + {1, 4}, + {2, 6}, + {3, 8}, + {4, 10}, + {5, 12}, + {6, 14}, + {7, 16}, + {8, 18}, + {9, 20}, + {10, 22}, + {11, 24}, + {12, 26}, + {13, 28}, + {14, 30}, + {15, 32}, + {0, 0}, +}; + static const struct clk_div_table dtable_6_8_16_32_64[] = { {6, 64}, {5, 32}, @@ -152,6 +239,7 @@ static const struct clk_div_table dtable_24_25_30_32[] = { static const char * const sel_clk_pll0[] = { ".loco", ".pll0" }; static const char * const sel_clk_pll1[] = { ".loco", ".pll1" }; static const char * const sel_clk_pll2[] = { ".loco", ".pll2" }; +static const char * const sel_clk_pll3[] = { ".loco", ".pll3" }; static const char * const sel_clk_pll4[] = { ".loco", ".pll4" }; static const char * const sel_clk_pll4d1_div3_div4[] = { ".pll4d1_div3", ".pll4d1_div4" }; static const char * const sel_clk_pll4d3_div10_div20[] = { ".pll4d3_div10", ".pll4d3_div20" }; @@ -173,10 +261,14 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { sel_clk_pll1, ARRAY_SIZE(sel_clk_pll1), CLK_MUX_READ_ONLY), DEF_MUX(".sel_clk_pll2", CLK_SEL_CLK_PLL2, SEL_PLL, sel_clk_pll2, ARRAY_SIZE(sel_clk_pll2), CLK_MUX_READ_ONLY), + DEF_MUX(".sel_clk_pll3", CLK_SEL_CLK_PLL3, SEL_PLL, + sel_clk_pll3, ARRAY_SIZE(sel_clk_pll3), CLK_MUX_READ_ONLY), DEF_MUX(".sel_clk_pll4", CLK_SEL_CLK_PLL4, SEL_PLL, sel_clk_pll4, ARRAY_SIZE(sel_clk_pll4), CLK_MUX_READ_ONLY), DEF_FIXED(".pll4d1", CLK_PLL4D1, CLK_SEL_CLK_PLL4, 1, 1), + DEF_FIXED(".pll4d50", CLK_PLL4D50, CLK_SEL_CLK_PLL4, 50, 1), + DEF_PLL3(".pll3", CLK_PLL3, CLK_PLL4D50, PLL3EN), DEF_FIXED(".pll4d1_div3", CLK_PLL4D1_DIV3, CLK_PLL4D1, 3, 1), DEF_FIXED(".pll4d1_div4", CLK_PLL4D1_DIV4, CLK_PLL4D1, 4, 1), DEF_FIXED(".pll4d3", CLK_PLL4D3, CLK_SEL_CLK_PLL4, 3, 1), @@ -229,6 +321,7 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { DEF_FIXED("PCLKL", R9A09G077_CLK_PCLKL, CLK_SEL_CLK_PLL1, 16, 1), DEF_FIXED("PCLKAH", R9A09G077_CLK_PCLKAH, CLK_PLL4D1, 6, 1), DEF_FIXED("PCLKAM", R9A09G077_CLK_PCLKAM, CLK_PLL4D1, 12, 1), + DEF_FIXED("PCLKAL", R9A09G077_CLK_PCLKAL, CLK_PLL4D1, 24, 1), DEF_FIXED("SDHI_CLKHS", R9A09G077_SDHI_CLKHS, CLK_SEL_CLK_PLL2, 1, 1), DEF_FIXED("USB_CLK", R9A09G077_USB_CLK, CLK_PLL4D1, 48, 1), DEF_FIXED("ETCLKA", R9A09G077_ETCLKA, CLK_SEL_CLK_PLL1, 5, 1), @@ -242,6 +335,9 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { FSELXSPI1, dtable_6_8_16_32_64), DEF_MUX("PCLKCAN", R9A09G077_PCLKCAN, FSELCANFD, sel_clk_pll4d3_div10_div20, ARRAY_SIZE(sel_clk_pll4d3_div10_div20), 0), + DEF_DIV_LCDC("LCDC_CLKD", R9A09G077_LCDC_CLKD, CLK_SEL_CLK_PLL3, LCDCDIVSEL, + dtable_2_32), + DEF_FIXED("PCLKRTC", R9A09G077_PCLKRTC, CLK_EXTAL, 128, 1), }; static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { @@ -272,6 +368,8 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { DEF_MOD("sci5fck", 600, CLK_SCI5ASYNC), DEF_MOD("iic2", 601, R9A09G077_CLK_PCLKL), DEF_MOD("spi3", 602, CLK_SPI3ASYNC), + DEF_MOD("rtc", 605, R9A09G077_CLK_PCLKL), + DEF_MOD("lcdc", 1204, R9A09G077_CLK_PCLKAL), DEF_MOD("sdhi0", 1212, R9A09G077_CLK_PCLKAM), DEF_MOD("sdhi1", 1213, R9A09G077_CLK_PCLKAM), }; @@ -481,6 +579,276 @@ r9a09g077_cpg_fselxspi_div_clk_register(struct device *dev, return hw->clk; } +static unsigned long r9a09g077_cpg_pll3_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct pll_clk *pll_clk = to_pll(hw); + u32 ctr0, ctr1; + u8 pdiv, sdiv; + u64 rate; + u16 mdiv; + s16 kdiv; + + ctr0 = readl(CPG_PLL3_VCO_CTR0(pll_clk->reg)); + ctr1 = readl(CPG_PLL3_VCO_CTR1(pll_clk->reg)); + + pdiv = FIELD_GET(CPG_PLL3_VCO_CTR0_PDIV, ctr0); + mdiv = FIELD_GET(CPG_PLL3_VCO_CTR0_MDIV, ctr0); + kdiv = (s16)FIELD_GET(CPG_PLL3_VCO_CTR1_KDIV, ctr1); + sdiv = FIELD_GET(CPG_PLL3_VCO_CTR1_SDIV, ctr1); + + rate = mul_u64_u32_shr(parent_rate, (mdiv << 16) + kdiv, 16 + sdiv); + + return DIV_ROUND_CLOSEST_ULL(rate, pdiv); +} + +static int r9a09g077_cpg_pll3_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct pll_clk *pll_clk = to_pll(hw); + u64 rate_millihz; + + if (req->rate == pll_clk->cur_rate) + return 0; + + rate_millihz = mul_u32_u32(req->rate, MILLI); + if (!rzv2h_cpg_get_pll_pars(pll_clk->limits, &pll_clk->pll_parameters, + rate_millihz)) { + dev_dbg(pll_clk->dev, + "failed to determine rate for req->rate: %lu\n", + req->rate); + return -EINVAL; + } + req->rate = DIV_ROUND_CLOSEST_ULL(pll_clk->pll_parameters.freq_millihz, MILLI); + pll_clk->cur_rate = req->rate; + + return 0; +} + +static int r9a09g077_cpg_pll3_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzv2h_pll_pars *params = &pll_clk->pll_parameters; + void __iomem *offset = pll_clk->reg; + u32 val; + int ret; + + /* Put PLL into standby mode */ + writel(0, offset); + ret = readl_poll_timeout_atomic(CPG_PLL_MON(offset), + val, !(val & CPG_PLL_MON_LOCK), + 100, 2000); + if (ret) { + dev_err(pll_clk->dev, "Failed to put PLL into standby mode"); + return ret; + } + + /* Output clock setting 1 */ + val = readl(CPG_PLL3_VCO_CTR0(offset)); + FIELD_MODIFY(CPG_PLL3_VCO_CTR0_MDIV, &val, params->m); + FIELD_MODIFY(CPG_PLL3_VCO_CTR0_PDIV, &val, params->p); + writel(val, CPG_PLL3_VCO_CTR0(offset)); + + /* Output clock setting 2 */ + val = readl(CPG_PLL3_VCO_CTR1(offset)); + FIELD_MODIFY(CPG_PLL3_VCO_CTR1_KDIV, &val, params->k); + FIELD_MODIFY(CPG_PLL3_VCO_CTR1_SDIV, &val, params->s); + writel(val, CPG_PLL3_VCO_CTR1(offset)); + + writel(CPG_PLL_EN_EN, offset); + + /* PLL normal mode transition, output clock stability check */ + ret = readl_poll_timeout_atomic(CPG_PLL_MON(offset), + val, (val & CPG_PLL_MON_LOCK), + 100, 2000); + if (ret) { + writel(0, offset); + dev_err(pll_clk->dev, "Failed to put PLL into normal mode"); + return ret; + } + + return 0; +} + +static const struct clk_ops r9a09g077_cpg_pll3_ops = { + .recalc_rate = r9a09g077_cpg_pll3_clk_recalc_rate, + .determine_rate = r9a09g077_cpg_pll3_determine_rate, + .set_rate = r9a09g077_cpg_pll3_set_rate, +}; + +static struct clk * __init +r9a09g077_cpg_pll3_clk_register(struct device *dev, + const struct cpg_core_clk *core, + void __iomem *addr, + struct cpg_mssr_pub *pub, + const struct rzv2h_pll_limits *limits) +{ + struct clk_init_data init = {}; + const struct clk *parent; + const char *parent_name; + struct pll_clk *pll_clk; + int ret; + + parent = pub->clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); + if (!pll_clk) + return ERR_PTR(-ENOMEM); + + parent_name = __clk_get_name(parent); + init.name = core->name; + init.ops = &r9a09g077_cpg_pll3_ops; + init.parent_names = &parent_name; + init.num_parents = 1; + + pll_clk->dev = dev; + pll_clk->hw.init = &init; + pll_clk->reg = addr; + pll_clk->limits = limits; + + ret = devm_clk_hw_register(dev, &pll_clk->hw); + if (ret) + return ERR_PTR(ret); + + return pll_clk->hw.clk; +} + +static int r9a09g077_cpg_lcdc_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct r9a09g077_lcdc_div_clk *dsi_div = to_lcdc_div_clk(hw); + struct clk_hw *mux_hw = clk_hw_get_parent(hw); + u8 table[RZT2H_MAX_LCDC_DIV_TABLES] = { 0 }; + struct rzv2h_pll_div_pars dsi_params; + const struct clk_div_table *div; + struct pll_clk *pll_clk; + unsigned int i = 0; + u64 freq_millihz; + + /* index 1 is always .pll3 in sel_clk_pll3[] */ + pll_clk = to_pll(clk_hw_get_parent_by_index(mux_hw, 1)); + + for (div = dsi_div->dtable; div->div; div++) { + if (i >= RZT2H_MAX_LCDC_DIV_TABLES) + return -EINVAL; + table[i++] = div->div; + } + + freq_millihz = mul_u32_u32(req->rate, MILLI); + + if (!rzv2h_cpg_get_pll_divs_pars(pll_clk->limits, &dsi_params, table, + i, freq_millihz)) { + dev_err(dsi_div->dev, + "LCDC divider failed to determine rate for req->rate: %lu\n", + req->rate); + return -EINVAL; + } + + req->rate = DIV_ROUND_CLOSEST_ULL(dsi_params.div.freq_millihz, MILLI); + req->best_parent_rate = req->rate * dsi_params.div.divider_value; + dsi_div->divider = dsi_params.div.divider_value; + pll_clk->cur_rate = req->best_parent_rate; + pll_clk->pll_parameters = dsi_params.pll; + + return 0; +} + +static int r9a09g077_cpg_lcdc_div_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct r9a09g077_lcdc_div_clk *dsi_div = to_lcdc_div_clk(hw); + const struct clk_div_table *clkt; + bool divider_found = false; + u32 val, shift; + + for (clkt = dsi_div->dtable; clkt->div; clkt++) { + if (clkt->div == dsi_div->divider) { + divider_found = true; + break; + } + } + + if (!divider_found) + return -EINVAL; + + shift = GET_SHIFT(dsi_div->conf); + val = readl(dsi_div->reg); + val &= ~(clk_div_mask(GET_WIDTH(dsi_div->conf)) << shift); + val |= clkt->val << shift; + writel(val, dsi_div->reg); + + return 0; +} + +static unsigned long +r9a09g077_cpg_lcdc_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct r9a09g077_lcdc_div_clk *dsi_div = to_lcdc_div_clk(hw); + u32 div; + + div = readl(dsi_div->reg); + div >>= GET_SHIFT(dsi_div->conf); + div &= clk_div_mask(GET_WIDTH(dsi_div->conf)); + div = dsi_div->dtable[div].div; + + return DIV_ROUND_CLOSEST_ULL(parent_rate, div); +} + +static const struct clk_ops r9a09g077_cpg_lcdc_div_ops = { + .recalc_rate = r9a09g077_cpg_lcdc_div_recalc_rate, + .determine_rate = r9a09g077_cpg_lcdc_div_determine_rate, + .set_rate = r9a09g077_cpg_lcdc_div_set_rate, +}; + +static struct clk * __init +r9a09g077_cpg_lcdc_div_clk_register(struct device *dev, + const struct cpg_core_clk *core, + void __iomem *addr, + struct cpg_mssr_pub *pub) +{ + struct r9a09g077_lcdc_div_clk *clk_hw_data; + struct clk_init_data init = {}; + struct clk **clks = pub->clks; + const struct clk *parent; + const char *parent_name; + struct clk_hw *hw; + int ret; + + parent = clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + clk_hw_data = devm_kzalloc(dev, sizeof(*clk_hw_data), GFP_KERNEL); + if (!clk_hw_data) + return ERR_PTR(-ENOMEM); + + clk_hw_data->dtable = core->dtable; + clk_hw_data->reg = addr; + clk_hw_data->conf = core->conf; + clk_hw_data->dev = dev; + clk_hw_data->divider = 32; /* Initialize divider for LCDC */ + + parent_name = __clk_get_name(parent); + init.name = core->name; + init.ops = &r9a09g077_cpg_lcdc_div_ops; + init.flags = core->flag; + init.parent_names = &parent_name; + init.num_parents = 1; + + hw = &clk_hw_data->hw; + hw->init = &init; + ret = devm_clk_hw_register(dev, hw); + if (ret) + return ERR_PTR(ret); + + return hw->clk; +} + static struct clk * __init r9a09g077_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, @@ -497,6 +865,11 @@ r9a09g077_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, return r9a09g077_cpg_mux_clk_register(dev, core, addr, pub); case CLK_TYPE_RZT2H_FSELXSPI: return r9a09g077_cpg_fselxspi_div_clk_register(dev, core, addr, pub); + case CLK_TYPE_RZT2H_PLL3: + return r9a09g077_cpg_pll3_clk_register(dev, core, pub->base1 + offset, + pub, &r9a09g077_cpg_pll3_limits); + case CLK_TYPE_RZT2H_LCDCDIV: + return r9a09g077_cpg_lcdc_div_clk_register(dev, core, addr, pub); default: return ERR_PTR(-EINVAL); } diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index b6dab92cb220..80f4403ea2ba 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -252,6 +252,22 @@ static void cpg_rzt2h_mstp_write(struct cpg_mssr_priv *priv, u16 offset, u32 val writel(value, base + RZT2H_MSTPCR_OFFSET(offset)); } +static void cpg_rzt2h_mstp_delay(u32 idx, bool bit_valid) +{ + unsigned int mask = bit_valid ? GENMASK(31, 0) : GENMASK(31, 5); + + if (idx == (MOD_CLK_PACK(1204) & mask)) { + /* LCDC needs 100 dummy reads, or 142us */ + udelay(142); + } else if (idx == (MOD_CLK_PACK(605) & mask)) { + /* RTC needs 300 dummy reads, or 428us */ + udelay(428); + } else { + /* default 7 dummy reads, or 10us */ + udelay(10); + } +} + static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) { struct mstp_clock *clock = to_mstp_clock(hw); @@ -311,7 +327,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) * register, we simply add a delay after the read operation. */ cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); - udelay(10); + cpg_rzt2h_mstp_delay(clock->index, true); return 0; } @@ -1141,7 +1157,7 @@ static int cpg_mssr_resume_noirq(struct device *dev) cpg_rzt2h_mstp_write(priv, priv->control_regs[reg], newval); /* See cpg_mstp_clock_endisable() on why this is necessary. */ cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); - udelay(10); + cpg_rzt2h_mstp_delay(reg * 32, false); continue; } else writel(newval, priv->pub.base0 + priv->control_regs[reg]); diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 975b705d3a2b..a899c37dd4cd 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -944,12 +944,6 @@ static unsigned long rzg2l_cpg_sipll5_recalc_rate(struct clk_hw *hw, return pll5_rate; } -static int rzg2l_cpg_sipll5_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - return 0; -} - static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) @@ -1021,7 +1015,7 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw, static const struct clk_ops rzg2l_cpg_sipll5_ops = { .recalc_rate = rzg2l_cpg_sipll5_recalc_rate, - .determine_rate = rzg2l_cpg_sipll5_determine_rate, + .determine_rate = clk_determine_rate_noop, .set_rate = rzg2l_cpg_sipll5_set_rate, }; diff --git a/drivers/clk/renesas/rzv2h-cpg-lib.c b/drivers/clk/renesas/rzv2h-cpg-lib.c new file mode 100644 index 000000000000..124239c7327e --- /dev/null +++ b/drivers/clk/renesas/rzv2h-cpg-lib.c @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RZV2H CPG Library. This library provides common functions to calculate + * PLL parameters for the RZV2H SoC. + * + * Copyright (C) 2026 Renesas Electronics Corp. + * + */ + +#include +#include +#include +#include +#include + +/** + * rzv2h_cpg_get_pll_pars - Finds the best combination of PLL parameters + * for a given frequency. + * + * @limits: Pointer to the structure containing the limits for the PLL parameters + * @pars: Pointer to the structure where the best calculated PLL parameters values + * will be stored + * @freq_millihz: Target output frequency in millihertz + * + * This function calculates the best set of PLL parameters (M, K, P, S) to achieve + * the desired frequency. + * There is no direct formula to calculate the PLL parameters, as it's an open + * system of equations, therefore this function uses an iterative approach to + * determine the best solution. The best solution is one that minimizes the error + * (desired frequency - actual frequency). + * + * Return: true if a valid set of parameters values is found, false otherwise. + */ +bool rzv2h_cpg_get_pll_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_pars *pars, u64 freq_millihz) +{ + unsigned long input_fref = limits->input_fref ?: (24 * MEGA); + u64 fout_min_millihz = mul_u32_u32(limits->fout.min, MILLI); + u64 fout_max_millihz = mul_u32_u32(limits->fout.max, MILLI); + struct rzv2h_pll_pars p, best; + + if (freq_millihz > fout_max_millihz || + freq_millihz < fout_min_millihz) + return false; + + /* Initialize best error to maximum possible value */ + best.error_millihz = S64_MAX; + + for (p.p = limits->p.min; p.p <= limits->p.max; p.p++) { + u32 fref = input_fref / p.p; + u16 divider; + + for (divider = 1 << limits->s.min, p.s = limits->s.min; + p.s <= limits->s.max; p.s++, divider <<= 1) { + for (p.m = limits->m.min; p.m <= limits->m.max; p.m++) { + u64 output_m, output_k_range; + s64 pll_k, output_k; + u64 fvco, output; + + /* + * The frequency generated by the PLL + divider + * is calculated as follows: + * + * With: + * Freq = Ffout = Ffvco / 2^(pll_s) + * Ffvco = (pll_m + (pll_k / 65536)) * Ffref + * Ffref = 24MHz / pll_p + * + * Freq can also be rewritten as: + * Freq = Ffvco / 2^(pll_s) + * = ((pll_m + (pll_k / 65536)) * Ffref) / 2^(pll_s) + * = (pll_m * Ffref) / 2^(pll_s) + ((pll_k / 65536) * Ffref) / 2^(pll_s) + * = output_m + output_k + * + * Every parameter has been determined at this + * point, but pll_k. + * + * Considering that: + * limits->k.min <= pll_k <= limits->k.max + * Then: + * -0.5 <= (pll_k / 65536) < 0.5 + * Therefore: + * -Ffref / (2 * 2^(pll_s)) <= output_k < Ffref / (2 * 2^(pll_s)) + */ + + /* Compute output M component (in mHz) */ + output_m = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(p.m, fref) * MILLI, + divider); + /* Compute range for output K (in mHz) */ + output_k_range = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(fref, MILLI), + 2 * divider); + /* + * No point in continuing if we can't achieve + * the desired frequency + */ + if (freq_millihz < (output_m - output_k_range) || + freq_millihz >= (output_m + output_k_range)) { + continue; + } + + /* + * Compute the K component + * + * Since: + * Freq = output_m + output_k + * Then: + * output_k = Freq - output_m + * = ((pll_k / 65536) * Ffref) / 2^(pll_s) + * Therefore: + * pll_k = (output_k * 65536 * 2^(pll_s)) / Ffref + */ + output_k = freq_millihz - output_m; + pll_k = div_s64(output_k * 65536ULL * divider, + fref); + pll_k = DIV_S64_ROUND_CLOSEST(pll_k, MILLI); + + /* Validate K value within allowed limits */ + if (pll_k < limits->k.min || + pll_k > limits->k.max) + continue; + + p.k = pll_k; + + /* Compute (Ffvco * 65536) */ + fvco = mul_u32_u32(p.m * 65536 + p.k, fref); + if (fvco < mul_u32_u32(limits->fvco.min, 65536) || + fvco > mul_u32_u32(limits->fvco.max, 65536)) + continue; + + /* PLL_M component of (output * 65536 * PLL_P) */ + output = mul_u32_u32(p.m * 65536, input_fref); + /* PLL_K component of (output * 65536 * PLL_P) */ + output += p.k * input_fref; + /* Make it in mHz */ + output *= MILLI; + output = DIV_U64_ROUND_CLOSEST(output, 65536 * p.p * divider); + + /* Check output frequency against limits */ + if (output < fout_min_millihz || + output > fout_max_millihz) + continue; + + p.error_millihz = freq_millihz - output; + p.freq_millihz = output; + + /* If an exact match is found, return immediately */ + if (p.error_millihz == 0) { + *pars = p; + return true; + } + + /* Update best match if error is smaller */ + if (abs(best.error_millihz) > abs(p.error_millihz)) + best = p; + } + } + } + + /* If no valid parameters were found, return false */ + if (best.error_millihz == S64_MAX) + return false; + + *pars = best; + return true; +} +EXPORT_SYMBOL_NS_GPL(rzv2h_cpg_get_pll_pars, "RZV2H_CPG"); + +/* + * rzv2h_cpg_get_pll_divs_pars - Finds the best combination of PLL parameters + * and divider value for a given frequency. + * + * @limits: Pointer to the structure containing the limits for the PLL parameters + * @pars: Pointer to the structure where the best calculated PLL parameters and + * divider values will be stored + * @table: Pointer to the array of valid divider values + * @table_size: Size of the divider values array + * @freq_millihz: Target output frequency in millihertz + * + * This function calculates the best set of PLL parameters (M, K, P, S) and divider + * value to achieve the desired frequency. See rzv2h_cpg_get_pll_pars() for more + * details on how the PLL parameters are calculated. + * + * freq_millihz is the desired frequency generated by the PLL followed by a + * a gear. + */ +bool rzv2h_cpg_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_div_pars *pars, + const u8 *table, u8 table_size, u64 freq_millihz) +{ + struct rzv2h_pll_div_pars p, best; + + best.div.error_millihz = S64_MAX; + p.div.error_millihz = S64_MAX; + for (unsigned int i = 0; i < table_size; i++) { + if (!rzv2h_cpg_get_pll_pars(limits, &p.pll, freq_millihz * table[i])) + continue; + + p.div.divider_value = table[i]; + p.div.freq_millihz = DIV_U64_ROUND_CLOSEST(p.pll.freq_millihz, table[i]); + p.div.error_millihz = freq_millihz - p.div.freq_millihz; + + if (p.div.error_millihz == 0) { + *pars = p; + return true; + } + + if (abs(best.div.error_millihz) > abs(p.div.error_millihz)) + best = p; + } + + if (best.div.error_millihz == S64_MAX) + return false; + + *pars = best; + return true; +} +EXPORT_SYMBOL_NS_GPL(rzv2h_cpg_get_pll_divs_pars, "RZV2H_CPG"); diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index 5bdfdc415bb6..917fc737f254 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -217,211 +217,8 @@ struct rzv2h_plldsi_div_clk { #define to_plldsi_div_clk(_hw) \ container_of(_hw, struct rzv2h_plldsi_div_clk, hw) -#define RZ_V2H_OSC_CLK_IN_MEGA (24 * MEGA) #define RZV2H_MAX_DIV_TABLES (16) -/** - * rzv2h_get_pll_pars - Finds the best combination of PLL parameters - * for a given frequency. - * - * @limits: Pointer to the structure containing the limits for the PLL parameters - * @pars: Pointer to the structure where the best calculated PLL parameters values - * will be stored - * @freq_millihz: Target output frequency in millihertz - * - * This function calculates the best set of PLL parameters (M, K, P, S) to achieve - * the desired frequency. - * There is no direct formula to calculate the PLL parameters, as it's an open - * system of equations, therefore this function uses an iterative approach to - * determine the best solution. The best solution is one that minimizes the error - * (desired frequency - actual frequency). - * - * Return: true if a valid set of parameters values is found, false otherwise. - */ -bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits, - struct rzv2h_pll_pars *pars, u64 freq_millihz) -{ - u64 fout_min_millihz = mul_u32_u32(limits->fout.min, MILLI); - u64 fout_max_millihz = mul_u32_u32(limits->fout.max, MILLI); - struct rzv2h_pll_pars p, best; - - if (freq_millihz > fout_max_millihz || - freq_millihz < fout_min_millihz) - return false; - - /* Initialize best error to maximum possible value */ - best.error_millihz = S64_MAX; - - for (p.p = limits->p.min; p.p <= limits->p.max; p.p++) { - u32 fref = RZ_V2H_OSC_CLK_IN_MEGA / p.p; - u16 divider; - - for (divider = 1 << limits->s.min, p.s = limits->s.min; - p.s <= limits->s.max; p.s++, divider <<= 1) { - for (p.m = limits->m.min; p.m <= limits->m.max; p.m++) { - u64 output_m, output_k_range; - s64 pll_k, output_k; - u64 fvco, output; - - /* - * The frequency generated by the PLL + divider - * is calculated as follows: - * - * With: - * Freq = Ffout = Ffvco / 2^(pll_s) - * Ffvco = (pll_m + (pll_k / 65536)) * Ffref - * Ffref = 24MHz / pll_p - * - * Freq can also be rewritten as: - * Freq = Ffvco / 2^(pll_s) - * = ((pll_m + (pll_k / 65536)) * Ffref) / 2^(pll_s) - * = (pll_m * Ffref) / 2^(pll_s) + ((pll_k / 65536) * Ffref) / 2^(pll_s) - * = output_m + output_k - * - * Every parameter has been determined at this - * point, but pll_k. - * - * Considering that: - * limits->k.min <= pll_k <= limits->k.max - * Then: - * -0.5 <= (pll_k / 65536) < 0.5 - * Therefore: - * -Ffref / (2 * 2^(pll_s)) <= output_k < Ffref / (2 * 2^(pll_s)) - */ - - /* Compute output M component (in mHz) */ - output_m = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(p.m, fref) * MILLI, - divider); - /* Compute range for output K (in mHz) */ - output_k_range = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(fref, MILLI), - 2 * divider); - /* - * No point in continuing if we can't achieve - * the desired frequency - */ - if (freq_millihz < (output_m - output_k_range) || - freq_millihz >= (output_m + output_k_range)) { - continue; - } - - /* - * Compute the K component - * - * Since: - * Freq = output_m + output_k - * Then: - * output_k = Freq - output_m - * = ((pll_k / 65536) * Ffref) / 2^(pll_s) - * Therefore: - * pll_k = (output_k * 65536 * 2^(pll_s)) / Ffref - */ - output_k = freq_millihz - output_m; - pll_k = div_s64(output_k * 65536ULL * divider, - fref); - pll_k = DIV_S64_ROUND_CLOSEST(pll_k, MILLI); - - /* Validate K value within allowed limits */ - if (pll_k < limits->k.min || - pll_k > limits->k.max) - continue; - - p.k = pll_k; - - /* Compute (Ffvco * 65536) */ - fvco = mul_u32_u32(p.m * 65536 + p.k, fref); - if (fvco < mul_u32_u32(limits->fvco.min, 65536) || - fvco > mul_u32_u32(limits->fvco.max, 65536)) - continue; - - /* PLL_M component of (output * 65536 * PLL_P) */ - output = mul_u32_u32(p.m * 65536, RZ_V2H_OSC_CLK_IN_MEGA); - /* PLL_K component of (output * 65536 * PLL_P) */ - output += p.k * RZ_V2H_OSC_CLK_IN_MEGA; - /* Make it in mHz */ - output *= MILLI; - output = DIV_U64_ROUND_CLOSEST(output, 65536 * p.p * divider); - - /* Check output frequency against limits */ - if (output < fout_min_millihz || - output > fout_max_millihz) - continue; - - p.error_millihz = freq_millihz - output; - p.freq_millihz = output; - - /* If an exact match is found, return immediately */ - if (p.error_millihz == 0) { - *pars = p; - return true; - } - - /* Update best match if error is smaller */ - if (abs(best.error_millihz) > abs(p.error_millihz)) - best = p; - } - } - } - - /* If no valid parameters were found, return false */ - if (best.error_millihz == S64_MAX) - return false; - - *pars = best; - return true; -} -EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_pars, "RZV2H_CPG"); - -/* - * rzv2h_get_pll_divs_pars - Finds the best combination of PLL parameters - * and divider value for a given frequency. - * - * @limits: Pointer to the structure containing the limits for the PLL parameters - * @pars: Pointer to the structure where the best calculated PLL parameters and - * divider values will be stored - * @table: Pointer to the array of valid divider values - * @table_size: Size of the divider values array - * @freq_millihz: Target output frequency in millihertz - * - * This function calculates the best set of PLL parameters (M, K, P, S) and divider - * value to achieve the desired frequency. See rzv2h_get_pll_pars() for more details - * on how the PLL parameters are calculated. - * - * freq_millihz is the desired frequency generated by the PLL followed by a - * a gear. - */ -bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, - struct rzv2h_pll_div_pars *pars, - const u8 *table, u8 table_size, u64 freq_millihz) -{ - struct rzv2h_pll_div_pars p, best; - - best.div.error_millihz = S64_MAX; - p.div.error_millihz = S64_MAX; - for (unsigned int i = 0; i < table_size; i++) { - if (!rzv2h_get_pll_pars(limits, &p.pll, freq_millihz * table[i])) - continue; - - p.div.divider_value = table[i]; - p.div.freq_millihz = DIV_U64_ROUND_CLOSEST(p.pll.freq_millihz, table[i]); - p.div.error_millihz = freq_millihz - p.div.freq_millihz; - - if (p.div.error_millihz == 0) { - *pars = p; - return true; - } - - if (abs(best.div.error_millihz) > abs(p.div.error_millihz)) - best = p; - } - - if (best.div.error_millihz == S64_MAX) - return false; - - *pars = best; - return true; -} -EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_divs_pars, "RZV2H_CPG"); - /** * struct rzv2h_plldsi_mux_clk - PLL DSI MUX clock * diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig index 85133498f013..4b55f48d72c2 100644 --- a/drivers/clk/rockchip/Kconfig +++ b/drivers/clk/rockchip/Kconfig @@ -23,6 +23,13 @@ config CLK_RV1103B help Build the driver for RV1103B Clock Driver. +config CLK_RV1106 + bool "Rockchip RV1106 clock controller support" + depends on ARM || COMPILE_TEST + default y + help + Build the driver for RV1106 Clock Driver. + config CLK_RV110X bool "Rockchip RV110x clock controller support" depends on ARM || COMPILE_TEST diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index 7c984ee006c6..554b7eb83dc9 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -19,6 +19,7 @@ clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o obj-$(CONFIG_CLK_PX30) += clk-px30.o obj-$(CONFIG_CLK_RV1103B) += clk-rv1103b.o +obj-$(CONFIG_CLK_RV1106) += clk-rv1106.o obj-$(CONFIG_CLK_RV110X) += clk-rv1108.o obj-$(CONFIG_CLK_RV1126) += clk-rv1126.o obj-$(CONFIG_CLK_RV1126B) += clk-rv1126b.o rst-rv1126b.o diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index 6b853800cb6b..706ca4b344d3 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "clk.h" @@ -900,6 +901,14 @@ static void rockchip_rk3588_pll_get_params(struct rockchip_clk_pll *pll, rate->k = ((pllcon >> RK3588_PLLCON2_K_SHIFT) & RK3588_PLLCON2_K_MASK); } +/* + * 2250 MHz <= Fvco <= 4500 MHz + * For Fvco > 3 GHz: period jitter +-1% frac PLL, +-0.75% int PLL + * For Fvco < 3 GHz: period jitter +-2% frac PLL, +-1.50% int PLL + * Fvco = ((m + k / 65536) * Fin) / p + * Fout = ((m + k / 65536) * Fin) / (p * 2^s) + * -32768 <= k <= 32767 (only available in frac PLLs, not int PLLs) + */ static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw, unsigned long prate) { struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); @@ -913,11 +922,10 @@ static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw, unsigned if (cur.k) { /* fractional mode */ - u64 frac_rate64 = prate * cur.k; + s64 frac_rate64 = (s64)prate * cur.k; - postdiv = cur.p * 65535; - do_div(frac_rate64, postdiv); - rate64 += frac_rate64; + postdiv = cur.p * 65536; + rate64 += div_s64(frac_rate64, postdiv); } rate64 = rate64 >> cur.s; diff --git a/drivers/clk/rockchip/clk-rk3576.c b/drivers/clk/rockchip/clk-rk3576.c index 2557358e0b9d..2cdd667f4004 100644 --- a/drivers/clk/rockchip/clk-rk3576.c +++ b/drivers/clk/rockchip/clk-rk3576.c @@ -79,13 +79,13 @@ static struct rockchip_pll_rate_table rk3576_pll_rates[] = { RK3588_PLL_RATE(1008000000, 2, 336, 2, 0), RK3588_PLL_RATE(1000000000, 3, 500, 2, 0), RK3588_PLL_RATE(983040000, 4, 655, 2, 23592), - RK3588_PLL_RATE(955520000, 3, 477, 2, 49806), + RK3588_PLL_RATE(955520000, 3, 478, 2, -15730), RK3588_PLL_RATE(903168000, 6, 903, 2, 11009), RK3588_PLL_RATE(900000000, 2, 300, 2, 0), RK3588_PLL_RATE(816000000, 2, 272, 2, 0), RK3588_PLL_RATE(786432000, 2, 262, 2, 9437), RK3588_PLL_RATE(786000000, 1, 131, 2, 0), - RK3588_PLL_RATE(785560000, 3, 392, 2, 51117), + RK3588_PLL_RATE(785560000, 3, 393, 2, -14419), RK3588_PLL_RATE(722534400, 8, 963, 2, 24850), RK3588_PLL_RATE(600000000, 2, 200, 2, 0), RK3588_PLL_RATE(594000000, 2, 198, 2, 0), @@ -315,6 +315,7 @@ PNAME(mux_100m_24m_lclk0_p) = { "clk_cpll_div10", "xin24m", "lclk_asrc_src_0" } PNAME(mux_100m_24m_lclk1_p) = { "clk_cpll_div10", "xin24m", "lclk_asrc_src_1" }; PNAME(mux_150m_100m_50m_24m_p) = { "clk_gpll_div8", "clk_cpll_div10", "clk_cpll_div20", "xin24m" }; PNAME(mux_200m_100m_50m_24m_p) = { "clk_gpll_div6", "clk_cpll_div10", "clk_cpll_div20", "xin24m" }; +PNAME(mux_200m_150m_100m_24m_p) = { "clk_gpll_div6", "clk_gpll_div8", "clk_cpll_div10", "xin24m" }; PNAME(mux_400m_200m_100m_24m_p) = { "clk_gpll_div3", "clk_gpll_div6", "clk_cpll_div10", "xin24m" }; PNAME(mux_500m_250m_100m_24m_p) = { "clk_cpll_div2", "clk_cpll_div4", "clk_cpll_div10", "xin24m" }; PNAME(mux_600m_400m_300m_24m_p) = { "clk_gpll_div2", "clk_gpll_div3", "clk_gpll_div4", "xin24m" }; @@ -706,19 +707,19 @@ static struct rockchip_clk_branch rk3576_clk_branches[] __initdata = { RK3576_CLKGATE_CON(16), 0, GFLAGS), GATE(PCLK_SPI4, "pclk_spi4", "pclk_bus_root", 0, RK3576_CLKGATE_CON(16), 1, GFLAGS), - COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_100m_50m_24m_p, 0, + COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_150m_100m_24m_p, 0, RK3576_CLKSEL_CON(70), 13, 2, MFLAGS, RK3576_CLKGATE_CON(16), 2, GFLAGS), - COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_100m_50m_24m_p, 0, + COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_150m_100m_24m_p, 0, RK3576_CLKSEL_CON(71), 0, 2, MFLAGS, RK3576_CLKGATE_CON(16), 3, GFLAGS), - COMPOSITE_NODIV(CLK_SPI2, "clk_spi2", mux_200m_100m_50m_24m_p, 0, + COMPOSITE_NODIV(CLK_SPI2, "clk_spi2", mux_200m_150m_100m_24m_p, 0, RK3576_CLKSEL_CON(71), 2, 2, MFLAGS, RK3576_CLKGATE_CON(16), 4, GFLAGS), - COMPOSITE_NODIV(CLK_SPI3, "clk_spi3", mux_200m_100m_50m_24m_p, 0, + COMPOSITE_NODIV(CLK_SPI3, "clk_spi3", mux_200m_150m_100m_24m_p, 0, RK3576_CLKSEL_CON(71), 4, 2, MFLAGS, RK3576_CLKGATE_CON(16), 5, GFLAGS), - COMPOSITE_NODIV(CLK_SPI4, "clk_spi4", mux_200m_100m_50m_24m_p, 0, + COMPOSITE_NODIV(CLK_SPI4, "clk_spi4", mux_200m_150m_100m_24m_p, 0, RK3576_CLKSEL_CON(71), 6, 2, MFLAGS, RK3576_CLKGATE_CON(16), 6, GFLAGS), GATE(PCLK_WDT0, "pclk_wdt0", "pclk_bus_root", 0, diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c index 86953f9ffee3..24baa0ef9bf3 100644 --- a/drivers/clk/rockchip/clk-rk3588.c +++ b/drivers/clk/rockchip/clk-rk3588.c @@ -79,14 +79,14 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = { RK3588_PLL_RATE(1008000000, 2, 336, 2, 0), RK3588_PLL_RATE(1000000000, 3, 500, 2, 0), RK3588_PLL_RATE(983040000, 4, 655, 2, 23592), - RK3588_PLL_RATE(955520000, 3, 477, 2, 49806), + RK3588_PLL_RATE(955520000, 3, 478, 2, -15730), RK3588_PLL_RATE(903168000, 6, 903, 2, 11009), RK3588_PLL_RATE(900000000, 2, 300, 2, 0), RK3588_PLL_RATE(850000000, 3, 425, 2, 0), RK3588_PLL_RATE(816000000, 2, 272, 2, 0), RK3588_PLL_RATE(786432000, 2, 262, 2, 9437), RK3588_PLL_RATE(786000000, 1, 131, 2, 0), - RK3588_PLL_RATE(785560000, 3, 392, 2, 51117), + RK3588_PLL_RATE(785560000, 3, 393, 2, -14419), RK3588_PLL_RATE(722534400, 8, 963, 2, 24850), RK3588_PLL_RATE(600000000, 2, 200, 2, 0), RK3588_PLL_RATE(594000000, 2, 198, 2, 0), @@ -2102,7 +2102,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { COMPOSITE(DCLK_VOP1_SRC, "dclk_vop1_src", gpll_cpll_v0pll_aupll_p, 0, RK3588_CLKSEL_CON(111), 14, 2, MFLAGS, 9, 5, DFLAGS, RK3588_CLKGATE_CON(52), 11, GFLAGS), - COMPOSITE(DCLK_VOP2_SRC, "dclk_vop2_src", gpll_cpll_v0pll_aupll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + COMPOSITE(DCLK_VOP2_SRC, "dclk_vop2_src", gpll_cpll_v0pll_aupll_p, 0, RK3588_CLKSEL_CON(112), 5, 2, MFLAGS, 0, 5, DFLAGS, RK3588_CLKGATE_CON(52), 12, GFLAGS), COMPOSITE_NODIV(DCLK_VOP0, "dclk_vop0", dclk_vop0_p, diff --git a/drivers/clk/rockchip/clk-rv1106.c b/drivers/clk/rockchip/clk-rv1106.c new file mode 100644 index 000000000000..3f26573e6cb7 --- /dev/null +++ b/drivers/clk/rockchip/clk-rv1106.c @@ -0,0 +1,1099 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Rockchip Electronics Co. Ltd. + * Author: Elaine Zhang + */ + +#include +#include +#include +#include +#include +#include "clk.h" + +/* + * Register offsets inside the CRU region. The RV1106 CRU is split into + * several sub-blocks, one per power domain, all accessed through a + * single register window. + */ +#define RV1106_TOPCRU_BASE 0x10000 +#define RV1106_PERICRU_BASE 0x12000 +#define RV1106_VICRU_BASE 0x14000 +#define RV1106_NPUCRU_BASE 0x16000 +#define RV1106_CORECRU_BASE 0x18000 +#define RV1106_VEPUCRU_BASE 0x1a000 +#define RV1106_VOCRU_BASE 0x1c000 +#define RV1106_DDRCRU_BASE 0x1e000 +#define RV1106_SUBDDRCRU_BASE 0x1f000 + +#define RV1106_PMUCLKSEL_CON(x) ((x) * 0x4 + 0x300) +#define RV1106_PMUCLKGATE_CON(x) ((x) * 0x4 + 0x800) +#define RV1106_PLL_CON(x) ((x) * 0x4 + RV1106_TOPCRU_BASE) +#define RV1106_MODE_CON (0x280 + RV1106_TOPCRU_BASE) +#define RV1106_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_TOPCRU_BASE) +#define RV1106_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_TOPCRU_BASE) +#define RV1106_GLB_SRST_FST (0xc08 + RV1106_TOPCRU_BASE) +#define RV1106_PERICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_PERICRU_BASE) +#define RV1106_PERICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_PERICRU_BASE) +#define RV1106_VICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_VICRU_BASE) +#define RV1106_VICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_VICRU_BASE) +#define RV1106_NPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_NPUCRU_BASE) +#define RV1106_NPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_NPUCRU_BASE) +#define RV1106_CORECLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_CORECRU_BASE) +#define RV1106_CORECLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_CORECRU_BASE) +#define RV1106_VEPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_VEPUCRU_BASE) +#define RV1106_VEPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_VEPUCRU_BASE) +#define RV1106_VOCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_VOCRU_BASE) +#define RV1106_VOCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_VOCRU_BASE) +#define RV1106_DDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_DDRCRU_BASE) +#define RV1106_DDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_DDRCRU_BASE) +#define RV1106_SUBDDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_SUBDDRCRU_BASE) +#define RV1106_SUBDDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_SUBDDRCRU_BASE) +#define RV1106_SUBDDRMODE_CON (0x280 + RV1106_SUBDDRCRU_BASE) + +/* Register offsets inside the GRF region for the MMC phase clocks */ +#define RV1106_VI_GRF_BASE 0x50000 +#define RV1106_VO_GRF_BASE 0x60000 + +#define RV1106_EMMC_CON0 0x20 +#define RV1106_EMMC_CON1 0x24 +#define RV1106_SDMMC_CON0 (0x4 + RV1106_VI_GRF_BASE) +#define RV1106_SDMMC_CON1 (0x8 + RV1106_VI_GRF_BASE) +#define RV1106_SDIO_CON0 (0x1c + RV1106_VO_GRF_BASE) +#define RV1106_SDIO_CON1 (0x20 + RV1106_VO_GRF_BASE) + +#define CRU_PVTPLL0_CON0_L 0x11000 +#define CRU_PVTPLL0_CON0_H 0x11004 +#define CRU_PVTPLL0_CON1_L 0x11008 +#define CRU_PVTPLL0_CON2_H 0x11014 + +#define CRU_PVTPLL1_CON0_L 0x11030 +#define CRU_PVTPLL1_CON0_H 0x11034 +#define CRU_PVTPLL1_CON1_L 0x11038 +#define CRU_PVTPLL1_CON2_H 0x11044 + +#define RV1106_GRF_SOC_STATUS0 0x10 +#define CPU_PVTPLL_CON0_L 0x40000 +#define CPU_PVTPLL_CON0_H 0x40004 + +#define PVTPLL_RING_SEL_MASK 0x7 +#define PVTPLL_RING_SEL_SHIFT 8 +#define PVTPLL_EN_MASK 0x3 +#define PVTPLL_EN_SHIFT 0 +#define PVTPLL_LENGTH_SEL_MASK 0x7f +#define PVTPLL_LENGTH_SEL_SHIFT 0 + +#define CPU_CLK_PATH_BASE RV1106_CORECLKSEL_CON(0) +#define CPU_PVTPLL_PATH_CORE (BIT(12) | BIT(28)) + +#define RV1106_FRAC_MAX_PRATE 1200000000 + +enum rv1106_plls { + apll, dpll, cpll, gpll, +}; + +static struct rockchip_pll_rate_table rv1106_pll_rates[] = { + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), + RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0), + RK3036_PLL_RATE(1584000000, 1, 132, 2, 1, 1, 0), + RK3036_PLL_RATE(1560000000, 1, 130, 2, 1, 1, 0), + RK3036_PLL_RATE(1536000000, 1, 128, 2, 1, 1, 0), + RK3036_PLL_RATE(1512000000, 1, 126, 2, 1, 1, 0), + RK3036_PLL_RATE(1488000000, 1, 124, 2, 1, 1, 0), + RK3036_PLL_RATE(1464000000, 1, 122, 2, 1, 1, 0), + RK3036_PLL_RATE(1440000000, 1, 120, 2, 1, 1, 0), + RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0), + RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0), + RK3036_PLL_RATE(1392000000, 1, 116, 2, 1, 1, 0), + RK3036_PLL_RATE(1368000000, 1, 114, 2, 1, 1, 0), + RK3036_PLL_RATE(1344000000, 1, 112, 2, 1, 1, 0), + RK3036_PLL_RATE(1320000000, 1, 110, 2, 1, 1, 0), + RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0), + RK3036_PLL_RATE(1272000000, 1, 106, 2, 1, 1, 0), + RK3036_PLL_RATE(1248000000, 1, 104, 2, 1, 1, 0), + RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0), + RK3036_PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0), + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), + RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0), + RK3036_PLL_RATE(993484800, 1, 124, 3, 1, 0, 3113851), + RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0), + RK3036_PLL_RATE(983040000, 1, 81, 2, 1, 0, 15435038), + RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0), + RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0), + RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), + RK3036_PLL_RATE(900000000, 1, 75, 2, 1, 1, 0), + RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0), + RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0), + RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0), + RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), + RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0), + RK3036_PLL_RATE(700000000, 3, 350, 4, 1, 1, 0), + RK3036_PLL_RATE(696000000, 1, 116, 4, 1, 1, 0), + RK3036_PLL_RATE(624000000, 1, 104, 4, 1, 1, 0), + RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0), + RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0), + RK3036_PLL_RATE(504000000, 1, 84, 4, 1, 1, 0), + RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0), + RK3036_PLL_RATE(496742400, 1, 124, 6, 1, 0, 3113851), + RK3036_PLL_RATE(491520000, 1, 40, 2, 1, 0, 16106127), + RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), + RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0), + RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), + RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0), + { /* sentinel */ }, +}; + +#define RV1106_DIV_ACLK_CORE_MASK 0x1f +#define RV1106_DIV_ACLK_CORE_SHIFT 7 +#define RV1106_DIV_PCLK_DBG_MASK 0x1f +#define RV1106_DIV_PCLK_DBG_SHIFT 0 +#define RV1106_CORE_SEL_MASK 0x3 +#define RV1106_CORE_SEL_SHIFT 5 + +#define RV1106_CLKSEL0(_aclk_core) \ +{ \ + .reg = RV1106_CORECLKSEL_CON(0), \ + .val = HIWORD_UPDATE(_aclk_core, RV1106_DIV_ACLK_CORE_MASK, \ + RV1106_DIV_ACLK_CORE_SHIFT), \ +} + +#define RV1106_CLKSEL1(_pclk_dbg) \ +{ \ + .reg = RV1106_CORECLKSEL_CON(1), \ + .val = HIWORD_UPDATE(_pclk_dbg, RV1106_DIV_PCLK_DBG_MASK, \ + RV1106_DIV_PCLK_DBG_SHIFT), \ +} + +#define RV1106_CLKSEL2(_is_pvtpll) \ +{ \ + .reg = RV1106_CORECLKSEL_CON(0), \ + .val = HIWORD_UPDATE(_is_pvtpll, RV1106_CORE_SEL_MASK, \ + RV1106_CORE_SEL_SHIFT), \ +} + +#define RV1106_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg, _is_pvtpll) \ +{ \ + .prate = _prate, \ + .divs = { \ + RV1106_CLKSEL0(_aclk_core), \ + RV1106_CLKSEL1(_pclk_dbg), \ + }, \ + .post_muxs = { \ + RV1106_CLKSEL2(_is_pvtpll), \ + }, \ +} + +static struct rockchip_cpuclk_rate_table rv1106_cpuclk_rates[] __initdata = { + RV1106_CPUCLK_RATE(1608000000, 3, 7, 1), + RV1106_CPUCLK_RATE(1584000000, 3, 7, 1), + RV1106_CPUCLK_RATE(1560000000, 3, 7, 1), + RV1106_CPUCLK_RATE(1536000000, 3, 7, 1), + RV1106_CPUCLK_RATE(1512000000, 3, 7, 1), + RV1106_CPUCLK_RATE(1488000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1464000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1440000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1416000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1392000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1368000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1344000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1320000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1296000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1272000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1248000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1224000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1200000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1104000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1096000000, 2, 5, 1), + RV1106_CPUCLK_RATE(1008000000, 1, 5, 1), + RV1106_CPUCLK_RATE(912000000, 1, 5, 1), + RV1106_CPUCLK_RATE(816000000, 1, 3, 1), + RV1106_CPUCLK_RATE(696000000, 1, 3, 0), + RV1106_CPUCLK_RATE(600000000, 1, 3, 0), + RV1106_CPUCLK_RATE(408000000, 1, 1, 0), + RV1106_CPUCLK_RATE(312000000, 1, 1, 0), + RV1106_CPUCLK_RATE(216000000, 1, 1, 0), + RV1106_CPUCLK_RATE(96000000, 1, 1, 0), +}; + +static const struct rockchip_cpuclk_reg_data rv1106_cpuclk_data = { + .core_reg[0] = RV1106_CORECLKSEL_CON(0), + .div_core_shift[0] = 0, + .div_core_mask[0] = 0x1f, + .num_cores = 1, + .mux_core_alt = 2, + .mux_core_main = 0, + .mux_core_shift = 5, + .mux_core_mask = 0x3, +}; + +PNAME(mux_pll_p) = { "xin24m" }; +PNAME(mux_armclk_p) = { "apll", "cpu_pvtpll", "gpll" }; +PNAME(mux_24m_32k_p) = { "xin24m", "clk_rtc_32k" }; +PNAME(mux_gpll_cpll_p) = { "gpll", "cpll" }; +PNAME(mux_gpll_24m_p) = { "gpll", "xin24m" }; +PNAME(mux_100m_50m_24m_p) = { "clk_100m_src", "clk_50m_src", "xin24m" }; +PNAME(mux_150m_100m_50m_24m_p) = { "clk_150m_src", "clk_100m_src", "clk_50m_src", "xin24m" }; +PNAME(mux_500m_300m_100m_24m_p) = { "clk_500m_src", "clk_300m_src", "clk_100m_src", "xin24m" }; +PNAME(mux_400m_300m_pvtpll0_pvtpll1_p) = { "clk_400m_src", "clk_300m_src", "clk_pvtpll_0", "clk_pvtpll_1" }; +PNAME(mux_500m_300m_pvtpll0_pvtpll1_p) = { "clk_500m_src", "clk_300m_src", "clk_pvtpll_0", "clk_pvtpll_1" }; +PNAME(mux_339m_200m_pvtpll0_pvtpll1_p) = { "clk_339m_src", "clk_200m_src", "clk_pvtpll_0", "clk_pvtpll_1" }; +PNAME(mux_400m_200m_100m_24m_p) = { "clk_400m_src", "clk_200m_src", "clk_100m_src", "xin24m" }; +PNAME(mux_200m_100m_50m_24m_p) = { "clk_200m_src", "clk_100m_src", "clk_50m_src", "xin24m" }; +PNAME(mux_300m_200m_100m_24m_p) = { "clk_300m_src", "clk_200m_src", "clk_100m_src", "xin24m" }; +PNAME(mux_500m_300m_200m_24m_p) = { "clk_500m_src", "clk_300m_src", "clk_200m_src", "xin24m" }; +PNAME(mux_50m_24m_p) = { "clk_50m_src", "xin24m" }; +PNAME(mux_400m_24m_p) = { "clk_400m_src", "xin24m" }; +PNAME(clk_rtc32k_pmu_p) = { "clk_rtc32k_frac", "xin32k", "clk_pvtm_32k" }; +PNAME(mux_200m_100m_24m_32k_p) = { "clk_200m_src", "clk_100m_src", "xin24m", "clk_rtc_32k" }; +PNAME(mux_100m_pmu_24m_p) = { "clk_100m_pmu", "xin24m" }; +PNAME(mux_200m_100m_24m_p) = { "clk_200m_src", "clk_100m_pmu", "xin24m" }; +PNAME(mux_339m_200m_100m_24m_p) = { "clk_339m_src", "clk_200m_src", "clk_100m_pmu", "xin24m" }; +PNAME(mux_dpll_300m_p) = { "dpll", "clk_300m_src" }; +PNAME(clk_i2s0_8ch_tx_p) = { "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_frac", "i2s0_mclkin", "xin_osc0_half" }; +PNAME(clk_i2s0_8ch_rx_p) = { "clk_i2s0_8ch_rx_src", "clk_i2s0_8ch_rx_frac", "i2s0_mclkin", "xin_osc0_half" }; +PNAME(i2s0_8ch_mclkout_p) = { "mclk_i2s0_8ch_tx", "mclk_i2s0_8ch_rx", "xin_osc0_half" }; +PNAME(clk_ref_mipi0_p) = { "clk_ref_mipi0_src", "clk_ref_mipi0_frac", "xin24m" }; +PNAME(clk_ref_mipi1_p) = { "clk_ref_mipi1_src", "clk_ref_mipi1_frac", "xin24m" }; +PNAME(clk_uart0_p) = { "clk_uart0_src", "clk_uart0_frac", "xin24m" }; +PNAME(clk_uart1_p) = { "clk_uart1_src", "clk_uart1_frac", "xin24m" }; +PNAME(clk_uart2_p) = { "clk_uart2_src", "clk_uart2_frac", "xin24m" }; +PNAME(clk_uart3_p) = { "clk_uart3_src", "clk_uart3_frac", "xin24m" }; +PNAME(clk_uart4_p) = { "clk_uart4_src", "clk_uart4_frac", "xin24m" }; +PNAME(clk_uart5_p) = { "clk_uart5_src", "clk_uart5_frac", "xin24m" }; +PNAME(clk_vicap_m0_p) = { "clk_vicap_m0_src", "clk_vicap_m0_frac", "xin24m" }; +PNAME(clk_vicap_m1_p) = { "clk_vicap_m1_src", "clk_vicap_m1_frac", "xin24m" }; + +static struct rockchip_pll_clock rv1106_pll_clks[] __initdata = { + [apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p, + CLK_IGNORE_UNUSED, RV1106_PLL_CON(0), + RV1106_MODE_CON, 0, 10, 0, rv1106_pll_rates), + [cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p, + 0, RV1106_PLL_CON(8), + RV1106_MODE_CON, 2, 10, 0, rv1106_pll_rates), + [dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p, + CLK_IGNORE_UNUSED, RV1106_PLL_CON(16), + RV1106_SUBDDRMODE_CON, 0, 10, 0, NULL), + [gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p, + 0, RV1106_PLL_CON(24), + RV1106_MODE_CON, 4, 10, 0, rv1106_pll_rates), +}; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) + +static struct rockchip_clk_branch rv1106_rtc32k_pmu_fracmux __initdata = + MUX(CLK_RTC_32K, "clk_rtc_32k", clk_rtc32k_pmu_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + RV1106_PMUCLKSEL_CON(0), 6, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_i2s0_8ch_tx_fracmux __initdata = + MUX(CLK_I2S0_8CH_TX, "clk_i2s0_8ch_tx", clk_i2s0_8ch_tx_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(19), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_i2s0_8ch_rx_fracmux __initdata = + MUX(CLK_I2S0_8CH_RX, "clk_i2s0_8ch_rx", clk_i2s0_8ch_rx_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(21), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_clk_ref_mipi0_fracmux __initdata = + MUX(CLK_REF_MIPI0, "clk_ref_mipi0", clk_ref_mipi0_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(27), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_clk_ref_mipi1_fracmux __initdata = + MUX(CLK_REF_MIPI1, "clk_ref_mipi1", clk_ref_mipi1_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(29), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_clk_uart0_fracmux __initdata = + MUX(CLK_UART0, "clk_uart0", clk_uart0_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(7), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_clk_uart1_fracmux __initdata = + MUX(CLK_UART1, "clk_uart1", clk_uart1_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(9), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_clk_uart2_fracmux __initdata = + MUX(CLK_UART2, "clk_uart2", clk_uart2_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(11), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_clk_uart3_fracmux __initdata = + MUX(CLK_UART3, "clk_uart3", clk_uart3_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(13), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_clk_uart4_fracmux __initdata = + MUX(CLK_UART4, "clk_uart4", clk_uart4_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(15), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_clk_uart5_fracmux __initdata = + MUX(CLK_UART5, "clk_uart5", clk_uart5_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(17), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_clk_vicap_m0_fracmux __initdata = + MUX(CLK_VICAP_M0, "clk_vicap_m0", clk_vicap_m0_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(31), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_clk_vicap_m1_fracmux __initdata = + MUX(CLK_VICAP_M1, "clk_vicap_m1", clk_vicap_m1_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(33), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rv1106_clk_branches[] __initdata = { + + FACTOR(XIN_OSC0_HALF, "xin_osc0_half", "xin24m", 0, 1, 2), + + /* PD_CORE */ + GATE(CLK_PVTM_CORE, "clk_pvtm_core", "xin24m", 0, + RV1106_CORECLKGATE_CON(0), 14, GFLAGS), + GATE(CLK_CORE_MCU_RTC, "clk_core_mcu_rtc", "xin24m", 0, + RV1106_CORECLKGATE_CON(1), 6, GFLAGS), + COMPOSITE(HCLK_CPU, "hclk_cpu", mux_gpll_24m_p, CLK_IS_CRITICAL, + RV1106_CORECLKSEL_CON(2), 5, 1, MFLAGS, 0, 5, DFLAGS, + RV1106_CORECLKGATE_CON(0), 12, GFLAGS), + COMPOSITE(CLK_CORE_MCU, "clk_core_mcu", mux_gpll_24m_p, 0, + RV1106_CORECLKSEL_CON(3), 11, 1, MFLAGS, 6, 5, DFLAGS, + RV1106_CORECLKGATE_CON(1), 1, GFLAGS), + COMPOSITE_NOMUX(PCLK_DBG, "pclk_dbg", "armclk", CLK_IS_CRITICAL, + RV1106_CORECLKSEL_CON(1), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RV1106_CORECLKGATE_CON(0), 6, GFLAGS), + GATE(PCLK_CPU_ROOT, "pclk_cpu_root", "pclk_dbg", CLK_IS_CRITICAL, + RV1106_CORECLKGATE_CON(0), 10, GFLAGS), + GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_cpu_root", 0, + RV1106_CORECLKGATE_CON(1), 8, GFLAGS), + + /* PD _TOP */ + COMPOSITE(CLK_50M_SRC, "clk_50m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1106_CLKSEL_CON(0), 5, 1, MFLAGS, 0, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 1, GFLAGS), + COMPOSITE(CLK_100M_SRC, "clk_100m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1106_CLKSEL_CON(0), 11, 1, MFLAGS, 6, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 2, GFLAGS), + COMPOSITE(CLK_150M_SRC, "clk_150m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1106_CLKSEL_CON(1), 5, 1, MFLAGS, 0, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 3, GFLAGS), + COMPOSITE(CLK_200M_SRC, "clk_200m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1106_CLKSEL_CON(1), 11, 1, MFLAGS, 6, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 4, GFLAGS), + COMPOSITE(CLK_250M_SRC, "clk_250m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1106_CLKSEL_CON(2), 5, 1, MFLAGS, 0, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 5, GFLAGS), + COMPOSITE(CLK_300M_SRC, "clk_300m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1106_CLKSEL_CON(2), 11, 1, MFLAGS, 6, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 6, GFLAGS), + COMPOSITE_HALFDIV(CLK_339M_SRC, "clk_339m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1106_CLKSEL_CON(3), 5, 1, MFLAGS, 0, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 7, GFLAGS), + COMPOSITE(CLK_400M_SRC, "clk_400m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1106_CLKSEL_CON(3), 11, 1, MFLAGS, 6, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_HALFDIV(CLK_450M_SRC, "clk_450m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1106_CLKSEL_CON(4), 5, 1, MFLAGS, 0, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 9, GFLAGS), + COMPOSITE(CLK_500M_SRC, "clk_500m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RV1106_CLKSEL_CON(4), 11, 1, MFLAGS, 6, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 10, GFLAGS), + + COMPOSITE_NODIV(PCLK_TOP_ROOT, "pclk_top_root", mux_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_CLKSEL_CON(24), 5, 2, MFLAGS, + RV1106_CLKGATE_CON(2), 9, GFLAGS), + + COMPOSITE(CLK_I2S0_8CH_TX_SRC, "clk_i2s0_8ch_tx_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(17), 7, 1, MFLAGS, 2, 5, DFLAGS, + RV1106_CLKGATE_CON(1), 13, GFLAGS), + COMPOSITE_FRACMUX(CLK_I2S0_8CH_TX_FRAC, "clk_i2s0_8ch_tx_frac", "clk_i2s0_8ch_tx_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(18), 0, + RV1106_CLKGATE_CON(1), 14, GFLAGS, + &rv1106_i2s0_8ch_tx_fracmux), + GATE(MCLK_I2S0_8CH_TX, "mclk_i2s0_8ch_tx", "clk_i2s0_8ch_tx", 0, + RV1106_CLKGATE_CON(1), 15, GFLAGS), + COMPOSITE(CLK_I2S0_8CH_RX_SRC, "clk_i2s0_8ch_rx_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(19), 7, 1, MFLAGS, 2, 5, DFLAGS, + RV1106_CLKGATE_CON(2), 0, GFLAGS), + COMPOSITE_FRACMUX(CLK_I2S0_8CH_RX_FRAC, "clk_i2s0_8ch_rx_frac", "clk_i2s0_8ch_rx_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(20), 0, + RV1106_CLKGATE_CON(2), 1, GFLAGS, + &rv1106_i2s0_8ch_rx_fracmux), + GATE(MCLK_I2S0_8CH_RX, "mclk_i2s0_8ch_rx", "clk_i2s0_8ch_rx", 0, + RV1106_CLKGATE_CON(2), 2, GFLAGS), + MUX(I2S0_8CH_MCLKOUT, "i2s0_8ch_mclkout", i2s0_8ch_mclkout_p, CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(21), 2, 2, MFLAGS), + COMPOSITE(CLK_REF_MIPI0_SRC, "clk_ref_mipi0_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(25), 7, 1, MFLAGS, 2, 5, DFLAGS, + RV1106_CLKGATE_CON(3), 4, GFLAGS), + COMPOSITE_FRACMUX(CLK_REF_MIPI0_FRAC, "clk_ref_mipi0_frac", "clk_ref_mipi0_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(26), 0, + RV1106_CLKGATE_CON(3), 5, GFLAGS, + &rv1106_clk_ref_mipi0_fracmux), + GATE(MCLK_REF_MIPI0, "mclk_ref_mipi0", "clk_ref_mipi0", 0, + RV1106_CLKGATE_CON(3), 6, GFLAGS), + COMPOSITE(CLK_REF_MIPI1_SRC, "clk_ref_mipi1_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(27), 7, 1, MFLAGS, 2, 5, DFLAGS, + RV1106_CLKGATE_CON(3), 7, GFLAGS), + COMPOSITE_FRACMUX(CLK_REF_MIPI1_FRAC, "clk_ref_mipi1_frac", "clk_ref_mipi1_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(28), 0, + RV1106_CLKGATE_CON(3), 8, GFLAGS, + &rv1106_clk_ref_mipi1_fracmux), + GATE(MCLK_REF_MIPI1, "mclk_ref_mipi1", "clk_ref_mipi1", 0, + RV1106_CLKGATE_CON(3), 9, GFLAGS), + COMPOSITE(CLK_UART0_SRC, "clk_uart0_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(5), 5, 1, MFLAGS, 0, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 11, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART0_FRAC, "clk_uart0_frac", "clk_uart0_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(6), 0, + RV1106_CLKGATE_CON(0), 12, GFLAGS, + &rv1106_clk_uart0_fracmux), + GATE(SCLK_UART0, "sclk_uart0", "clk_uart0", 0, + RV1106_CLKGATE_CON(0), 13, GFLAGS), + COMPOSITE(CLK_UART1_SRC, "clk_uart1_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(7), 7, 1, MFLAGS, 2, 5, DFLAGS, + RV1106_CLKGATE_CON(0), 14, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(8), 0, + RV1106_CLKGATE_CON(0), 15, GFLAGS, + &rv1106_clk_uart1_fracmux), + GATE(SCLK_UART1, "sclk_uart1", "clk_uart1", 0, + RV1106_CLKGATE_CON(1), 0, GFLAGS), + COMPOSITE(CLK_UART2_SRC, "clk_uart2_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(9), 7, 1, MFLAGS, 2, 5, DFLAGS, + RV1106_CLKGATE_CON(1), 1, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(10), 0, + RV1106_CLKGATE_CON(1), 2, GFLAGS, + &rv1106_clk_uart2_fracmux), + GATE(SCLK_UART2, "sclk_uart2", "clk_uart2", 0, + RV1106_CLKGATE_CON(1), 3, GFLAGS), + COMPOSITE(CLK_UART3_SRC, "clk_uart3_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(11), 7, 1, MFLAGS, 2, 5, DFLAGS, + RV1106_CLKGATE_CON(1), 4, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(12), 0, + RV1106_CLKGATE_CON(1), 5, GFLAGS, + &rv1106_clk_uart3_fracmux), + GATE(SCLK_UART3, "sclk_uart3", "clk_uart3", 0, + RV1106_CLKGATE_CON(1), 6, GFLAGS), + COMPOSITE(CLK_UART4_SRC, "clk_uart4_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(13), 7, 1, MFLAGS, 2, 5, DFLAGS, + RV1106_CLKGATE_CON(1), 7, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART4_FRAC, "clk_uart4_frac", "clk_uart4_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(14), 0, + RV1106_CLKGATE_CON(1), 8, GFLAGS, + &rv1106_clk_uart4_fracmux), + GATE(SCLK_UART4, "sclk_uart4", "clk_uart4", 0, + RV1106_CLKGATE_CON(1), 9, GFLAGS), + COMPOSITE(CLK_UART5_SRC, "clk_uart5_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(15), 7, 1, MFLAGS, 2, 5, DFLAGS, + RV1106_CLKGATE_CON(1), 10, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART5_FRAC, "clk_uart5_frac", "clk_uart5_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(16), 0, + RV1106_CLKGATE_CON(1), 11, GFLAGS, + &rv1106_clk_uart5_fracmux), + GATE(SCLK_UART5, "sclk_uart5", "clk_uart5", 0, + RV1106_CLKGATE_CON(1), 12, GFLAGS), + COMPOSITE(CLK_VICAP_M0_SRC, "clk_vicap_m0_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(29), 7, 1, MFLAGS, 2, 5, DFLAGS, + RV1106_CLKGATE_CON(3), 10, GFLAGS), + COMPOSITE_FRACMUX(CLK_VICAP_M0_FRAC, "clk_vicap_m0_frac", "clk_vicap_m0_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(30), 0, + RV1106_CLKGATE_CON(3), 11, GFLAGS, + &rv1106_clk_vicap_m0_fracmux), + GATE(SCLK_VICAP_M0, "sclk_vicap_m0", "clk_vicap_m0", 0, + RV1106_CLKGATE_CON(3), 12, GFLAGS), + COMPOSITE(CLK_VICAP_M1_SRC, "clk_vicap_m1_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(31), 7, 1, MFLAGS, 2, 5, DFLAGS, + RV1106_CLKGATE_CON(3), 13, GFLAGS), + COMPOSITE_FRACMUX(CLK_VICAP_M1_FRAC, "clk_vicap_m1_frac", "clk_vicap_m1_src", CLK_SET_RATE_PARENT, + RV1106_CLKSEL_CON(32), 0, + RV1106_CLKGATE_CON(3), 14, GFLAGS, + &rv1106_clk_vicap_m1_fracmux), + GATE(SCLK_VICAP_M1, "sclk_vicap_m1", "clk_vicap_m1", 0, + RV1106_CLKGATE_CON(3), 15, GFLAGS), + COMPOSITE(DCLK_VOP_SRC, "dclk_vop_src", mux_gpll_cpll_p, 0, + RV1106_CLKSEL_CON(23), 8, 1, MFLAGS, 3, 5, DFLAGS, + RV1106_CLKGATE_CON(2), 6, GFLAGS), + + /* PD_DDR */ + COMPOSITE_NODIV(PCLK_DDR_ROOT, "pclk_ddr_root", mux_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_DDRCLKSEL_CON(0), 0, 2, MFLAGS, + RV1106_DDRCLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NODIV(ACLK_DDR_ROOT, "aclk_ddr_root", mux_500m_300m_100m_24m_p, CLK_IS_CRITICAL, + RV1106_DDRCLKSEL_CON(0), 8, 2, MFLAGS, + RV1106_DDRCLKGATE_CON(0), 12, GFLAGS), + GATE(PCLK_DDRPHY, "pclk_ddrphy", "pclk_ddr_root", CLK_IGNORE_UNUSED, + RV1106_DDRCLKGATE_CON(1), 3, GFLAGS), + GATE(PCLK_DDR_HWLP, "pclk_ddr_hwlp", "pclk_ddr_root", CLK_IGNORE_UNUSED, + RV1106_DDRCLKGATE_CON(1), 2, GFLAGS), + GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_ddr_root", 0, + RV1106_DDRCLKGATE_CON(0), 7, GFLAGS), + GATE(CLK_TIMER_DDRMON, "clk_timer_ddrmon", "xin24m", 0, + RV1106_DDRCLKGATE_CON(0), 8, GFLAGS), + GATE(PCLK_DDRC, "pclk_ddrc", "pclk_ddr_root", CLK_IGNORE_UNUSED, + RV1106_DDRCLKGATE_CON(0), 5, GFLAGS), + GATE(PCLK_DFICTRL, "pclk_dfictrl", "pclk_ddr_root", CLK_IS_CRITICAL, + RV1106_DDRCLKGATE_CON(0), 11, GFLAGS), + GATE(ACLK_SYS_SHRM, "aclk_sys_shrm", "aclk_ddr_root", CLK_IS_CRITICAL, + RV1106_DDRCLKGATE_CON(0), 13, GFLAGS), + + /* PD_NPU */ + COMPOSITE_NODIV(HCLK_NPU_ROOT, "hclk_npu_root", mux_150m_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_NPUCLKSEL_CON(0), 0, 2, MFLAGS, + RV1106_NPUCLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NODIV(ACLK_NPU_ROOT, "aclk_npu_root", mux_500m_300m_pvtpll0_pvtpll1_p, CLK_IS_CRITICAL, + RV1106_NPUCLKSEL_CON(0), 2, 2, MFLAGS, + RV1106_NPUCLKGATE_CON(0), 1, GFLAGS), + COMPOSITE_NODIV(PCLK_NPU_ROOT, "pclk_npu_root", mux_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_NPUCLKSEL_CON(0), 4, 2, MFLAGS, + RV1106_NPUCLKGATE_CON(0), 2, GFLAGS), + GATE(HCLK_RKNN, "hclk_rknn", "hclk_npu_root", 0, + RV1106_NPUCLKGATE_CON(0), 9, GFLAGS), + GATE(ACLK_RKNN, "aclk_rknn", "aclk_npu_root", 0, + RV1106_NPUCLKGATE_CON(0), 10, GFLAGS), + + /* PD_PERI */ + COMPOSITE_NODIV(PCLK_PERI_ROOT, "pclk_peri_root", mux_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_PERICLKSEL_CON(1), 0, 2, MFLAGS, + RV1106_PERICLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NODIV(ACLK_PERI_ROOT, "aclk_peri_root", mux_400m_200m_100m_24m_p, CLK_IS_CRITICAL, + RV1106_PERICLKSEL_CON(1), 2, 2, MFLAGS, + RV1106_PERICLKGATE_CON(0), 1, GFLAGS), + COMPOSITE_NODIV(HCLK_PERI_ROOT, "hclk_peri_root", mux_200m_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_PERICLKSEL_CON(1), 4, 2, MFLAGS, + RV1106_PERICLKGATE_CON(0), 2, GFLAGS), + COMPOSITE_NODIV(ACLK_BUS_ROOT, "aclk_bus_root", mux_300m_200m_100m_24m_p, CLK_IS_CRITICAL, + RV1106_PERICLKSEL_CON(9), 0, 2, MFLAGS, + RV1106_PERICLKGATE_CON(6), 8, GFLAGS), + GATE(PCLK_ACODEC, "pclk_acodec", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(6), 3, GFLAGS), + COMPOSITE_NOMUX(MCLK_ACODEC_TX, "mclk_acodec_tx", "mclk_i2s0_8ch_tx", 0, + RV1106_PERICLKSEL_CON(8), 0, 8, DFLAGS, + RV1106_PERICLKGATE_CON(6), 4, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_CRYPTO, "clk_core_crypto", mux_300m_200m_100m_24m_p, 0, + RV1106_PERICLKSEL_CON(6), 5, 2, MFLAGS, + RV1106_PERICLKGATE_CON(3), 11, GFLAGS), + COMPOSITE_NODIV(CLK_PKA_CRYPTO, "clk_pka_crypto", mux_300m_200m_100m_24m_p, 0, + RV1106_PERICLKSEL_CON(6), 7, 2, MFLAGS, + RV1106_PERICLKGATE_CON(3), 12, GFLAGS), + GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_bus_root", 0, + RV1106_PERICLKGATE_CON(3), 13, GFLAGS), + GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_peri_root", 0, + RV1106_PERICLKGATE_CON(3), 14, GFLAGS), + GATE(ACLK_DECOM, "aclk_decom", "aclk_peri_root", 0, + RV1106_PERICLKGATE_CON(5), 9, GFLAGS), + GATE(PCLK_DECOM, "pclk_decom", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(5), 10, GFLAGS), + COMPOSITE_NODIV(DCLK_DECOM, "dclk_decom", mux_400m_200m_100m_24m_p, 0, + RV1106_PERICLKSEL_CON(7), 14, 2, MFLAGS, + RV1106_PERICLKGATE_CON(5), 11, GFLAGS), + GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_root", 0, + RV1106_PERICLKGATE_CON(5), 8, GFLAGS), + GATE(PCLK_DSM, "pclk_dsm", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(6), 2, GFLAGS), + GATE(MCLK_DSM, "mclk_dsm", "mclk_i2s0_8ch_tx", 0, + RV1106_PERICLKGATE_CON(6), 1, GFLAGS), + COMPOSITE(CCLK_SRC_EMMC, "cclk_src_emmc", mux_400m_24m_p, 0, + RV1106_PERICLKSEL_CON(7), 6, 1, MFLAGS, 0, 6, DFLAGS, + RV1106_PERICLKGATE_CON(4), 12, GFLAGS), + GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri_root", 0, + RV1106_PERICLKGATE_CON(4), 13, GFLAGS), + GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(2), 0, GFLAGS), + GATE(DBCLK_GPIO4, "dbclk_gpio4", "xin24m", 0, + RV1106_PERICLKGATE_CON(2), 1, GFLAGS), + GATE(PCLK_I2C0, "pclk_i2c0", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(1), 6, GFLAGS), + COMPOSITE_NODIV(CLK_I2C0, "clk_i2c0", mux_200m_100m_50m_24m_p, 0, + RV1106_PERICLKSEL_CON(1), 8, 2, MFLAGS, + RV1106_PERICLKGATE_CON(1), 7, GFLAGS), + GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(1), 10, GFLAGS), + COMPOSITE_NODIV(CLK_I2C2, "clk_i2c2", mux_200m_100m_50m_24m_p, 0, + RV1106_PERICLKSEL_CON(1), 12, 2, MFLAGS, + RV1106_PERICLKGATE_CON(1), 11, GFLAGS), + GATE(PCLK_I2C3, "pclk_i2c3", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(1), 12, GFLAGS), + COMPOSITE_NODIV(CLK_I2C3, "clk_i2c3", mux_200m_100m_50m_24m_p, 0, + RV1106_PERICLKSEL_CON(1), 14, 2, MFLAGS, + RV1106_PERICLKGATE_CON(1), 13, GFLAGS), + GATE(PCLK_I2C4, "pclk_i2c4", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(1), 14, GFLAGS), + COMPOSITE_NODIV(CLK_I2C4, "clk_i2c4", mux_200m_100m_50m_24m_p, 0, + RV1106_PERICLKSEL_CON(2), 0, 2, MFLAGS, + RV1106_PERICLKGATE_CON(1), 15, GFLAGS), + GATE(HCLK_I2S0, "hclk_i2s0", "hclk_peri_root", 0, + RV1106_PERICLKGATE_CON(6), 0, GFLAGS), + GATE(PCLK_DFT2APB, "pclk_dft2apb", "pclk_peri_root", CLK_IGNORE_UNUSED, + RV1106_PERICLKGATE_CON(6), 7, GFLAGS), + GATE(HCLK_IVE, "hclk_ive", "hclk_peri_root", 0, + RV1106_PERICLKGATE_CON(6), 9, GFLAGS), + GATE(ACLK_IVE, "aclk_ive", "aclk_peri_root", 0, + RV1106_PERICLKGATE_CON(6), 10, GFLAGS), + GATE(PCLK_PWM0_PERI, "pclk_pwm0_peri", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(7), 3, GFLAGS), + COMPOSITE_NODIV(CLK_PWM0_PERI, "clk_pwm0_peri", mux_100m_50m_24m_p, 0, + RV1106_PERICLKSEL_CON(11), 0, 2, MFLAGS, + RV1106_PERICLKGATE_CON(7), 4, GFLAGS), + GATE(CLK_CAPTURE_PWM0_PERI, "clk_capture_pwm0_peri", "xin24m", 0, + RV1106_PERICLKGATE_CON(7), 5, GFLAGS), + GATE(CLK_TIMER_ROOT, "clk_timer_root", "xin24m", 0, + RV1106_PERICLKGATE_CON(0), 3, GFLAGS), + GATE(HCLK_SFC, "hclk_sfc", "hclk_peri_root", 0, + RV1106_PERICLKGATE_CON(4), 14, GFLAGS), + COMPOSITE(SCLK_SFC, "sclk_sfc", mux_500m_300m_200m_24m_p, 0, + RV1106_PERICLKSEL_CON(7), 12, 2, MFLAGS, 7, 5, DFLAGS, + RV1106_PERICLKGATE_CON(5), 0, GFLAGS), + GATE(PCLK_UART0, "pclk_uart0", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(6), 11, GFLAGS), + GATE(PCLK_UART1, "pclk_uart1", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(6), 15, GFLAGS), + GATE(PCLK_PWM1_PERI, "pclk_pwm1_peri", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(3), 15, GFLAGS), + COMPOSITE_NODIV(CLK_PWM1_PERI, "clk_pwm1_peri", mux_100m_50m_24m_p, 0, + RV1106_PERICLKSEL_CON(6), 9, 2, MFLAGS, + RV1106_PERICLKGATE_CON(4), 0, GFLAGS), + GATE(CLK_CAPTURE_PWM1_PERI, "clk_capture_pwm1_peri", "xin24m", 0, + RV1106_PERICLKGATE_CON(4), 1, GFLAGS), + GATE(PCLK_PWM2_PERI, "pclk_pwm2_peri", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(4), 2, GFLAGS), + COMPOSITE_NODIV(CLK_PWM2_PERI, "clk_pwm2_peri", mux_100m_50m_24m_p, 0, + RV1106_PERICLKSEL_CON(6), 11, 2, MFLAGS, + RV1106_PERICLKGATE_CON(4), 3, GFLAGS), + GATE(CLK_CAPTURE_PWM2_PERI, "clk_capture_pwm2_peri", "xin24m", 0, + RV1106_PERICLKGATE_CON(4), 4, GFLAGS), + GATE(HCLK_BOOTROM, "hclk_bootrom", "hclk_peri_root", 0, + RV1106_PERICLKGATE_CON(0), 7, GFLAGS), + GATE(HCLK_SAI, "hclk_sai", "hclk_peri_root", 0, + RV1106_PERICLKGATE_CON(5), 13, GFLAGS), + GATE(MCLK_SAI, "mclk_sai", "mclk_i2s0_8ch_tx", 0, + RV1106_PERICLKGATE_CON(5), 14, GFLAGS), + GATE(PCLK_SARADC, "pclk_saradc", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(3), 3, GFLAGS), + COMPOSITE_NOMUX(CLK_SARADC, "clk_saradc", "xin24m", 0, + RV1106_PERICLKSEL_CON(6), 0, 3, DFLAGS, + RV1106_PERICLKGATE_CON(3), 4, GFLAGS), + GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(3), 6, GFLAGS), + COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_100m_50m_24m_p, 0, + RV1106_PERICLKSEL_CON(6), 3, 2, MFLAGS, + RV1106_PERICLKGATE_CON(3), 7, GFLAGS), + GATE(PCLK_STIMER, "pclk_stimer", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(0), 15, GFLAGS), + GATE(CLK_STIMER0, "clk_stimer0", "clk_timer_root", 0, + RV1106_PERICLKGATE_CON(1), 0, GFLAGS), + GATE(CLK_STIMER1, "clk_stimer1", "clk_timer_root", 0, + RV1106_PERICLKGATE_CON(1), 1, GFLAGS), + GATE(PCLK_TIMER, "pclk_timer", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(0), 8, GFLAGS), + GATE(CLK_TIMER0, "clk_timer0", "clk_timer_root", 0, + RV1106_PERICLKGATE_CON(0), 9, GFLAGS), + GATE(CLK_TIMER1, "clk_timer1", "clk_timer_root", 0, + RV1106_PERICLKGATE_CON(0), 10, GFLAGS), + GATE(CLK_TIMER2, "clk_timer2", "clk_timer_root", 0, + RV1106_PERICLKGATE_CON(0), 11, GFLAGS), + GATE(CLK_TIMER3, "clk_timer3", "clk_timer_root", 0, + RV1106_PERICLKGATE_CON(0), 12, GFLAGS), + GATE(CLK_TIMER4, "clk_timer4", "clk_timer_root", 0, + RV1106_PERICLKGATE_CON(0), 13, GFLAGS), + GATE(CLK_TIMER5, "clk_timer5", "clk_timer_root", 0, + RV1106_PERICLKGATE_CON(0), 14, GFLAGS), + GATE(HCLK_TRNG_NS, "hclk_trng_ns", "hclk_peri_root", 0, + RV1106_PERICLKGATE_CON(3), 9, GFLAGS), + GATE(HCLK_TRNG_S, "hclk_trng_s", "hclk_peri_root", 0, + RV1106_PERICLKGATE_CON(3), 10, GFLAGS), + GATE(PCLK_UART2, "pclk_uart2", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(2), 3, GFLAGS), + GATE(PCLK_UART3, "pclk_uart3", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(2), 7, GFLAGS), + GATE(PCLK_UART4, "pclk_uart4", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(2), 11, GFLAGS), + GATE(PCLK_UART5, "pclk_uart5", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(2), 15, GFLAGS), + GATE(ACLK_USBOTG, "aclk_usbotg", "aclk_bus_root", 0, + RV1106_PERICLKGATE_CON(4), 7, GFLAGS), + GATE(CLK_REF_USBOTG, "clk_ref_usbotg", "xin24m", 0, + RV1106_PERICLKGATE_CON(4), 8, GFLAGS), + GATE(PCLK_USBPHY, "pclk_usbphy", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(5), 1, GFLAGS), + GATE(CLK_REF_USBPHY, "clk_ref_usbphy", "xin24m", 0, + RV1106_PERICLKGATE_CON(5), 2, GFLAGS), + GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(1), 2, GFLAGS), + GATE(TCLK_WDT_NS, "tclk_wdt_ns", "xin24m", 0, + RV1106_PERICLKGATE_CON(1), 3, GFLAGS), + GATE(PCLK_WDT_S, "pclk_wdt_s", "pclk_peri_root", 0, + RV1106_PERICLKGATE_CON(1), 4, GFLAGS), + GATE(TCLK_WDT_S, "tclk_wdt_s", "xin24m", 0, + RV1106_PERICLKGATE_CON(1), 5, GFLAGS), + + /* PD_PMU */ + COMPOSITE_FRACMUX(CLK_RTC32K_FRAC, "clk_rtc32k_frac", "xin24m", CLK_IGNORE_UNUSED, + RV1106_PMUCLKSEL_CON(6), 0, + RV1106_PMUCLKGATE_CON(1), 14, GFLAGS, + &rv1106_rtc32k_pmu_fracmux), + DIV(CLK_100M_PMU, "clk_100m_pmu", "clk_200m_src", 0, + RV1106_PMUCLKSEL_CON(0), 0, 3, DFLAGS), + COMPOSITE_NODIV(PCLK_PMU_ROOT, "pclk_pmu_root", mux_100m_pmu_24m_p, CLK_IS_CRITICAL, + RV1106_PMUCLKSEL_CON(0), 3, 1, MFLAGS, + RV1106_PMUCLKGATE_CON(0), 1, GFLAGS), + COMPOSITE_NODIV(HCLK_PMU_ROOT, "hclk_pmu_root", mux_200m_100m_24m_p, CLK_IS_CRITICAL, + RV1106_PMUCLKSEL_CON(0), 4, 2, MFLAGS, + RV1106_PMUCLKGATE_CON(0), 2, GFLAGS), + GATE(CLK_PMU, "clk_pmu", "xin24m", CLK_IS_CRITICAL, + RV1106_PMUCLKGATE_CON(1), 0, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_root", CLK_IS_CRITICAL, + RV1106_PMUCLKGATE_CON(1), 1, GFLAGS), + GATE(CLK_DDR_FAIL_SAFE, "clk_ddr_fail_safe", "clk_pmu", 0, + RV1106_PMUCLKGATE_CON(1), 15, GFLAGS), + GATE(PCLK_PMU_GPIO0, "pclk_pmu_gpio0", "pclk_pmu_root", 0, + RV1106_PMUCLKGATE_CON(1), 2, GFLAGS), + COMPOSITE_NODIV(DBCLK_PMU_GPIO0, "dbclk_pmu_gpio0", mux_24m_32k_p, 0, + RV1106_PMUCLKSEL_CON(0), 15, 1, MFLAGS, + RV1106_PMUCLKGATE_CON(1), 3, GFLAGS), + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_pmu_root", 0, + RV1106_PMUCLKGATE_CON(0), 3, GFLAGS), + COMPOSITE_NODIV(CLK_I2C1, "clk_i2c1", mux_200m_100m_24m_32k_p, 0, + RV1106_PMUCLKSEL_CON(0), 6, 2, MFLAGS, + RV1106_PMUCLKGATE_CON(0), 4, GFLAGS), + GATE(PCLK_PMU_MAILBOX, "pclk_pmu_mailbox", "pclk_pmu_root", 0, + RV1106_PMUCLKGATE_CON(2), 10, GFLAGS), + GATE(CLK_PMU_MCU, "clk_pmu_mcu", "hclk_pmu_root", 0, + RV1106_PMUCLKGATE_CON(0), 9, GFLAGS), + GATE(CLK_PMU_MCU_RTC, "clk_pmu_mcu_rtc", "xin24m", 0, + RV1106_PMUCLKGATE_CON(0), 13, GFLAGS), + COMPOSITE_NOMUX(CLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", 0, + RV1106_PMUCLKSEL_CON(1), 0, 5, DFLAGS, + RV1106_PMUCLKGATE_CON(1), 4, GFLAGS), + GATE(PCLK_PVTM_PMU, "pclk_pvtm_pmu", "pclk_pmu_root", 0, + RV1106_PMUCLKGATE_CON(1), 5, GFLAGS), + GATE(CLK_REFOUT, "clk_refout", "xin24m", 0, + RV1106_PMUCLKGATE_CON(2), 13, GFLAGS), + GATE(HCLK_PMU_SRAM, "hclk_pmu_sram", "hclk_pmu_root", CLK_IGNORE_UNUSED, + RV1106_PMUCLKGATE_CON(0), 8, GFLAGS), + GATE(PCLK_PMU_WDT, "pclk_pmu_wdt", "pclk_pmu_root", 0, + RV1106_PMUCLKGATE_CON(2), 8, GFLAGS), + COMPOSITE_NODIV(TCLK_PMU_WDT, "tclk_pmu_wdt", mux_24m_32k_p, 0, + RV1106_PMUCLKSEL_CON(7), 2, 1, MFLAGS, + RV1106_PMUCLKGATE_CON(2), 9, GFLAGS), + + /* PD_SUBDDR */ + COMPOSITE(CLK_CORE_DDRC_SRC, "clk_core_ddrc_src", mux_dpll_300m_p, CLK_IGNORE_UNUSED, + RV1106_SUBDDRCLKSEL_CON(0), 5, 1, MFLAGS, 0, 5, DFLAGS, + RV1106_SUBDDRCLKGATE_CON(0), 2, GFLAGS), + GATE(CLK_DFICTRL, "clk_dfictrl", "clk_core_ddrc_src", CLK_IGNORE_UNUSED, + RV1106_SUBDDRCLKGATE_CON(0), 5, GFLAGS), + GATE(CLK_DDRMON, "clk_ddrmon", "clk_core_ddrc_src", CLK_IGNORE_UNUSED, + RV1106_SUBDDRCLKGATE_CON(0), 4, GFLAGS), + GATE(CLK_DDR_PHY, "clk_ddr_phy", "clk_core_ddrc_src", CLK_IGNORE_UNUSED, + RV1106_SUBDDRCLKGATE_CON(0), 6, GFLAGS), + GATE(ACLK_DDRC, "aclk_ddrc", "clk_core_ddrc_src", CLK_IS_CRITICAL, + RV1106_SUBDDRCLKGATE_CON(0), 1, GFLAGS), + GATE(CLK_CORE_DDRC, "clk_core_ddrc", "clk_core_ddrc_src", CLK_IS_CRITICAL, + RV1106_SUBDDRCLKGATE_CON(0), 3, GFLAGS), + + /* PD_VEPU */ + COMPOSITE_NODIV(HCLK_VEPU_ROOT, "hclk_vepu_root", mux_200m_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_VEPUCLKSEL_CON(0), 0, 2, MFLAGS, + RV1106_VEPUCLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NODIV(ACLK_VEPU_COM_ROOT, "aclk_vepu_com_root", mux_400m_200m_100m_24m_p, CLK_IS_CRITICAL, + RV1106_VEPUCLKSEL_CON(0), 2, 2, MFLAGS, + RV1106_VEPUCLKGATE_CON(0), 1, GFLAGS), + COMPOSITE_NODIV(ACLK_VEPU_ROOT, "aclk_vepu_root", mux_300m_200m_100m_24m_p, CLK_IS_CRITICAL, + RV1106_VEPUCLKSEL_CON(0), 4, 2, MFLAGS, + RV1106_VEPUCLKGATE_CON(0), 2, GFLAGS), + COMPOSITE_NODIV(PCLK_VEPU_ROOT, "pclk_vepu_root", mux_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_VEPUCLKSEL_CON(0), 6, 2, MFLAGS, + RV1106_VEPUCLKGATE_CON(0), 3, GFLAGS), + GATE(PCLK_SPI0, "pclk_spi0", "pclk_vepu_root", 0, + RV1106_VEPUCLKGATE_CON(1), 2, GFLAGS), + COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_100m_50m_24m_p, 0, + RV1106_VEPUCLKSEL_CON(0), 12, 2, MFLAGS, + RV1106_VEPUCLKGATE_CON(1), 3, GFLAGS), + GATE(CLK_UART_DETN_FLT, "clk_uart_detn_flt", "xin24m", 0, + RV1106_VEPUCLKGATE_CON(1), 8, GFLAGS), + GATE(HCLK_VEPU, "hclk_vepu", "hclk_vepu_root", 0, + RV1106_VEPUCLKGATE_CON(0), 8, GFLAGS), + GATE(ACLK_VEPU, "aclk_vepu", "aclk_vepu_root", 0, + RV1106_VEPUCLKGATE_CON(0), 9, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_VEPU, "clk_core_vepu", mux_400m_300m_pvtpll0_pvtpll1_p, 0, + RV1106_VEPUCLKSEL_CON(0), 8, 2, MFLAGS, + RV1106_VEPUCLKGATE_CON(0), 10, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_VEPU_DVBM, "clk_core_vepu_dvbm", mux_200m_100m_50m_24m_p, 0, + RV1106_VEPUCLKSEL_CON(0), 10, 2, MFLAGS, + RV1106_VEPUCLKGATE_CON(0), 13, GFLAGS), + GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_vepu_root", 0, + RV1106_VEPUCLKGATE_CON(0), 15, GFLAGS), + GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m", 0, + RV1106_VEPUCLKGATE_CON(1), 0, GFLAGS), + GATE(HCLK_VEPU_PP, "hclk_vepu_pp", "hclk_vepu_root", 0, + RV1106_VEPUCLKGATE_CON(0), 11, GFLAGS), + GATE(ACLK_VEPU_PP, "aclk_vepu_pp", "aclk_vepu_root", 0, + RV1106_VEPUCLKGATE_CON(0), 12, GFLAGS), + + /* PD_VI */ + COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_150m_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_VICLKSEL_CON(0), 0, 2, MFLAGS, + RV1106_VICLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NODIV(ACLK_VI_ROOT, "aclk_vi_root", mux_339m_200m_100m_24m_p, CLK_IS_CRITICAL, + RV1106_VICLKSEL_CON(0), 2, 2, MFLAGS, + RV1106_VICLKGATE_CON(0), 1, GFLAGS), + COMPOSITE_NODIV(PCLK_VI_ROOT, "pclk_vi_root", mux_150m_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_VICLKSEL_CON(0), 4, 2, MFLAGS, + RV1106_VICLKGATE_CON(0), 2, GFLAGS), + COMPOSITE_NODIV(PCLK_VI_RTC_ROOT, "pclk_vi_rtc_root", mux_50m_24m_p, 0, + RV1106_VICLKSEL_CON(0), 6, 1, MFLAGS, + RV1106_VICLKGATE_CON(0), 3, GFLAGS), + + GATE(PCLK_CSIHOST0, "pclk_csihost0", "pclk_vi_root", 0, + RV1106_VICLKGATE_CON(1), 3, GFLAGS), + GATE(PCLK_CSIHOST1, "pclk_csihost1", "pclk_vi_root", 0, + RV1106_VICLKGATE_CON(1), 5, GFLAGS), + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_vi_root", 0, + RV1106_VICLKGATE_CON(1), 15, GFLAGS), + GATE(DBCLK_GPIO3, "dbclk_gpio3", "xin24m", 0, + RV1106_VICLKGATE_CON(2), 0, GFLAGS), + GATE(HCLK_ISP3P2, "hclk_isp3p2", "hclk_vi_root", 0, + RV1106_VICLKGATE_CON(0), 7, GFLAGS), + GATE(ACLK_ISP3P2, "aclk_isp3p2", "aclk_vi_root", 0, + RV1106_VICLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_ISP3P2, "clk_core_isp3p2", mux_339m_200m_pvtpll0_pvtpll1_p, 0, + RV1106_VICLKSEL_CON(0), 7, 2, MFLAGS, + RV1106_VICLKGATE_CON(0), 9, GFLAGS), + GATE(PCLK_MIPICSIPHY, "pclk_mipicsiphy", "pclk_vi_root", 0, + RV1106_VICLKGATE_CON(1), 14, GFLAGS), + COMPOSITE(CCLK_SRC_SDMMC, "cclk_src_sdmmc", mux_400m_24m_p, 0, + RV1106_VICLKSEL_CON(1), 14, 1, MFLAGS, 8, 6, DFLAGS, + RV1106_VICLKGATE_CON(1), 11, GFLAGS), + GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_vi_root", 0, + RV1106_VICLKGATE_CON(1), 12, GFLAGS), + GATE(CLK_SDMMC_DETN_FLT, "clk_sdmmc_detn_flt", "xin24m", 0, + RV1106_VICLKGATE_CON(1), 13, GFLAGS), + GATE(PCLK_VI_RTC_TEST, "pclk_vi_rtc_test", "pclk_vi_rtc_root", 0, + RV1106_VICLKGATE_CON(2), 5, GFLAGS), + GATE(PCLK_VI_RTC_PHY, "pclk_vi_rtc_phy", "pclk_vi_rtc_root", 0, + RV1106_VICLKGATE_CON(2), 6, GFLAGS), + COMPOSITE_NODIV(DCLK_VICAP, "dclk_vicap", mux_339m_200m_100m_24m_p, 0, + RV1106_VICLKSEL_CON(0), 9, 2, MFLAGS, + RV1106_VICLKGATE_CON(0), 10, GFLAGS), + GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_root", 0, + RV1106_VICLKGATE_CON(0), 12, GFLAGS), + GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi_root", 0, + RV1106_VICLKGATE_CON(0), 13, GFLAGS), + + /* PD_VO */ + COMPOSITE_NODIV(ACLK_MAC_ROOT, "aclk_mac_root", mux_300m_200m_100m_24m_p, 0, + RV1106_VOCLKSEL_CON(1), 12, 2, MFLAGS, + RV1106_VOCLKGATE_CON(1), 4, GFLAGS), + COMPOSITE_NODIV(ACLK_VO_ROOT, "aclk_vo_root", mux_400m_200m_100m_24m_p, CLK_IS_CRITICAL, + RV1106_VOCLKSEL_CON(0), 0, 2, MFLAGS, + RV1106_VOCLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NODIV(HCLK_VO_ROOT, "hclk_vo_root", mux_200m_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_VOCLKSEL_CON(0), 2, 2, MFLAGS, + RV1106_VOCLKGATE_CON(0), 1, GFLAGS), + COMPOSITE_NODIV(PCLK_VO_ROOT, "pclk_vo_root", mux_150m_100m_50m_24m_p, CLK_IS_CRITICAL, + RV1106_VOCLKSEL_CON(0), 4, 2, MFLAGS, + RV1106_VOCLKGATE_CON(0), 2, GFLAGS), + COMPOSITE_NODIV(ACLK_VOP_ROOT, "aclk_vop_root", mux_300m_200m_100m_24m_p, 0, + RV1106_VOCLKSEL_CON(1), 10, 2, MFLAGS, + RV1106_VOCLKGATE_CON(0), 11, GFLAGS), + + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_vo_root", 0, + RV1106_VOCLKGATE_CON(3), 0, GFLAGS), + GATE(DBCLK_GPIO2, "dbclk_gpio2", "xin24m", 0, + RV1106_VOCLKGATE_CON(3), 1, GFLAGS), + GATE(ACLK_MAC, "aclk_mac", "aclk_mac_root", 0, + RV1106_VOCLKGATE_CON(1), 8, GFLAGS), + GATE(PCLK_MAC, "pclk_mac", "pclk_vo_root", 0, + RV1106_VOCLKGATE_CON(1), 9, GFLAGS), + FACTOR(CLK_GMAC0_50M_O, "clk_gmac0_50m_o", "clk_50m_src", 0, 1, 1), + FACTOR(CLK_GMAC0_REF_50M, "clk_gmac0_ref_50m", "clk_gmac0_50m_o", 0, 1, 1), + DIV(CLK_GMAC0_TX_50M_O, "clk_gmac0_tx_50m_o", "clk_gmac0_50m_o", 0, + RV1106_VOCLKSEL_CON(2), 1, 6, DFLAGS), + GATE(CLK_MACPHY, "clk_macphy", "xin24m", 0, + RV1106_VOCLKGATE_CON(2), 13, GFLAGS), + GATE(CLK_OTPC_ARB, "clk_otpc_arb", "xin24m", 0, + RV1106_VOCLKGATE_CON(2), 11, GFLAGS), + GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_vo_root", 0, + RV1106_VOCLKGATE_CON(2), 3, GFLAGS), + GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m", 0, + RV1106_VOCLKGATE_CON(2), 5, GFLAGS), + COMPOSITE_NOMUX(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "xin24m", 0, + RV1106_VOCLKSEL_CON(3), 10, 3, DFLAGS, + RV1106_VOCLKGATE_CON(2), 6, GFLAGS), + GATE(PCLK_OTPC_S, "pclk_otpc_s", "pclk_vo_root", 0, + RV1106_VOCLKGATE_CON(2), 7, GFLAGS), + GATE(CLK_SBPI_OTPC_S, "clk_sbpi_otpc_s", "xin24m", 0, + RV1106_VOCLKGATE_CON(2), 9, GFLAGS), + COMPOSITE_NOMUX(CLK_USER_OTPC_S, "clk_user_otpc_s", "xin24m", 0, + RV1106_VOCLKSEL_CON(3), 13, 3, DFLAGS, + RV1106_VOCLKGATE_CON(2), 10, GFLAGS), + GATE(PCLK_OTP_MASK, "pclk_otp_mask", "pclk_vo_root", 0, + RV1106_VOCLKGATE_CON(2), 14, GFLAGS), + GATE(CLK_PMC_OTP, "clk_pmc_otp", "clk_sbpi_otpc_s", 0, + RV1106_VOCLKGATE_CON(2), 15, GFLAGS), + GATE(HCLK_RGA2E, "hclk_rga2e", "hclk_vo_root", 0, + RV1106_VOCLKGATE_CON(0), 7, GFLAGS), + GATE(ACLK_RGA2E, "aclk_rga2e", "aclk_vo_root", 0, + RV1106_VOCLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_RGA2E, "clk_core_rga2e", mux_400m_200m_100m_24m_p, 0, + RV1106_VOCLKSEL_CON(1), 8, 2, MFLAGS, + RV1106_VOCLKGATE_CON(0), 9, GFLAGS), + COMPOSITE(CCLK_SRC_SDIO, "cclk_src_sdio", mux_400m_24m_p, 0, + RV1106_VOCLKSEL_CON(2), 13, 1, MFLAGS, 7, 6, DFLAGS, + RV1106_VOCLKGATE_CON(1), 14, GFLAGS), + GATE(HCLK_SDIO, "hclk_sdio", "hclk_vo_root", 0, + RV1106_VOCLKGATE_CON(1), 15, GFLAGS), + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_vo_root", 0, + RV1106_VOCLKGATE_CON(2), 0, GFLAGS), + COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m", 0, + RV1106_VOCLKSEL_CON(3), 0, 5, DFLAGS, + RV1106_VOCLKGATE_CON(2), 1, GFLAGS), + COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m", 0, + RV1106_VOCLKSEL_CON(3), 5, 5, DFLAGS, + RV1106_VOCLKGATE_CON(2), 2, GFLAGS), + GATE(HCLK_VOP, "hclk_vop", "hclk_vo_root", 0, + RV1106_VOCLKGATE_CON(0), 13, GFLAGS), + GATE(DCLK_VOP, "dclk_vop", "dclk_vop_src", 0, + RV1106_VOCLKGATE_CON(0), 14, GFLAGS), + GATE(ACLK_VOP, "aclk_vop", "aclk_vop_root", 0, + RV1106_VOCLKGATE_CON(0), 15, GFLAGS), + + /* IO CLK */ + GATE(RX0PCLK_VICAP, "rx0pclk_vicap", "rx0pclk_vicap_io", 0, + RV1106_VICLKGATE_CON(1), 0, GFLAGS), + GATE(RX1PCLK_VICAP, "rx1pclk_vicap", "rx1pclk_vicap_io", 0, + RV1106_VICLKGATE_CON(1), 1, GFLAGS), + GATE(ISP0CLK_VICAP, "isp0clk_vicap", "isp0clk_vicap_io", 0, + RV1106_VICLKGATE_CON(1), 2, GFLAGS), + GATE(I0CLK_VICAP, "i0clk_vicap", "i0clk_vicap_io", 0, + RV1106_VICLKGATE_CON(0), 14, GFLAGS), + GATE(I1CLK_VICAP, "i1clk_vicap", "i1clk_vicap_io", 0, + RV1106_VICLKGATE_CON(0), 15, GFLAGS), + GATE(PCLK_VICAP, "pclk_vicap", "pclk_vicap_io", 0, + RV1106_VICLKGATE_CON(0), 11, GFLAGS), + GATE(CLK_RXBYTECLKHS_0, "clk_rxbyteclkhs_0", "clk_rxbyteclkhs_0_io", 0, + RV1106_VICLKGATE_CON(1), 4, GFLAGS), + GATE(CLK_RXBYTECLKHS_1, "clk_rxbyteclkhs_1", "clk_rxbyteclkhs_1_io", 0, + RV1106_VICLKGATE_CON(1), 6, GFLAGS), + + GATE(PCLK_VICAP_VEPU, "pclk_vicap_vepu", "pclk_vicap_vepu_io", 0, + RV1106_VEPUCLKGATE_CON(0), 14, GFLAGS), + GATE(SCLK_IN_SPI0, "sclk_in_spi0", "sclk_in_spi0_io", 0, + RV1106_VEPUCLKGATE_CON(1), 4, GFLAGS), + + GATE(CLK_UTMI_USBOTG, "clk_utmi_usbotg", "clk_utmi_usbotg_io", 0, + RV1106_PERICLKGATE_CON(4), 9, GFLAGS), +}; + +static struct rockchip_clk_branch rv1106_grf_clk_branches[] __initdata = { + MMC_GRF(SCLK_EMMC_DRV, "emmc_drv", "cclk_src_emmc", + RV1106_EMMC_CON0, 1, grf_type_sys), + MMC_GRF(SCLK_EMMC_SAMPLE, "emmc_sample", "cclk_src_emmc", + RV1106_EMMC_CON1, 1, grf_type_sys), + MMC_GRF(SCLK_SDMMC_DRV, "sdmmc_drv", "cclk_src_sdmmc", + RV1106_SDMMC_CON0, 1, grf_type_sys), + MMC_GRF(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "cclk_src_sdmmc", + RV1106_SDMMC_CON1, 1, grf_type_sys), + MMC_GRF(SCLK_SDIO_DRV, "sdio_drv", "cclk_src_sdio", + RV1106_SDIO_CON0, 1, grf_type_sys), + MMC_GRF(SCLK_SDIO_SAMPLE, "sdio_sample", "cclk_src_sdio", + RV1106_SDIO_CON1, 1, grf_type_sys), +}; + +static void __init rv1106_pvtpll_init(struct rockchip_clk_provider *ctx) +{ + /* set pvtpll ref clk mux */ + writel_relaxed(CPU_PVTPLL_PATH_CORE, ctx->reg_base + CPU_CLK_PATH_BASE); + + if (!IS_ERR(ctx->grf)) { + regmap_write(ctx->grf, CPU_PVTPLL_CON0_H, + HIWORD_UPDATE(0x7, PVTPLL_LENGTH_SEL_MASK, + PVTPLL_LENGTH_SEL_SHIFT)); + regmap_write(ctx->grf, CPU_PVTPLL_CON0_L, + HIWORD_UPDATE(0x1, PVTPLL_RING_SEL_MASK, + PVTPLL_RING_SEL_SHIFT)); + regmap_write(ctx->grf, CPU_PVTPLL_CON0_L, + HIWORD_UPDATE(0x3, PVTPLL_EN_MASK, + PVTPLL_EN_SHIFT)); + } + + writel_relaxed(0x007f0000, ctx->reg_base + CRU_PVTPLL0_CON0_H); + writel_relaxed(0xffff0018, ctx->reg_base + CRU_PVTPLL0_CON1_L); + writel_relaxed(0xffff0004, ctx->reg_base + CRU_PVTPLL0_CON2_H); + writel_relaxed(0x00030003, ctx->reg_base + CRU_PVTPLL0_CON0_L); + + writel_relaxed(0x007f0000, ctx->reg_base + CRU_PVTPLL1_CON0_H); + writel_relaxed(0xffff0018, ctx->reg_base + CRU_PVTPLL1_CON1_L); + writel_relaxed(0xffff0004, ctx->reg_base + CRU_PVTPLL1_CON2_H); + writel_relaxed(0x00030003, ctx->reg_base + CRU_PVTPLL1_CON0_L); +} + +static int __init clk_rv1106_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct rockchip_clk_provider *ctx; + unsigned long clk_nr; + void __iomem *reg_base; + int ret; + + clk_nr = rockchip_clk_find_max_clk_id(rv1106_clk_branches, + ARRAY_SIZE(rv1106_clk_branches)) + 1; + clk_nr = max(clk_nr, + rockchip_clk_find_max_clk_id(rv1106_grf_clk_branches, + ARRAY_SIZE(rv1106_grf_clk_branches)) + 1); + reg_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(reg_base)) + return dev_err_probe(dev, PTR_ERR(reg_base), + "could not map cru region"); + + ctx = rockchip_clk_init(np, reg_base, clk_nr); + if (IS_ERR(ctx)) + return dev_err_probe(dev, PTR_ERR(ctx), + "rockchip clk init failed"); + + rv1106_pvtpll_init(ctx); + + rockchip_clk_register_plls(ctx, rv1106_pll_clks, + ARRAY_SIZE(rv1106_pll_clks), + RV1106_GRF_SOC_STATUS0); + + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", + mux_armclk_p, ARRAY_SIZE(mux_armclk_p), + &rv1106_cpuclk_data, rv1106_cpuclk_rates, + ARRAY_SIZE(rv1106_cpuclk_rates)); + + rockchip_clk_register_branches(ctx, rv1106_clk_branches, + ARRAY_SIZE(rv1106_clk_branches)); + + /* + * The MMC drive and sample phase clocks have their control + * registers in the GRF region, so they can only be provided when + * the rockchip,grf property points at a valid syscon. + */ + if (!IS_ERR(ctx->grf)) { + ret = rockchip_clk_add_grf(ctx, ctx->grf, grf_type_sys); + if (ret) + dev_err(dev, "failed to add grf: %d\n", ret); + else + rockchip_clk_register_branches(ctx, + rv1106_grf_clk_branches, + ARRAY_SIZE(rv1106_grf_clk_branches)); + } + + rockchip_register_restart_notifier(ctx, RV1106_GLB_SRST_FST, NULL); + + rockchip_clk_of_add_provider(np, ctx); + + return 0; +} + +static const struct of_device_id clk_rv1106_match_table[] = { + { .compatible = "rockchip,rv1106-cru" }, + { /* end */ } +}; + +static struct platform_driver clk_rv1106_driver = { + .driver = { + .name = "clk-rv1106", + .of_match_table = clk_rv1106_match_table, + .suppress_bind_attrs = true, + }, +}; +builtin_platform_driver_probe(clk_rv1106_driver, clk_rv1106_probe); diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 9e3503e2ffc2..72b36bba3152 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -635,10 +635,10 @@ struct rockchip_pll_rate_table { }; struct { /* for RK3588 */ - unsigned int m; - unsigned int p; - unsigned int s; - unsigned int k; + unsigned int m; /* main divider, 10 bit unsigned */ + unsigned int p; /* pre-divider, 6 bit unsigned */ + unsigned int s; /* scaler, 3 bit unsigned */ + s16 k; /* fractional part, 16 bit two's complement */ }; }; }; diff --git a/drivers/clk/samsung/clk-acpm.c b/drivers/clk/samsung/clk-acpm.c index 953ca8d5720a..7680bc8c5275 100644 --- a/drivers/clk/samsung/clk-acpm.c +++ b/drivers/clk/samsung/clk-acpm.c @@ -72,18 +72,6 @@ static unsigned long acpm_clk_recalc_rate(struct clk_hw *hw, clk->id); } -static int acpm_clk_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - /* - * We can't figure out what rate it will be, so just return the - * rate back to the caller. acpm_clk_recalc_rate() will be called - * after the rate is set and we'll know what rate the clock is - * running at then. - */ - return 0; -} - static int acpm_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -95,7 +83,7 @@ static int acpm_clk_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops acpm_clk_ops = { .recalc_rate = acpm_clk_recalc_rate, - .determine_rate = acpm_clk_determine_rate, + .determine_rate = clk_determine_rate_noop, .set_rate = acpm_clk_set_rate, }; @@ -166,8 +154,8 @@ static int acpm_clk_probe(struct platform_device *pdev) } static const struct platform_device_id acpm_clk_id[] = { - { "gs101-acpm-clk" }, - {} + { .name = "gs101-acpm-clk" }, + { } }; MODULE_DEVICE_TABLE(platform, acpm_clk_id); diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c index ffc33e5decf5..37cf47533dc6 100644 --- a/drivers/clk/samsung/clk-cpu.c +++ b/drivers/clk/samsung/clk-cpu.c @@ -101,11 +101,11 @@ struct exynos_cpuclk { const struct clk_hw *alt_parent; void __iomem *base; spinlock_t *lock; - const struct exynos_cpuclk_cfg_data *cfg; - const unsigned long num_cfgs; + unsigned long num_cfgs; struct notifier_block clk_nb; unsigned long flags; const struct exynos_cpuclk_chip *chip; + struct exynos_cpuclk_cfg_data cfg[] __counted_by(num_cfgs); }; /* ---- Common code --------------------------------------------------------- */ @@ -660,10 +660,6 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, return -EINVAL; } - cpuclk = kzalloc_obj(*cpuclk); - if (!cpuclk) - return -ENOMEM; - parent_name = clk_hw_get_name(parent); init.name = clk_data->name; @@ -672,6 +668,17 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, init.num_parents = 1; init.ops = &exynos_cpuclk_clk_ops; + /* Find count of configuration rates in cfg */ + for (num_cfgs = 0; clk_data->cfg[num_cfgs].prate != 0; ) + num_cfgs++; + + cpuclk = kzalloc_flex(*cpuclk, cfg, num_cfgs); + if (!cpuclk) + return -ENOMEM; + + cpuclk->num_cfgs = num_cfgs; + + memcpy(cpuclk->cfg, clk_data->cfg, num_cfgs * sizeof(*cpuclk->cfg)); cpuclk->alt_parent = alt_parent; cpuclk->hw.init = &init; cpuclk->base = ctx->reg_base + clk_data->offset; @@ -687,29 +694,16 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, goto free_cpuclk; } - /* Find count of configuration rates in cfg */ - for (num_cfgs = 0; clk_data->cfg[num_cfgs].prate != 0; ) - num_cfgs++; - - cpuclk->cfg = kmemdup_array(clk_data->cfg, num_cfgs, sizeof(*cpuclk->cfg), - GFP_KERNEL); - if (!cpuclk->cfg) { - ret = -ENOMEM; - goto unregister_clk_nb; - } - ret = clk_hw_register(NULL, &cpuclk->hw); if (ret) { pr_err("%s: could not register cpuclk %s\n", __func__, clk_data->name); - goto free_cpuclk_data; + goto unregister_clk_nb; } samsung_clk_add_lookup(ctx, &cpuclk->hw, clk_data->id); return 0; -free_cpuclk_data: - kfree(cpuclk->cfg); unregister_clk_nb: clk_notifier_unregister(parent->clk, &cpuclk->clk_nb); free_cpuclk: diff --git a/drivers/clk/samsung/clk-exynos990.c b/drivers/clk/samsung/clk-exynos990.c index 7a27557e6713..44c068bc1dc8 100644 --- a/drivers/clk/samsung/clk-exynos990.c +++ b/drivers/clk/samsung/clk-exynos990.c @@ -20,7 +20,7 @@ #define CLKS_NR_HSI0 (CLK_GOUT_HSI0_LHS_ACEL_D_HSI0_CLK + 1) #define CLKS_NR_PERIC0 (CLK_GOUT_PERIC0_SYSREG_PCLK + 1) #define CLKS_NR_PERIC1 (CLK_GOUT_PERIC1_XIU_P_ACLK + 1) -#define CLKS_NR_PERIS (CLK_GOUT_PERIS_OTP_CON_TOP_OSCCLK + 1) +#define CLKS_NR_PERIS (CLK_GOUT_PERIS_TMU_SUB_PCLK + 1) /* ---- CMU_TOP ------------------------------------------------------------- */ @@ -2550,7 +2550,7 @@ static const unsigned long peris_clk_regs[] __initconst = { /* Parent clock list for CMU_PERIS muxes */ PNAME(mout_peris_bus_user_p) = { "oscclk", "mout_cmu_peris_bus" }; -PNAME(mout_peris_clk_peris_gic_p) = { "oscclk", "mout_peris_bus_user" }; +PNAME(mout_peris_clk_peris_gic_p) = { "mout_peris_bus_user", "oscclk" }; static const struct samsung_mux_clock peris_mux_clks[] __initconst = { MUX(CLK_MOUT_PERIS_BUS_USER, "mout_peris_bus_user", @@ -2583,15 +2583,15 @@ static const struct samsung_gate_clock peris_gate_clks[] __initconst = { CLK_CON_GAT_GOUT_BLK_PERIS_UID_RSTNSYNC_CLK_PERIS_BUSP_IPCLKPORT_CLK, 21, 0, 0), GATE(CLK_GOUT_PERIS_CLK_PERIS_OSCCLK_CLK, - "gout_peris_clk_peris_oscclk_clk", "mout_peris_bus_user", + "gout_peris_clk_peris_oscclk_clk", "oscclk", CLK_CON_GAT_CLK_BLK_PERIS_UID_RSTNSYNC_CLK_PERIS_OSCCLK_IPCLKPORT_CLK, 21, 0, 0), GATE(CLK_GOUT_PERIS_CLK_PERIS_GIC_CLK, - "gout_peris_clk_peris_gic_clk", "mout_peris_bus_user", + "gout_peris_clk_peris_gic_clk", "mout_peris_clk_peris_gic", CLK_CON_GAT_GOUT_BLK_PERIS_UID_RSTNSYNC_CLK_PERIS_GIC_IPCLKPORT_CLK, 21, 0, 0), GATE(CLK_GOUT_PERIS_AD_AXI_P_PERIS_ACLKM, - "gout_peris_ad_axi_p_peris_aclkm", "mout_peris_bus_user", + "gout_peris_ad_axi_p_peris_aclkm", "mout_peris_clk_peris_gic", CLK_CON_GAT_GOUT_BLK_PERIS_UID_AD_AXI_P_PERIS_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0), GATE(CLK_GOUT_PERIS_OTP_CON_BIRA_PCLK, @@ -2599,27 +2599,31 @@ static const struct samsung_gate_clock peris_gate_clks[] __initconst = { CLK_CON_GAT_GOUT_BLK_PERIS_UID_OTP_CON_BIRA_IPCLKPORT_PCLK, 21, 0, 0), GATE(CLK_GOUT_PERIS_GIC_CLK, - "gout_peris_gic_clk", "mout_peris_bus_user", + "gout_peris_gic_clk", "mout_peris_clk_peris_gic", CLK_CON_GAT_GOUT_BLK_PERIS_UID_GIC_IPCLKPORT_CLK, 21, CLK_IS_CRITICAL, 0), GATE(CLK_GOUT_PERIS_LHM_AXI_P_PERIS_CLK, - "gout_peris_lhm_axi_p_peris_clk", "oscclk", + "gout_peris_lhm_axi_p_peris_clk", "mout_peris_bus_user", CLK_CON_GAT_GOUT_BLK_PERIS_UID_LHM_AXI_P_PERIS_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CLK_GOUT_PERIS_MCT_PCLK, - "gout_peris_mct_pclk", "mout_peris_clk_peris_gic", + "gout_peris_mct_pclk", "mout_peris_bus_user", CLK_CON_GAT_GOUT_BLK_PERIS_UID_MCT_IPCLKPORT_PCLK, 21, 0, 0), GATE(CLK_GOUT_PERIS_OTP_CON_TOP_PCLK, - "gout_peris_otp_con_top_pclk", "mout_peris_clk_peris_gic", + "gout_peris_otp_con_top_pclk", "mout_peris_bus_user", CLK_CON_GAT_GOUT_BLK_PERIS_UID_OTP_CON_TOP_IPCLKPORT_PCLK, 21, 0, 0), GATE(CLK_GOUT_PERIS_D_TZPC_PERIS_PCLK, "gout_peris_d_tzpc_peris_pclk", "mout_peris_bus_user", CLK_CON_GAT_GOUT_BLK_PERIS_UID_D_TZPC_PERIS_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_PERIS_TMU_SUB_PCLK, + "gout_peris_tmu_sub_pclk", "mout_peris_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIS_UID_TMU_SUB_IPCLKPORT_PCLK, + 21, 0, 0), GATE(CLK_GOUT_PERIS_TMU_TOP_PCLK, - "gout_peris_tmu_top_pclk", "mout_peris_clk_peris_gic", + "gout_peris_tmu_top_pclk", "mout_peris_bus_user", CLK_CON_GAT_GOUT_BLK_PERIS_UID_TMU_TOP_IPCLKPORT_PCLK, 21, 0, 0), GATE(CLK_GOUT_PERIS_OTP_CON_BIRA_OSCCLK, diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index fdb84bcec912..e74552846ba3 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -28,7 +28,7 @@ struct samsung_clk_pll { unsigned short lock_offs; enum samsung_pll_type type; unsigned int rate_count; - const struct samsung_pll_rate_table *rate_table; + struct samsung_pll_rate_table rate_table[] __counted_by(rate_count); }; #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw) @@ -1593,35 +1593,32 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, { struct samsung_clk_pll *pll; struct clk_init_data init; - int ret, len; + unsigned int len = 0; + int ret; - pll = kzalloc_obj(*pll); + if (pll_clk->rate_table) { + /* find count of rates in rate_table */ + while (pll_clk->rate_table[len].rate != 0) + len++; + } + + pll = kzalloc_flex(*pll, rate_table, len); if (!pll) { pr_err("%s: could not allocate pll clk %s\n", __func__, pll_clk->name); return; } + pll->rate_count = len; + if (len) + memcpy(pll->rate_table, pll_clk->rate_table, + len * sizeof(*pll->rate_table)); + init.name = pll_clk->name; init.flags = pll_clk->flags; init.parent_names = &pll_clk->parent_name; init.num_parents = 1; - if (pll_clk->rate_table) { - /* find count of rates in rate_table */ - for (len = 0; pll_clk->rate_table[len].rate != 0; ) - len++; - - pll->rate_count = len; - pll->rate_table = kmemdup_array(pll_clk->rate_table, - pll->rate_count, - sizeof(*pll->rate_table), - GFP_KERNEL); - WARN(!pll->rate_table, - "%s: could not allocate rate table for %s\n", - __func__, pll_clk->name); - } - switch (pll_clk->type) { case pll_2126: init.ops = &samsung_pll2126_clk_ops; @@ -1640,7 +1637,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, case pll_a9fracm: pll->enable_offs = PLL35XX_ENABLE_SHIFT; pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT; - if (!pll->rate_table) + if (!pll->rate_count) init.ops = &samsung_pll35xx_clk_min_ops; else init.ops = &samsung_pll35xx_clk_ops; @@ -1659,7 +1656,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, case pll_0732x: pll->enable_offs = PLL0822X_ENABLE_SHIFT; pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT; - if (!pll->rate_table) + if (!pll->rate_count) init.ops = &samsung_pll0822x_clk_min_ops; else init.ops = &samsung_pll0822x_clk_ops; @@ -1669,7 +1666,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, break; case pll_4502: case pll_4508: - if (!pll->rate_table) + if (!pll->rate_count) init.ops = &samsung_pll45xx_clk_min_ops; else init.ops = &samsung_pll45xx_clk_ops; @@ -1679,7 +1676,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, case pll_2650: pll->enable_offs = PLL36XX_ENABLE_SHIFT; pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT; - if (!pll->rate_table) + if (!pll->rate_count) init.ops = &samsung_pll36xx_clk_min_ops; else init.ops = &samsung_pll36xx_clk_ops; @@ -1687,7 +1684,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, case pll_0831x: pll->enable_offs = PLL0831X_ENABLE_SHIFT; pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT; - if (!pll->rate_table) + if (!pll->rate_count) init.ops = &samsung_pll0831x_clk_min_ops; else init.ops = &samsung_pll0831x_clk_ops; @@ -1703,7 +1700,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, case pll_4650: case pll_4650c: case pll_1460x: - if (!pll->rate_table) + if (!pll->rate_count) init.ops = &samsung_pll46xx_clk_min_ops; else init.ops = &samsung_pll46xx_clk_ops; @@ -1712,19 +1709,19 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, init.ops = &samsung_pll2550x_clk_ops; break; case pll_2550xx: - if (!pll->rate_table) + if (!pll->rate_count) init.ops = &samsung_pll2550xx_clk_min_ops; else init.ops = &samsung_pll2550xx_clk_ops; break; case pll_2650x: - if (!pll->rate_table) + if (!pll->rate_count) init.ops = &samsung_pll2650x_clk_min_ops; else init.ops = &samsung_pll2650x_clk_ops; break; case pll_2650xx: - if (!pll->rate_table) + if (!pll->rate_count) init.ops = &samsung_pll2650xx_clk_min_ops; else init.ops = &samsung_pll2650xx_clk_ops; @@ -1734,7 +1731,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, init.ops = &samsung_pll531x_clk_ops; break; case pll_1031x: - if (!pll->rate_table) + if (!pll->rate_count) init.ops = &samsung_pll1031x_clk_min_ops; else init.ops = &samsung_pll1031x_clk_ops; @@ -1742,7 +1739,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, case pll_a9fraco: pll->enable_offs = PLLA9FRACO_ENABLE_SHIFT; pll->lock_offs = PLLA9FRACO_LOCK_STAT_SHIFT; - if (!pll->rate_table) + if (!pll->rate_count) init.ops = &samsung_a9fraco_clk_min_ops; else init.ops = &samsung_a9fraco_clk_ops; @@ -1761,7 +1758,6 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, if (ret) { pr_err("%s: failed to register pll clock %s : %d\n", __func__, pll_clk->name, ret); - kfree(pll->rate_table); kfree(pll); return; } diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 7f1bc3e31442..a3b251fb6fcb 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -429,21 +429,22 @@ void samsung_clk_extended_sleep_init(void __iomem *reg_base, unsigned long nr_rsuspend) { struct samsung_clock_reg_cache *reg_cache; + int i; - reg_cache = kzalloc_obj(struct samsung_clock_reg_cache); + reg_cache = kzalloc_flex(*reg_cache, rdump, nr_rdump); if (!reg_cache) panic("could not allocate register reg_cache.\n"); - reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); - if (!reg_cache->rdump) - panic("could not allocate register dump storage.\n"); + reg_cache->rd_num = nr_rdump; + + for (i = 0; i < nr_rdump; ++i) + reg_cache->rdump[i].offset = rdump[i]; if (list_empty(&clock_reg_cache_list)) register_syscore(&samsung_clk_syscore); reg_cache->reg_base = reg_base; reg_cache->sysreg = sysreg; - reg_cache->rd_num = nr_rdump; reg_cache->rsuspend = rsuspend; reg_cache->rsuspend_num = nr_rsuspend; list_add_tail(®_cache->node, &clock_reg_cache_list); diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index b1192ca03db5..3b8d51e9b73c 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -11,7 +11,7 @@ #define __SAMSUNG_CLK_H #include -#include +#include #include #include "clk-pll.h" #include "clk-cpu.h" @@ -324,10 +324,10 @@ struct samsung_clock_reg_cache { struct list_head node; void __iomem *reg_base; struct regmap *sysreg; - struct samsung_clk_reg_dump *rdump; - unsigned int rd_num; const struct samsung_clk_reg_dump *rsuspend; unsigned int rsuspend_num; + unsigned int rd_num; + struct samsung_clk_reg_dump rdump[] __counted_by(rd_num); }; /** diff --git a/drivers/clk/spacemit/ccu-k3.c b/drivers/clk/spacemit/ccu-k3.c index 764426359540..92b930d5ff30 100644 --- a/drivers/clk/spacemit/ccu-k3.c +++ b/drivers/clk/spacemit/ccu-k3.c @@ -218,11 +218,19 @@ static const struct clk_parent_data i2s_sysclk_src_parents[] = { CCU_PARENT_HW(pll1_d96_25p6), CCU_PARENT_HW(i2s_153p6_base), }; -CCU_MUX_GATE_DEFINE(i2s_sysclk_src, i2s_sysclk_src_parents, MPMU_ISCCR, 30, 1, BIT(31), 0); +CCU_MUX_GATE_DEFINE(i2s_sysclk_src, i2s_sysclk_src_parents, MPMU_ISCCR1, 30, 1, BIT(31), 0); -CCU_DDN_DEFINE(i2s1_sysclk, i2s_sysclk_src, MPMU_ISCCR, 0, 15, 15, 12, 1, 0); +CCU_DDN_DEFINE(i2s_sysclk, i2s_sysclk_src, MPMU_ISCCR1, 0, 15, 15, 12, 1, 0); -CCU_DIV_GATE_DEFINE(i2s_bclk, CCU_PARENT_HW(i2s1_sysclk), MPMU_ISCCR, 27, 2, BIT(29), 0); +CCU_FACTOR_DEFINE(i2s_bclk_factor, CCU_PARENT_HW(i2s_sysclk), 2, 1); +/* + * Divider of i2s_bclk always implies a 1/2 factor, which is + * described by i2s_bclk_factor. + */ +CCU_DIV_GATE_DEFINE(i2s_bclk, CCU_PARENT_HW(i2s_bclk_factor), MPMU_ISCCR1, 27, 2, BIT(29), 0); + +CCU_MUX_GATE_DEFINE(i2s1_sysclk_src, i2s_sysclk_src_parents, MPMU_ISCCR0, 30, 1, BIT(31), 0); +CCU_DDN_DEFINE(i2s1_sysclk, i2s1_sysclk_src, MPMU_ISCCR0, 0, 15, 15, 12, 1, 0); static const struct clk_parent_data i2s_sysclk_parents[] = { CCU_PARENT_HW(pll1_d4_614p4), @@ -236,14 +244,14 @@ CCU_MUX_DEFINE(i2s3_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 12, 2, CCU_MUX_DEFINE(i2s4_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 16, 2, 0); CCU_MUX_DEFINE(i2s5_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 20, 2, 0); -CCU_DDN_DEFINE(i2s0_sysclk_div, i2s0_sysclk_sel, MPMU_I2S0_SYSCLK, 0, 16, 16, 16, 1, 0); -CCU_DDN_DEFINE(i2s2_sysclk_div, i2s2_sysclk_sel, MPMU_I2S2_SYSCLK, 0, 16, 16, 16, 1, 0); -CCU_DDN_DEFINE(i2s3_sysclk_div, i2s3_sysclk_sel, MPMU_I2S3_SYSCLK, 0, 16, 16, 16, 1, 0); -CCU_DDN_DEFINE(i2s4_sysclk_div, i2s4_sysclk_sel, MPMU_I2S4_SYSCLK, 0, 16, 16, 16, 1, 0); -CCU_DDN_DEFINE(i2s5_sysclk_div, i2s5_sysclk_sel, MPMU_I2S5_SYSCLK, 0, 16, 16, 16, 1, 0); +CCU_DDN_DEFINE(i2s0_sysclk_div, i2s0_sysclk_sel, MPMU_I2S0_SYSCLK, 0, 16, 16, 16, 2, 0); +CCU_DDN_DEFINE(i2s2_sysclk_div, i2s2_sysclk_sel, MPMU_I2S2_SYSCLK, 0, 16, 16, 16, 2, 0); +CCU_DDN_DEFINE(i2s3_sysclk_div, i2s3_sysclk_sel, MPMU_I2S3_SYSCLK, 0, 16, 16, 16, 2, 0); +CCU_DDN_DEFINE(i2s4_sysclk_div, i2s4_sysclk_sel, MPMU_I2S4_SYSCLK, 0, 16, 16, 16, 2, 0); +CCU_DDN_DEFINE(i2s5_sysclk_div, i2s5_sysclk_sel, MPMU_I2S5_SYSCLK, 0, 16, 16, 16, 2, 0); static const struct clk_parent_data i2s2_sysclk_parents[] = { - CCU_PARENT_HW(i2s1_sysclk), + CCU_PARENT_HW(i2s_sysclk), CCU_PARENT_HW(i2s2_sysclk_div), }; CCU_GATE_DEFINE(i2s0_sysclk, CCU_PARENT_HW(i2s0_sysclk_div), MPMU_I2S_SYSCLK_CTRL, BIT(2), 0); @@ -926,15 +934,16 @@ CCU_MUX_DIV_GATE_FC_DEFINE(dpu_aclk, dpu_aclk_parents, APMU_LCD_CLK_RES_CTRL5, 1 20, 3, BIT(16), 0); static const struct clk_parent_data ufs_aclk_parents[] = { - CCU_PARENT_HW(pll1_d6_409p6), CCU_PARENT_HW(pll1_d5_491p52), - CCU_PARENT_HW(pll1_d4_614p4), - CCU_PARENT_HW(pll1_d8_307p2), - CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll2_d6), + CCU_PARENT_HW(pll2_d5), }; CCU_MUX_DIV_GATE_FC_DEFINE(ufs_aclk, ufs_aclk_parents, APMU_UFS_CLK_RES_CTRL, 5, 3, BIT(8), 2, 3, BIT(1), 0); +CCU_FACTOR_DEFINE(ufs_refclk, CCU_PARENT_HW(pll1_d64_38p4), 2, 1); + static const struct clk_parent_data edp0_pclk_parents[] = { CCU_PARENT_HW(lcd_pxclk), CCU_PARENT_NAME(external_clk), @@ -1161,8 +1170,11 @@ static struct clk_hw *k3_ccu_mpmu_hws[] = { [CLK_MPMU_I2S_153P6] = &i2s_153p6.common.hw, [CLK_MPMU_I2S_153P6_BASE] = &i2s_153p6_base.common.hw, [CLK_MPMU_I2S_SYSCLK_SRC] = &i2s_sysclk_src.common.hw, - [CLK_MPMU_I2S1_SYSCLK] = &i2s1_sysclk.common.hw, + [CLK_MPMU_I2S_SYSCLK] = &i2s_sysclk.common.hw, + [CLK_MPMU_I2S_BCLK_FACTOR] = &i2s_bclk_factor.common.hw, [CLK_MPMU_I2S_BCLK] = &i2s_bclk.common.hw, + [CLK_MPMU_I2S1_SYSCLK_SRC] = &i2s1_sysclk_src.common.hw, + [CLK_MPMU_I2S1_SYSCLK] = &i2s1_sysclk.common.hw, [CLK_MPMU_I2S0_SYSCLK_SEL] = &i2s0_sysclk_sel.common.hw, [CLK_MPMU_I2S2_SYSCLK_SEL] = &i2s2_sysclk_sel.common.hw, [CLK_MPMU_I2S3_SYSCLK_SEL] = &i2s3_sysclk_sel.common.hw, @@ -1392,6 +1404,7 @@ static struct clk_hw *k3_ccu_apmu_hws[] = { [CLK_APMU_DSI4LN2_DPU_ACLK] = &dsi4ln2_dpu_aclk.common.hw, [CLK_APMU_DPU_ACLK] = &dpu_aclk.common.hw, [CLK_APMU_UFS_ACLK] = &ufs_aclk.common.hw, + [CLK_APMU_UFS_REFCLK] = &ufs_refclk.common.hw, [CLK_APMU_EDP0_PXCLK] = &edp0_pxclk.common.hw, [CLK_APMU_EDP1_PXCLK] = &edp1_pxclk.common.hw, [CLK_APMU_PCIE_PORTA_MSTE] = &pciea_mstr_clk.common.hw, diff --git a/drivers/clk/sprd/pll.c b/drivers/clk/sprd/pll.c index bc2db19aec0e..4aec30777d8a 100644 --- a/drivers/clk/sprd/pll.c +++ b/drivers/clk/sprd/pll.c @@ -254,16 +254,10 @@ static int sprd_pll_clk_prepare(struct clk_hw *hw) return 0; } -static int sprd_pll_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - return 0; -} - const struct clk_ops sprd_pll_ops = { .prepare = sprd_pll_clk_prepare, .recalc_rate = sprd_pll_recalc_rate, - .determine_rate = sprd_pll_determine_rate, + .determine_rate = clk_determine_rate_noop, .set_rate = sprd_pll_set_rate, }; EXPORT_SYMBOL_GPL(sprd_pll_ops); diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c index 9eb2cb83fa69..17551c6a879a 100644 --- a/drivers/clk/st/clkgen-pll.c +++ b/drivers/clk/st/clkgen-pll.c @@ -260,7 +260,7 @@ static int __clkgen_pll_enable(struct clk_hw *hw) if (pll->data->switch2pll_en) CLKGEN_WRITE(pll, switch2pll, 0); - pr_debug("%s:%s enabled\n", __clk_get_name(hw->clk), __func__); + pr_debug("%s:%s enabled\n", clk_hw_get_name(hw), __func__); } return ret; @@ -295,7 +295,7 @@ static void __clkgen_pll_disable(struct clk_hw *hw) CLKGEN_WRITE(pll, pdn_ctrl, 1); - pr_debug("%s:%s disabled\n", __clk_get_name(hw->clk), __func__); + pr_debug("%s:%s disabled\n", clk_hw_get_name(hw), __func__); } static void clkgen_pll_disable(struct clk_hw *hw) @@ -405,14 +405,14 @@ static int stm_pll3200c32_determine_rate(struct clk_hw *hw, &req->rate); else { pr_debug("%s: %s rate %ld Invalid\n", __func__, - __clk_get_name(hw->clk), req->rate); + clk_hw_get_name(hw), req->rate); req->rate = 0; return 0; } pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n", - __func__, __clk_get_name(hw->clk), + __func__, clk_hw_get_name(hw), req->rate, (unsigned int)params.ndiv, (unsigned int)params.idf); @@ -434,7 +434,7 @@ static int set_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate, clk_pll3200c32_get_rate(parent_rate, ¶ms, &hwrate); pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n", - __func__, __clk_get_name(hw->clk), + __func__, clk_hw_get_name(hw), hwrate, (unsigned int)params.ndiv, (unsigned int)params.idf); @@ -547,7 +547,7 @@ static unsigned long recalc_stm_pll4600c28(struct clk_hw *hw, clk_pll4600c28_get_rate(parent_rate, ¶ms, &rate); - pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate); + pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate); return rate; } @@ -562,14 +562,14 @@ static int stm_pll4600c28_determine_rate(struct clk_hw *hw, &req->rate); } else { pr_debug("%s: %s rate %ld Invalid\n", __func__, - __clk_get_name(hw->clk), req->rate); + clk_hw_get_name(hw), req->rate); req->rate = 0; return 0; } pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n", - __func__, __clk_get_name(hw->clk), + __func__, clk_hw_get_name(hw), req->rate, (unsigned int)params.ndiv, (unsigned int)params.idf); @@ -591,12 +591,12 @@ static int set_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate, clk_pll4600c28_get_rate(parent_rate, ¶ms, &hwrate); } else { pr_debug("%s: %s rate %ld Invalid\n", __func__, - __clk_get_name(hw->clk), rate); + clk_hw_get_name(hw), rate); return -EINVAL; } pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n", - __func__, __clk_get_name(hw->clk), + __func__, clk_hw_get_name(hw), hwrate, (unsigned int)params.ndiv, (unsigned int)params.idf); diff --git a/drivers/clk/stm32/clk-stm32mp21.c b/drivers/clk/stm32/clk-stm32mp21.c index c8a37b716bd5..bdb17419908c 100644 --- a/drivers/clk/stm32/clk-stm32mp21.c +++ b/drivers/clk/stm32/clk-stm32mp21.c @@ -4,6 +4,7 @@ * Author: Gabriel Fernandez for STMicroelectronics. */ +#include #include #include #include diff --git a/drivers/clk/stm32/clk-stm32mp25.c b/drivers/clk/stm32/clk-stm32mp25.c index 52f0e8a12926..eb0bc918ecee 100644 --- a/drivers/clk/stm32/clk-stm32mp25.c +++ b/drivers/clk/stm32/clk-stm32mp25.c @@ -4,6 +4,7 @@ * Author: Gabriel Fernandez for STMicroelectronics. */ +#include #include #include #include diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c index f6bfeba009e8..98ae10307f43 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c @@ -44,16 +44,20 @@ #define DCXO_CTRL_REG 0x160 #define DCXO_CTRL_CLK16M_RC_EN BIT(0) +#define DCXO_GATING_REG 0x16c + +#define CLK_NUMBER_NO_GATES (CLK_OSC24M_32K_DIV + 1) + struct sun6i_rtc_match_data { bool have_ext_osc32k : 1; bool have_iosc_calibration : 1; + bool have_dcxo_status : 1; + bool have_phy_ref_gates : 1; bool rtc_32k_single_parent : 1; const struct clk_parent_data *osc32k_fanout_parents; u8 osc32k_fanout_nparents; }; -static bool have_iosc_calibration; - static int ccu_iosc_enable(struct clk_hw *hw) { struct ccu_common *cm = hw_to_ccu_common(hw); @@ -80,7 +84,7 @@ static unsigned long ccu_iosc_recalc_rate(struct clk_hw *hw, { struct ccu_common *cm = hw_to_ccu_common(hw); - if (have_iosc_calibration) { + if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) { u32 reg = readl(cm->base + IOSC_CLK_CALI_REG); /* @@ -119,7 +123,7 @@ static int ccu_iosc_32k_prepare(struct clk_hw *hw) struct ccu_common *cm = hw_to_ccu_common(hw); u32 val; - if (!have_iosc_calibration) + if (!(cm->features & CCU_FEATURE_IOSC_CALIBRATION)) return 0; val = readl(cm->base + IOSC_CLK_CALI_REG); @@ -134,7 +138,7 @@ static void ccu_iosc_32k_unprepare(struct clk_hw *hw) struct ccu_common *cm = hw_to_ccu_common(hw); u32 val; - if (!have_iosc_calibration) + if (!(cm->features & CCU_FEATURE_IOSC_CALIBRATION)) return; val = readl(cm->base + IOSC_CLK_CALI_REG); @@ -148,7 +152,7 @@ static unsigned long ccu_iosc_32k_recalc_rate(struct clk_hw *hw, struct ccu_common *cm = hw_to_ccu_common(hw); u32 val; - if (have_iosc_calibration) { + if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) { val = readl(cm->base + IOSC_CLK_CALI_REG); /* Assume the calibrated 32k clock is accurate. */ @@ -167,7 +171,7 @@ static unsigned long ccu_iosc_32k_recalc_accuracy(struct clk_hw *hw, struct ccu_common *cm = hw_to_ccu_common(hw); u32 val; - if (have_iosc_calibration) { + if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) { val = readl(cm->base + IOSC_CLK_CALI_REG); /* Assume the calibrated 32k clock is accurate. */ @@ -191,10 +195,8 @@ static struct ccu_common iosc_32k_clk = { CLK_GET_RATE_NOCACHE), }; -static const struct clk_hw *ext_osc32k[] = { NULL }; /* updated during probe */ - -static SUNXI_CCU_GATE_HWS(ext_osc32k_gate_clk, "ext-osc32k-gate", - ext_osc32k, 0x0, BIT(4), 0); +static SUNXI_CCU_GATE_FW(ext_osc32k_gate_clk, "ext-osc32k-gate", + "ext-osc32k", 0x0, BIT(4), 0); static const struct clk_hw *osc32k_parents[] = { &iosc_32k_clk.hw, @@ -217,22 +219,50 @@ static struct ccu_mux osc32k_clk = { }, }; -/* This falls back to the global name for fwnodes without a named reference. */ +/* + * This falls back to the global name for fwnodes without a named reference. + * NOTE: osc24M name might be misleading the oscillator could also be a 26MHz + * or a 19.2MHz one starting with the a733. The original name is kept anyway + * in case anything is relying on it. + */ static const struct clk_parent_data osc24M[] = { { .fw_name = "hosc", .name = "osc24M" } }; -static struct ccu_gate osc24M_32k_clk = { - .enable = BIT(16), +static struct clk_fixed_factor osc24M_32k_div_clk = { + .mult = 1, + .div = 750, + .hw.init = CLK_HW_INIT_PARENTS_DATA("osc24M-32k-div", + osc24M, + &clk_fixed_factor_ops, + 0), +}; + +static struct clk_div_table osc24M_32k_div_a733_table[] = { + { .val = 0, .div = 732 }, + { .val = 1, .div = 586 }, + { .val = 2, .div = 793 }, + { .val = 3, .div = 732 }, + { /* Sentinel */ }, +}; + +static struct ccu_div osc24M_32k_div_a733_clk = { + .enable = BIT(1), + .div = _SUNXI_CCU_DIV_TABLE_FLAGS(14, 2, + osc24M_32k_div_a733_table, + CLK_DIVIDER_READ_ONLY), .common = { - .reg = LOSC_OUT_GATING_REG, - .prediv = 750, - .features = CCU_FEATURE_ALL_PREDIV, - .hw.init = CLK_HW_INIT_PARENTS_DATA("osc24M-32k", osc24M, - &ccu_gate_ops, 0), + .reg = DCXO_CTRL_REG, + .hw.init = CLK_HW_INIT_PARENTS_DATA("osc24M-32k-div", + osc24M, + &ccu_rodiv_ops, + 0), }, }; +static SUNXI_CCU_GATE(osc24M_32k_clk, "osc24M-32k", "osc24M-32k-div", + LOSC_OUT_GATING_REG, BIT(16), 0); + static const struct clk_hw *rtc_32k_parents[] = { &osc32k_clk.common.hw, &osc24M_32k_clk.common.hw @@ -270,6 +300,15 @@ static struct ccu_mux osc32k_fanout_clk = { }, }; +static SUNXI_CCU_GATE_FW(hosc_serdes1_clk, "hosc-serdes1", "hosc", + DCXO_GATING_REG, BIT(5), 0); +static SUNXI_CCU_GATE_FW(hosc_serdes0_clk, "hosc-serdes0", "hosc", + DCXO_GATING_REG, BIT(4), 0); +static SUNXI_CCU_GATE_FW(hosc_hdmi_clk, "hosc-hdmi", "hosc", + DCXO_GATING_REG, BIT(1), 0); +static SUNXI_CCU_GATE_FW(hosc_ufs_clk, "hosc-ufs", "hosc", + DCXO_GATING_REG, BIT(0), 0); + static struct ccu_common *sun6i_rtc_ccu_clks[] = { &iosc_clk, &iosc_32k_clk, @@ -278,6 +317,11 @@ static struct ccu_common *sun6i_rtc_ccu_clks[] = { &osc24M_32k_clk.common, &rtc_32k_clk.common, &osc32k_fanout_clk.common, + &osc24M_32k_div_a733_clk.common, + &hosc_serdes1_clk.common, + &hosc_serdes0_clk.common, + &hosc_hdmi_clk.common, + &hosc_ufs_clk.common, }; static struct clk_hw_onecell_data sun6i_rtc_ccu_hw_clks = { @@ -290,6 +334,11 @@ static struct clk_hw_onecell_data sun6i_rtc_ccu_hw_clks = { [CLK_EXT_OSC32K_GATE] = &ext_osc32k_gate_clk.common.hw, [CLK_OSC24M_32K] = &osc24M_32k_clk.common.hw, [CLK_RTC_32K] = &rtc_32k_clk.common.hw, + [CLK_OSC24M_32K_DIV] = &osc24M_32k_div_clk.hw, + [CLK_HOSC_UFS] = &hosc_ufs_clk.common.hw, + [CLK_HOSC_HDMI] = &hosc_hdmi_clk.common.hw, + [CLK_HOSC_SERDES0] = &hosc_serdes0_clk.common.hw, + [CLK_HOSC_SERDES1] = &hosc_serdes1_clk.common.hw, }, }; @@ -332,6 +381,15 @@ static const struct sun6i_rtc_match_data sun55i_a523_rtc_ccu_data = { .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents), }; +static const struct sun6i_rtc_match_data sun60i_a733_rtc_ccu_data = { + .have_ext_osc32k = true, + .have_iosc_calibration = true, + .have_dcxo_status = true, + .have_phy_ref_gates = true, + .osc32k_fanout_parents = sun50i_r329_osc32k_fanout_parents, + .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents), +}; + static const struct of_device_id sun6i_rtc_ccu_match[] = { { .compatible = "allwinner,sun50i-h616-rtc", @@ -345,6 +403,10 @@ static const struct of_device_id sun6i_rtc_ccu_match[] = { .compatible = "allwinner,sun55i-a523-rtc", .data = &sun55i_a523_rtc_ccu_data, }, + { + .compatible = "allwinner,sun60i-a733-rtc", + .data = &sun60i_a733_rtc_ccu_data, + }, {}, }; MODULE_DEVICE_TABLE(of, sun6i_rtc_ccu_match); @@ -352,7 +414,6 @@ MODULE_DEVICE_TABLE(of, sun6i_rtc_ccu_match); int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg) { const struct sun6i_rtc_match_data *data; - struct clk *ext_osc32k_clk = NULL; const struct of_device_id *match; /* This driver is only used for newer variants of the hardware. */ @@ -361,23 +422,12 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg) return 0; data = match->data; - have_iosc_calibration = data->have_iosc_calibration; - - if (data->have_ext_osc32k) { - const char *fw_name; - - /* ext-osc32k was the only input clock in the old binding. */ - fw_name = of_property_present(dev->of_node, "clock-names") - ? "ext-osc32k" : NULL; - ext_osc32k_clk = devm_clk_get_optional(dev, fw_name); - if (IS_ERR(ext_osc32k_clk)) - return PTR_ERR(ext_osc32k_clk); + if (data->have_iosc_calibration) { + iosc_clk.features |= CCU_FEATURE_IOSC_CALIBRATION; + iosc_32k_clk.features |= CCU_FEATURE_IOSC_CALIBRATION; } - if (ext_osc32k_clk) { - /* Link ext-osc32k-gate to its parent. */ - *ext_osc32k = __clk_get_hw(ext_osc32k_clk); - } else { + if (!data->have_ext_osc32k) { /* ext-osc32k-gate is an orphan, so do not register it. */ sun6i_rtc_ccu_hw_clks.hws[CLK_EXT_OSC32K_GATE] = NULL; osc32k_init_data.num_parents = 1; @@ -389,6 +439,13 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg) osc32k_fanout_init_data.parent_data = data->osc32k_fanout_parents; osc32k_fanout_init_data.num_parents = data->osc32k_fanout_nparents; + if (data->have_dcxo_status) + sun6i_rtc_ccu_hw_clks.hws[CLK_OSC24M_32K_DIV] = + &osc24M_32k_div_a733_clk.common.hw; + + if (!data->have_phy_ref_gates) + sun6i_rtc_ccu_hw_clks.num = CLK_NUMBER_NO_GATES; + return devm_sunxi_ccu_probe(dev, reg, &sun6i_rtc_ccu_desc); } diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h index 9ae821fc2599..4f4f4cb00f1d 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h +++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.h @@ -9,7 +9,8 @@ #define CLK_EXT_OSC32K_GATE 4 #define CLK_OSC24M_32K 5 #define CLK_RTC_32K 6 +#define CLK_OSC24M_32K_DIV 7 -#define CLK_NUMBER (CLK_RTC_32K + 1) +#define CLK_NUMBER (CLK_HOSC_SERDES1 + 1) #endif /* _CCU_SUN6I_RTC_H */ diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c index 1c083b4d0b7e..43d8eca6abee 100644 --- a/drivers/clk/sunxi-ng/ccu_common.c +++ b/drivers/clk/sunxi-ng/ccu_common.c @@ -114,7 +114,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, const struct sunxi_ccu_desc *desc) { struct ccu_reset *reset; - int i, ret; + int i, j, ret; ccu->desc = desc; @@ -130,8 +130,8 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, cclk->lock = &ccu->lock; } - for (i = 0; i < desc->hw_clks->num ; i++) { - struct clk_hw *hw = desc->hw_clks->hws[i]; + for (j = 0; j < desc->hw_clks->num ; j++) { + struct clk_hw *hw = desc->hw_clks->hws[j]; const char *name; if (!hw) @@ -143,7 +143,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, else ret = of_clk_hw_register(node, hw); if (ret) { - pr_err("Couldn't register clock %d - %s\n", i, name); + pr_err("Couldn't register clock %d - %s\n", j, name); goto err_clk_unreg; } } @@ -186,8 +186,8 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, err_del_provider: of_clk_del_provider(node); err_clk_unreg: - while (--i >= 0) { - struct clk_hw *hw = desc->hw_clks->hws[i]; + while (--j >= 0) { + struct clk_hw *hw = desc->hw_clks->hws[j]; if (!hw) continue; diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h index bbec283b9d99..d9dc24ad5503 100644 --- a/drivers/clk/sunxi-ng/ccu_common.h +++ b/drivers/clk/sunxi-ng/ccu_common.h @@ -21,6 +21,7 @@ #define CCU_FEATURE_CLOSEST_RATE BIT(9) #define CCU_FEATURE_DUAL_DIV BIT(10) #define CCU_FEATURE_UPDATE_BIT BIT(11) +#define CCU_FEATURE_IOSC_CALIBRATION BIT(12) /* MMC timing mode switch bit */ #define CCU_MMC_NEW_TIMING_MODE BIT(30) diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c index 62d680ccb524..c385e0160f13 100644 --- a/drivers/clk/sunxi-ng/ccu_div.c +++ b/drivers/clk/sunxi-ng/ccu_div.c @@ -20,8 +20,22 @@ static int ccu_div_determine_rate_helper(struct ccu_mux_internal *mux, if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) req->rate *= cd->fixed_post_div; - ret = divider_determine_rate(&cd->common.hw, req, cd->div.table, - cd->div.width, cd->div.flags); + if (cd->div.flags & CLK_DIVIDER_READ_ONLY) { + unsigned long val; + u32 reg; + + reg = readl(cd->common.base + cd->common.reg); + val = reg >> cd->div.shift; + val &= (1 << cd->div.width) - 1; + + ret = divider_ro_determine_rate(&cd->common.hw, req, cd->div.table, + cd->div.width, cd->div.flags, val); + + } else { + ret = divider_determine_rate(&cd->common.hw, req, cd->div.table, + cd->div.width, cd->div.flags); + } + if (ret) return ret; @@ -143,3 +157,16 @@ const struct clk_ops ccu_div_ops = { .set_rate = ccu_div_set_rate, }; EXPORT_SYMBOL_NS_GPL(ccu_div_ops, "SUNXI_CCU"); + +const struct clk_ops ccu_rodiv_ops = { + .disable = ccu_div_disable, + .enable = ccu_div_enable, + .is_enabled = ccu_div_is_enabled, + + .get_parent = ccu_div_get_parent, + .set_parent = ccu_div_set_parent, + + .determine_rate = ccu_div_determine_rate, + .recalc_rate = ccu_div_recalc_rate, +}; +EXPORT_SYMBOL_NS_GPL(ccu_rodiv_ops, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h index be00b3277e97..a30a92780a05 100644 --- a/drivers/clk/sunxi-ng/ccu_div.h +++ b/drivers/clk/sunxi-ng/ccu_div.h @@ -300,5 +300,6 @@ static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw) } extern const struct clk_ops ccu_div_ops; +extern const struct clk_ops ccu_rodiv_ops; #endif /* _CCU_DIV_H_ */ diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c index 766f27cff748..4503c9780c39 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.c +++ b/drivers/clk/sunxi-ng/ccu_mux.c @@ -66,7 +66,6 @@ unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common, { return parent_rate / ccu_mux_get_prediv(common, cm, parent_index); } -EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_apply_prediv, "SUNXI_CCU"); static unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common, struct ccu_mux_internal *cm, @@ -93,66 +92,65 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common, struct clk_rate_request adj_req = *req; best_parent = clk_hw_get_parent(hw); - best_parent_rate = clk_hw_get_rate(best_parent); - + adj_req.best_parent_rate = clk_hw_get_rate(best_parent); adj_req.best_parent_hw = best_parent; - adj_req.best_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1, - best_parent_rate); + + /* + * This effectively treats the predivider as a postdivider. + * It stays mathematically correct and ensures whatever + * round() will do stays correct while walking the tree. + * It may query the parent rate too while handling rate + * propagation. + */ + adj_req.rate = ccu_mux_helper_unapply_prediv(common, cm, -1, + req->rate); ret = round(cm, &adj_req, data); if (ret) return ret; - best_rate = adj_req.rate; - /* - * best_parent_rate might have been modified by our clock. - * Unapply the pre-divider if there's one, and give - * the actual frequency the parent needs to run at. + * parent_rate might have been modified by our clock as part + * of the rate propagation mechanism. Same goes below. */ - best_parent_rate = ccu_mux_helper_unapply_prediv(common, cm, -1, - adj_req.best_parent_rate); + best_parent_rate = adj_req.best_parent_rate; + best_rate = ccu_mux_helper_apply_prediv(common, cm, -1, + adj_req.rate); goto out; } for (i = 0; i < clk_hw_get_num_parents(hw); i++) { struct clk_rate_request tmp_req = *req; - unsigned long parent_rate; + unsigned long rate; struct clk_hw *parent; parent = clk_hw_get_parent_by_index(hw, i); if (!parent) continue; - parent_rate = ccu_mux_helper_apply_prediv(common, cm, i, - clk_hw_get_rate(parent)); - tmp_req.best_parent_hw = parent; - tmp_req.best_parent_rate = parent_rate; + tmp_req.best_parent_rate = clk_hw_get_rate(parent); + tmp_req.rate = ccu_mux_helper_unapply_prediv(common, cm, i, + req->rate); ret = round(cm, &tmp_req, data); if (ret) continue; - /* - * parent_rate might have been modified by our clock. - * Unapply the pre-divider if there's one, and give - * the actual frequency the parent needs to run at. - */ - parent_rate = ccu_mux_helper_unapply_prediv(common, cm, i, - tmp_req.best_parent_rate); + rate = ccu_mux_helper_apply_prediv(common, cm, i, + tmp_req.rate); - if (tmp_req.rate == req->rate) { + if (rate == req->rate) { best_parent = parent; - best_parent_rate = parent_rate; - best_rate = tmp_req.rate; + best_parent_rate = tmp_req.best_parent_rate; + best_rate = rate; goto out; } - if (ccu_is_better_rate(common, req->rate, tmp_req.rate, best_rate)) { - best_rate = tmp_req.rate; - best_parent_rate = parent_rate; + if (ccu_is_better_rate(common, req->rate, rate, best_rate)) { + best_rate = rate; + best_parent_rate = tmp_req.best_parent_rate; best_parent = parent; } } diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c index f6d2b934228b..067a8555c4e7 100644 --- a/drivers/clk/tegra/clk-bpmp.c +++ b/drivers/clk/tegra/clk-bpmp.c @@ -367,7 +367,15 @@ static int tegra_bpmp_clk_get_info(struct tegra_bpmp *bpmp, unsigned int id, if (err < 0) return err; - strscpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN); + if (dev_to_node(bpmp->dev) == NUMA_NO_NODE) { + strscpy(info->name, response.name, sizeof(info->name)); + } else { + err = snprintf(info->name, sizeof(info->name), "%d-%s", + dev_to_node(bpmp->dev), response.name); + if (WARN_ON(err >= sizeof(info->name))) + return -E2BIG; + } + info->num_parents = response.num_parents; for (i = 0; i < info->num_parents; i++) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index d86003b6d94f..adfb74f111ef 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -575,6 +575,7 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, break; case 9600000: case 28800000: + case 48000000: /* * PLL_P_OUT1 rate is not listed in PLLA table */ diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index a4f40533cc43..f1bca81b7776 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -620,10 +620,6 @@ static const char *mux_plld_out0_plld2_out0[] = { }; #define mux_plld_out0_plld2_out0_idx NULL -static const char *mux_pllmcp_clkm[] = { - "pll_m_out0", "pll_c_out0", "pll_p_out0", "clk_m", "pll_m_ud", -}; - static const struct clk_div_table pll_re_div_table[] = { { .val = 0, .div = 1 }, { .val = 1, .div = 2 }, @@ -670,7 +666,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { [tegra_clk_csi] = { .dt_id = TEGRA114_CLK_CSI, .present = true }, [tegra_clk_i2c2] = { .dt_id = TEGRA114_CLK_I2C2, .present = true }, [tegra_clk_uartc] = { .dt_id = TEGRA114_CLK_UARTC, .present = true }, - [tegra_clk_emc] = { .dt_id = TEGRA114_CLK_EMC, .present = true }, [tegra_clk_usb2] = { .dt_id = TEGRA114_CLK_USB2, .present = true }, [tegra_clk_usb3] = { .dt_id = TEGRA114_CLK_USB3, .present = true }, [tegra_clk_vde_8] = { .dt_id = TEGRA114_CLK_VDE, .present = true }, @@ -1051,14 +1046,7 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base, periph_clk_enb_refcnt); clks[TEGRA114_CLK_CSUS] = clk; - /* emc mux */ - clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, - ARRAY_SIZE(mux_pllmcp_clkm), - CLK_SET_RATE_NO_REPARENT, - clk_base + CLK_SOURCE_EMC, - 29, 3, 0, &emc_lock); - - clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, + clk = tegra_clk_register_mc("mc", "emc", clk_base + CLK_SOURCE_EMC, &emc_lock); clks[TEGRA114_CLK_MC] = clk; @@ -1324,6 +1312,26 @@ static int tegra114_reset_deassert(unsigned long id) return 0; } +static struct clk *tegra114_clk_src_onecell_get(struct of_phandle_args *clkspec, + void *data) +{ + struct clk_hw *hw; + struct clk *clk; + + clk = of_clk_src_onecell_get(clkspec, data); + if (IS_ERR(clk)) + return clk; + + hw = __clk_get_hw(clk); + + if (clkspec->args[0] == TEGRA114_CLK_EMC) { + if (!tegra124_clk_emc_driver_available(hw)) + return ERR_PTR(-EPROBE_DEFER); + } + + return clk; +} + static void __init tegra114_clock_init(struct device_node *np) { struct device_node *node; @@ -1371,7 +1379,10 @@ static void __init tegra114_clock_init(struct device_node *np) tegra_init_special_resets(1, tegra114_reset_assert, tegra114_reset_deassert); - tegra_add_of_provider(np, of_clk_src_onecell_get); + tegra_add_of_provider(np, tegra114_clk_src_onecell_get); + clks[TEGRA114_CLK_EMC] = tegra124_clk_register_emc(clk_base, np, + &emc_lock); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); tegra_clk_apply_init_table = tegra114_clock_apply_init_table; diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c index f3b2c96fdcfc..94ac24ea1e6a 100644 --- a/drivers/clk/tegra/clk-tegra124-emc.c +++ b/drivers/clk/tegra/clk-tegra124-emc.c @@ -537,6 +537,7 @@ struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np clk = clk_register(NULL, &tegra->hw); if (IS_ERR(clk)) { + of_node_put(tegra->emc_node); kfree(tegra); return clk; } diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 0c86cff719e3..df1d7b471745 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -1460,7 +1460,7 @@ static int tegra210_pllx_dyn_ramp(struct tegra_clk_pll *pllx, udelay(1); pr_debug("%s: dynamic ramp to m = %u n = %u p = %u, Fout = %lu kHz\n", - __clk_get_name(pllx->hw.clk), cfg->m, cfg->n, cfg->p, + clk_hw_get_name(&pllx->hw), cfg->m, cfg->n, cfg->p, cfg->input_rate / cfg->m * cfg->n / pllx->params->pdiv_tohw[cfg->p].pdiv / 1000); diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c index e305fcbac647..8885d28face5 100644 --- a/drivers/clk/ti/adpll.c +++ b/drivers/clk/ti/adpll.c @@ -483,7 +483,7 @@ static const struct clk_ops ti_adpll_ops = { static int ti_adpll_init_dco(struct ti_adpll_data *d) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk *clock; const char *postfix; int width, err; @@ -576,7 +576,7 @@ static int ti_adpll_init_clkout(struct ti_adpll_data *d, struct clk *clk1) { struct ti_adpll_clkout_data *co; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_ops *ops; const char *parent_names[2]; const char *child_name; diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c index c379bbdae25a..01eae8995254 100644 --- a/drivers/clk/ti/composite.c +++ b/drivers/clk/ti/composite.c @@ -52,7 +52,7 @@ static const struct clk_ops ti_composite_gate_ops = { struct component_clk { int num_parents; - const char **parent_names; + struct clk_parent_data *parent_data; struct device_node *node; int type; struct clk_hw *hw; @@ -116,7 +116,7 @@ static void __init _register_composite(void *user, struct clk_hw_omap_comp *cclk = to_clk_hw_comp(hw); struct component_clk *comp; int num_parents = 0; - const char **parent_names = NULL; + struct clk_parent_data *parent_data = NULL; const char *name; int i; int ret; @@ -155,7 +155,7 @@ static void __init _register_composite(void *user, continue; if (comp->num_parents) { num_parents = comp->num_parents; - parent_names = comp->parent_names; + parent_data = comp->parent_data; break; } } @@ -166,8 +166,8 @@ static void __init _register_composite(void *user, } name = ti_dt_clk_name(node); - clk = clk_register_composite(NULL, name, - parent_names, num_parents, + clk = clk_register_composite_pdata(NULL, name, + parent_data, num_parents, _get_hw(cclk, CLK_COMPONENT_TYPE_MUX), &ti_clk_mux_ops, _get_hw(cclk, CLK_COMPONENT_TYPE_DIVIDER), @@ -190,7 +190,7 @@ cleanup: if (!cclk->comp_clks[i]) continue; list_del(&cclk->comp_clks[i]->link); - kfree(cclk->comp_clks[i]->parent_names); + kfree(cclk->comp_clks[i]->parent_data); kfree(cclk->comp_clks[i]); } @@ -237,8 +237,9 @@ int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type) { unsigned int num_parents; - const char **parent_names; + struct clk_parent_data *parent_data; struct component_clk *clk; + unsigned int i; num_parents = of_clk_get_parent_count(node); @@ -247,20 +248,21 @@ int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw, return -EINVAL; } - parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); - if (!parent_names) + parent_data = kcalloc(num_parents, sizeof(*parent_data), GFP_KERNEL); + if (!parent_data) return -ENOMEM; - of_clk_parent_fill(node, parent_names, num_parents); + for (i = 0; i < num_parents; i++) + parent_data[i].index = i; clk = kzalloc_obj(*clk); if (!clk) { - kfree(parent_names); + kfree(parent_data); return -ENOMEM; } clk->num_parents = num_parents; - clk->parent_names = parent_names; + clk->parent_data = parent_data; clk->hw = hw; clk->node = node; clk->type = type; diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index af923b8cb0ed..3b438c2d68aa 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -311,7 +311,7 @@ static struct clk *_register_divider(struct device_node *node, u32 flags, struct clk_omap_divider *div) { - struct clk_init_data init; + struct clk_init_data init = {}; const char *parent_name; const char *name; diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index d6a0ccfd81db..0fef60e82107 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c @@ -119,14 +119,14 @@ const struct clk_ops ti_clk_mux_ops = { }; static struct clk *_register_mux(struct device_node *node, const char *name, - const char * const *parent_names, + const struct clk_parent_data *parent_data, u8 num_parents, unsigned long flags, struct clk_omap_reg *reg, u8 shift, u32 mask, s8 latch, u8 clk_mux_flags, u32 *table) { + struct clk_init_data init = {}; struct clk_omap_mux *mux; struct clk *clk; - struct clk_init_data init; /* allocate the mux */ mux = kzalloc_obj(*mux); @@ -136,7 +136,7 @@ static struct clk *_register_mux(struct device_node *node, const char *name, init.name = name; init.ops = &ti_clk_mux_ops; init.flags = flags; - init.parent_names = parent_names; + init.parent_data = parent_data; init.num_parents = num_parents; /* struct clk_mux assignments */ @@ -167,24 +167,26 @@ static void of_mux_clk_setup(struct device_node *node) struct clk *clk; struct clk_omap_reg reg; unsigned int num_parents; - const char **parent_names; + struct clk_parent_data *parent_data; const char *name; u8 clk_mux_flags = 0; u32 mask = 0; u32 shift = 0; s32 latch = -EINVAL; u32 flags = CLK_SET_RATE_NO_REPARENT; + int i; num_parents = of_clk_get_parent_count(node); if (num_parents < 2) { pr_err("mux-clock %pOFn must have parents\n", node); return; } - parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); - if (!parent_names) - goto cleanup; + parent_data = kcalloc(num_parents, sizeof(*parent_data), GFP_KERNEL); + if (!parent_data) + return; - of_clk_parent_fill(node, parent_names, num_parents); + for (i = 0; i < num_parents; i++) + parent_data[i].index = i; if (ti_clk_get_reg_addr(node, 0, ®)) goto cleanup; @@ -207,7 +209,7 @@ static void of_mux_clk_setup(struct device_node *node) mask = (1 << fls(mask)) - 1; name = ti_dt_clk_name(node); - clk = _register_mux(node, name, parent_names, num_parents, + clk = _register_mux(node, name, parent_data, num_parents, flags, ®, shift, mask, latch, clk_mux_flags, NULL); @@ -215,7 +217,7 @@ static void of_mux_clk_setup(struct device_node *node) of_clk_add_provider(node, of_clk_src_simple_get, clk); cleanup: - kfree(parent_names); + kfree(parent_data); } CLK_OF_DECLARE(mux_clk, "ti,mux-clock", of_mux_clk_setup); diff --git a/drivers/clk/ultrarisc/Kconfig b/drivers/clk/ultrarisc/Kconfig new file mode 100644 index 000000000000..2eecc6ac3119 --- /dev/null +++ b/drivers/clk/ultrarisc/Kconfig @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config CLK_ULTRARISC + tristate + depends on OF + depends on ARCH_ULTRARISC || COMPILE_TEST + +config CLK_ULTRARISC_DP1000 + tristate "UltraRISC DP1000 clock controller" + select CLK_ULTRARISC + depends on OF && HAS_IOMEM + depends on ARCH_ULTRARISC || COMPILE_TEST + default ARCH_ULTRARISC + help + This driver provides the clock controller for the UltraRISC + DP1000 SoC. It exposes the PLL output, derived fixed-factor + clocks, programmable divider clocks, and peripheral gate + clocks to Linux consumers. diff --git a/drivers/clk/ultrarisc/Makefile b/drivers/clk/ultrarisc/Makefile new file mode 100644 index 000000000000..b013708c9444 --- /dev/null +++ b/drivers/clk/ultrarisc/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_CLK_ULTRARISC) += clk-ultrarisc.o +obj-$(CONFIG_CLK_ULTRARISC_DP1000) += clk-dp1000.o diff --git a/drivers/clk/ultrarisc/clk-dp1000.c b/drivers/clk/ultrarisc/clk-dp1000.c new file mode 100644 index 000000000000..ffea77c4cca0 --- /dev/null +++ b/drivers/clk/ultrarisc/clk-dp1000.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd. + */ + +#include + +#include + +#include "clk-ultrarisc.h" + +#define DP1000_PLL_CFG1_OFFSET 0x400 +#define DP1000_PLL_CFG2_OFFSET 0x404 + +#define DP1000_CCR_UART_OFFSET 0x220 +#define DP1000_CCR_I2C_OFFSET 0x224 +#define DP1000_CCR_GMAC_OFFSET 0x228 +#define DP1000_CCR_SPI_OFFSET 0x22c +#define DP1000_PERI_CLKENA_OFFSET 0x270 + +#define DP1000_CCR_LOAD BIT(16) + +#define DP1000_PERI_MAX_RATE 62500000UL +#define DP1000_CLK_NUM 21 + +static const struct ultrarisc_pll_layout dp1000_pll_layout = { + .cfg1_offset = DP1000_PLL_CFG1_OFFSET, + .cfg2_offset = DP1000_PLL_CFG2_OFFSET, + .frac_mask = GENMASK(23, 0), + .m_mask = GENMASK(23, 16), + .n_mask = GENMASK(11, 6), + .oddiv1_mask = GENMASK(1, 0), + .oddiv2_mask = GENMASK(4, 3), +}; + +static const struct ultrarisc_pll_desc dp1000_plls[] = { + { + .id = DP1000_CLK_SYSPLL, + .name = "syspll_clk", + }, +}; + +#define DP1000_FIXED_FACTOR(_id, _name, _parent, _mult, _div) \ + { \ + .id = (_id), \ + .name = (_name), \ + .parent_id = (_parent), \ + .mult = (_mult), \ + .div = (_div), \ + } + +#define DP1000_DIV(_id, _name, _offset, _parent, _max_rate) \ + { \ + .id = (_id), \ + .name = (_name), \ + .offset = (_offset), \ + .parent_id = (_parent), \ + .max_rate = (_max_rate), \ + .load_mask = DP1000_CCR_LOAD, \ + .div_shift = 8, \ + .div_width = 4, \ + .gate_bit = 0, \ + .divider_flags = CLK_DIVIDER_ONE_BASED, \ + .gate_flags = 0, \ + } + +#define DP1000_GATE(_id, _name, _parent, _bit) \ + { \ + .id = (_id), \ + .name = (_name), \ + .offset = DP1000_PERI_CLKENA_OFFSET, \ + .parent_id = (_parent), \ + .gate_bit = (_bit), \ + .gate_flags = 0, \ + } + +static const struct ultrarisc_fixed_factor_desc dp1000_fixed_factor_clks[] = { + DP1000_FIXED_FACTOR(DP1000_CLK_SYSPLL_DIV2, "syspll_div2_clk", + DP1000_CLK_SYSPLL, 1, 2), + DP1000_FIXED_FACTOR(DP1000_CLK_SUBSYS, "subsys_clk", + DP1000_CLK_SYSPLL_DIV2, 1, 2), + DP1000_FIXED_FACTOR(DP1000_CLK_PCIE_DBI, "pcie_dbi_clk", + DP1000_CLK_SYSPLL, 1, 10), + DP1000_FIXED_FACTOR(DP1000_CLK_PCIEX4_CORE, "pciex4_core_clk", + DP1000_CLK_SYSPLL, 1, 2), + DP1000_FIXED_FACTOR(DP1000_CLK_PCIEX16_CORE, "pciex16_core_clk", + DP1000_CLK_SYSPLL, 1, 1), + DP1000_FIXED_FACTOR(DP1000_CLK_PCIE_AUX, "pcie_aux_clk", + DP1000_CLK_SYSPLL, 1, 40), +}; + +static const struct ultrarisc_divider_desc dp1000_divider_clks[] = { + DP1000_DIV(DP1000_CLK_GMAC, "gmac_clk", DP1000_CCR_GMAC_OFFSET, + DP1000_CLK_SYSPLL_DIV2, 0), + DP1000_DIV(DP1000_CLK_UART_ROOT, "uart_root_clk", + DP1000_CCR_UART_OFFSET, DP1000_CLK_SUBSYS, + DP1000_PERI_MAX_RATE), + DP1000_DIV(DP1000_CLK_I2C_ROOT, "i2c_root_clk", + DP1000_CCR_I2C_OFFSET, DP1000_CLK_SUBSYS, + DP1000_PERI_MAX_RATE), + DP1000_DIV(DP1000_CLK_SPI_ROOT, "spi_root_clk", + DP1000_CCR_SPI_OFFSET, DP1000_CLK_SUBSYS, + DP1000_PERI_MAX_RATE), +}; + +static const struct ultrarisc_gate_desc dp1000_gate_clks[] = { + DP1000_GATE(DP1000_CLK_UART0, "uart0_clk", DP1000_CLK_UART_ROOT, 0), + DP1000_GATE(DP1000_CLK_UART1, "uart1_clk", DP1000_CLK_UART_ROOT, 1), + DP1000_GATE(DP1000_CLK_UART2, "uart2_clk", DP1000_CLK_UART_ROOT, 2), + DP1000_GATE(DP1000_CLK_UART3, "uart3_clk", DP1000_CLK_UART_ROOT, 3), + DP1000_GATE(DP1000_CLK_I2C0, "i2c0_clk", DP1000_CLK_I2C_ROOT, 4), + DP1000_GATE(DP1000_CLK_I2C1, "i2c1_clk", DP1000_CLK_I2C_ROOT, 5), + DP1000_GATE(DP1000_CLK_I2C2, "i2c2_clk", DP1000_CLK_I2C_ROOT, 6), + DP1000_GATE(DP1000_CLK_I2C3, "i2c3_clk", DP1000_CLK_I2C_ROOT, 7), + DP1000_GATE(DP1000_CLK_SPI0, "spi0_clk", DP1000_CLK_SPI_ROOT, 8), + DP1000_GATE(DP1000_CLK_SPI1, "spi1_clk", DP1000_CLK_SPI_ROOT, 9), +}; + +static const struct ultrarisc_clk_soc_data dp1000_clk_soc_data = { + .num_clks = DP1000_CLK_NUM, + .pll_layout = &dp1000_pll_layout, + .plls = dp1000_plls, + .num_plls = ARRAY_SIZE(dp1000_plls), + .fixed_factors = dp1000_fixed_factor_clks, + .num_fixed_factors = ARRAY_SIZE(dp1000_fixed_factor_clks), + .dividers = dp1000_divider_clks, + .num_dividers = ARRAY_SIZE(dp1000_divider_clks), + .gates = dp1000_gate_clks, + .num_gates = ARRAY_SIZE(dp1000_gate_clks), +}; + +static int dp1000_clk_probe(struct platform_device *pdev) +{ + return ultrarisc_clk_probe(pdev, &dp1000_clk_soc_data); +} + +static const struct of_device_id dp1000_clk_of_match[] = { + { .compatible = "ultrarisc,dp1000-clk" }, + { } +}; +MODULE_DEVICE_TABLE(of, dp1000_clk_of_match); + +static struct platform_driver dp1000_clk_driver = { + .probe = dp1000_clk_probe, + .driver = { + .name = "ultrarisc-dp1000-clk", + .of_match_table = dp1000_clk_of_match, + }, +}; +module_platform_driver(dp1000_clk_driver); + +MODULE_IMPORT_NS("CLK_ULTRARISC"); +MODULE_DESCRIPTION("UltraRISC DP1000 clock controller"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/ultrarisc/clk-ultrarisc.c b/drivers/clk/ultrarisc/clk-ultrarisc.c new file mode 100644 index 000000000000..bbcd2234ea71 --- /dev/null +++ b/drivers/clk/ultrarisc/clk-ultrarisc.c @@ -0,0 +1,399 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include + +#include "clk-ultrarisc.h" + +struct ultrarisc_pll_clk { + struct clk_hw hw; + void __iomem *base; + const struct ultrarisc_pll_layout *layout; +}; + +struct ultrarisc_divider_clk { + struct clk_divider divider; + struct clk_gate gate; + u32 load_mask; +}; + +#define to_ultrarisc_pll_clk(_hw) \ + container_of(_hw, struct ultrarisc_pll_clk, hw) + +static inline struct ultrarisc_divider_clk *to_ultrarisc_divider_clk(struct clk_hw *hw) +{ + struct clk_divider *divider = to_clk_divider(hw); + + return container_of(divider, struct ultrarisc_divider_clk, divider); +} + +static unsigned long ultrarisc_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ultrarisc_pll_clk *pll = to_ultrarisc_pll_clk(hw); + const struct ultrarisc_pll_layout *layout = pll->layout; + u32 oddiv1_div, oddiv2_div; + u64 mult, rate, den; + u32 frac, m, n; + u32 cfg1, cfg2; + + cfg1 = readl_relaxed(pll->base + layout->cfg1_offset); + cfg2 = readl_relaxed(pll->base + layout->cfg2_offset); + + frac = field_get(layout->frac_mask, cfg1); + m = field_get(layout->m_mask, cfg2); + n = field_get(layout->n_mask, cfg2); + if (!n) + return 0; + + oddiv1_div = 1U << field_get(layout->oddiv1_mask, cfg2); + oddiv2_div = 1U << field_get(layout->oddiv2_mask, cfg2); + + /* + * The output frequency is calculated as: + * fvco = parent * (m + frac / 2^24) / n + * fout = fvco / (2^oddiv1_raw * 2^oddiv2_raw) + * + * The output divider values are derived from the raw register field values as: + * oddivX_div = 1 << oddivX_raw + */ + mult = ((u64)m << 24) + frac; + rate = (u64)parent_rate * mult; + den = ((u64)n << 24) * oddiv1_div * oddiv2_div; + + return div64_u64(rate + (den >> 1), den); +} + +static const struct clk_ops ultrarisc_pll_ro_ops = { + .recalc_rate = ultrarisc_pll_recalc_rate, +}; + +static unsigned long ultrarisc_divider_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_divider *divider = to_clk_divider(hw); + u32 val; + + val = readl_relaxed(divider->reg) >> divider->shift; + val &= clk_div_mask(divider->width); + + return divider_recalc_rate(hw, parent_rate, val, divider->table, + divider->flags, divider->width); +} + +static int ultrarisc_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_divider *divider = to_clk_divider(hw); + + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); +} + +static int ultrarisc_divider_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct ultrarisc_divider_clk *divider_clk = to_ultrarisc_divider_clk(hw); + struct clk_divider *divider = ÷r_clk->divider; + int value; + u32 val; + + value = divider_get_val(rate, parent_rate, divider->table, + divider->width, divider->flags); + if (value < 0) + return value; + + scoped_guard(spinlock_irqsave, divider->lock) { + val = readl_relaxed(divider->reg); + val &= ~(clk_div_mask(divider->width) << divider->shift); + val |= value << divider->shift; + writel_relaxed(val, divider->reg); + + if (divider_clk->load_mask) { + /* + * Program the new divider field, then write 1 to the + * load bit to trigger the update. The load bit is + * write-triggered and reads back as 0 on this hardware. + */ + writel_relaxed(val | divider_clk->load_mask, divider->reg); + } + } + + return 0; +} + +static const struct clk_ops ultrarisc_divider_ops = { + .recalc_rate = ultrarisc_divider_recalc_rate, + .determine_rate = ultrarisc_divider_determine_rate, + .set_rate = ultrarisc_divider_set_rate, +}; + +static struct clk_hw *ultrarisc_clk_register_pll(struct device *dev, + const struct ultrarisc_pll_desc *desc, + const struct ultrarisc_pll_layout *layout, + void __iomem *base) +{ + struct clk_parent_data pdata = { .index = 0 }; + struct ultrarisc_pll_clk *pll; + struct clk_init_data init = { + .name = desc->name, + .ops = &ultrarisc_pll_ro_ops, + .parent_data = &pdata, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }; + int ret; + + pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + pll->base = base; + pll->layout = layout; + pll->hw.init = &init; + + ret = devm_clk_hw_register(dev, &pll->hw); + if (ret) + return ERR_PTR(ret); + + return &pll->hw; +} + +static struct clk_hw * +ultrarisc_clk_register_divider(struct device *dev, + const struct ultrarisc_divider_desc *desc, + struct clk_hw *parent_hw, void __iomem *base, + spinlock_t *lock) +{ + const struct clk_parent_data pdata = { .hw = parent_hw }; + void __iomem *reg = base + desc->offset; + struct ultrarisc_divider_clk *divider; + + if (!desc->div_width) + return ERR_PTR(-EINVAL); + + if (!lock) + return ERR_PTR(-EINVAL); + + divider = devm_kzalloc(dev, sizeof(*divider), GFP_KERNEL); + if (!divider) + return ERR_PTR(-ENOMEM); + + divider->divider.reg = reg; + divider->divider.shift = desc->div_shift; + divider->divider.width = desc->div_width; + divider->divider.flags = desc->divider_flags; + divider->divider.lock = lock; + divider->load_mask = desc->load_mask; + divider->gate.reg = reg; + divider->gate.bit_idx = desc->gate_bit; + divider->gate.flags = desc->gate_flags; + divider->gate.lock = lock; + + return devm_clk_hw_register_composite_pdata(dev, desc->name, + &pdata, 1, NULL, NULL, + ÷r->divider.hw, + &ultrarisc_divider_ops, + ÷r->gate.hw, + &clk_gate_ops, 0); +} + +static int ultrarisc_clk_register_fixed_factors(struct device *dev, + struct clk_hw_onecell_data *clk_data, + const struct ultrarisc_clk_soc_data *soc_data) +{ + u32 i; + + for (i = 0; i < soc_data->num_fixed_factors; i++) { + const struct ultrarisc_fixed_factor_desc *desc; + struct clk_hw *parent_hw; + struct clk_hw *hw; + + desc = &soc_data->fixed_factors[i]; + if (desc->id >= clk_data->num || desc->parent_id >= clk_data->num) + return -EINVAL; + + parent_hw = clk_data->hws[desc->parent_id]; + if (!parent_hw) + return -EINVAL; + + hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, desc->name, + parent_hw, 0, + desc->mult, + desc->div); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + clk_data->hws[desc->id] = hw; + } + + return 0; +} + +static int ultrarisc_clk_register_plls(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data, + const struct ultrarisc_clk_soc_data *soc_data, + void __iomem *base) +{ + struct device *dev = &pdev->dev; + u32 i; + + for (i = 0; i < soc_data->num_plls; i++) { + const struct ultrarisc_pll_desc *desc = &soc_data->plls[i]; + struct clk_hw *hw; + + if (desc->id >= clk_data->num) { + dev_err(dev, "%s invalid clock ID %u >= %u\n", + desc->name, desc->id, clk_data->num); + return -EINVAL; + } + + hw = ultrarisc_clk_register_pll(dev, desc, soc_data->pll_layout, base); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + clk_data->hws[desc->id] = hw; + } + + return 0; +} + +static int ultrarisc_clk_register_dividers(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data, + const struct ultrarisc_clk_soc_data *soc_data, + void __iomem *base, + spinlock_t *lock) +{ + struct device *dev = &pdev->dev; + u32 i; + + for (i = 0; i < soc_data->num_dividers; i++) { + const struct ultrarisc_divider_desc *desc; + struct clk_hw *parent_hw; + struct clk_hw *hw; + + desc = &soc_data->dividers[i]; + if (desc->id >= clk_data->num || desc->parent_id >= clk_data->num) + return -EINVAL; + + parent_hw = clk_data->hws[desc->parent_id]; + if (!parent_hw) + return -EINVAL; + + hw = ultrarisc_clk_register_divider(dev, desc, parent_hw, base, + lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + if (desc->max_rate) + clk_hw_set_rate_range(hw, 0, desc->max_rate); + + clk_data->hws[desc->id] = hw; + } + + return 0; +} + +static int ultrarisc_clk_register_gates(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data, + const struct ultrarisc_clk_soc_data *soc_data, + void __iomem *base, + spinlock_t *lock) +{ + struct device *dev = &pdev->dev; + u32 i; + + for (i = 0; i < soc_data->num_gates; i++) { + const struct ultrarisc_gate_desc *desc; + struct clk_hw *parent_hw; + struct clk_hw *hw; + + desc = &soc_data->gates[i]; + if (desc->id >= clk_data->num || desc->parent_id >= clk_data->num) + return -EINVAL; + + parent_hw = clk_data->hws[desc->parent_id]; + if (!parent_hw) + return -EINVAL; + + hw = devm_clk_hw_register_gate_parent_hw(dev, desc->name, + parent_hw, 0, + base + desc->offset, + desc->gate_bit, + desc->gate_flags, + lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + clk_data->hws[desc->id] = hw; + } + + return 0; +} + +int ultrarisc_clk_probe(struct platform_device *pdev, + const struct ultrarisc_clk_soc_data *soc_data) +{ + struct clk_hw_onecell_data *clk_data; + struct device *dev = &pdev->dev; + void __iomem *base; + spinlock_t *lock; + int ret; + + if (!soc_data) + return -EINVAL; + + lock = devm_kzalloc(dev, sizeof(*lock), GFP_KERNEL); + if (!lock) + return -ENOMEM; + + spin_lock_init(lock); + + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, + soc_data->num_clks), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->num = soc_data->num_clks; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + ret = ultrarisc_clk_register_plls(pdev, clk_data, soc_data, base); + if (ret) + return ret; + + ret = ultrarisc_clk_register_fixed_factors(dev, clk_data, soc_data); + if (ret) + return ret; + + ret = ultrarisc_clk_register_dividers(pdev, clk_data, soc_data, base, lock); + if (ret) + return ret; + + ret = ultrarisc_clk_register_gates(pdev, clk_data, soc_data, base, lock); + if (ret) + return ret; + + for (int i = 0; i < clk_data->num; i++) { + if (!clk_data->hws[i]) { + dev_err(dev, "missing clock ID %u\n", i); + return -EINVAL; + } + } + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); +} +EXPORT_SYMBOL_NS_GPL(ultrarisc_clk_probe, "CLK_ULTRARISC"); + +MODULE_DESCRIPTION("UltraRISC clock core driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/ultrarisc/clk-ultrarisc.h b/drivers/clk/ultrarisc/clk-ultrarisc.h new file mode 100644 index 000000000000..8202b7ed0e31 --- /dev/null +++ b/drivers/clk/ultrarisc/clk-ultrarisc.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ULTRARISC_CLK_ULTRARISC_H +#define __ULTRARISC_CLK_ULTRARISC_H + +#include +#include +#include + +struct ultrarisc_pll_layout { + u32 cfg1_offset; + u32 cfg2_offset; + u32 frac_mask; + u32 m_mask; + u32 n_mask; + u32 oddiv1_mask; + u32 oddiv2_mask; +}; + +struct ultrarisc_pll_desc { + u32 id; + const char *name; +}; + +struct ultrarisc_fixed_factor_desc { + u32 id; + const char *name; + u32 parent_id; + u32 mult; + u32 div; +}; + +struct ultrarisc_divider_desc { + u32 id; + const char *name; + u32 offset; + u32 parent_id; + unsigned long max_rate; + u32 load_mask; + u8 div_shift; + u8 div_width; + u8 gate_bit; + u16 divider_flags; + u8 gate_flags; +}; + +struct ultrarisc_gate_desc { + u32 id; + const char *name; + u32 offset; + u32 parent_id; + u8 gate_bit; + u8 gate_flags; +}; + +struct ultrarisc_clk_soc_data { + const struct ultrarisc_pll_layout *pll_layout; + const struct ultrarisc_pll_desc *plls; + u32 num_plls; + const struct ultrarisc_fixed_factor_desc *fixed_factors; + u32 num_fixed_factors; + const struct ultrarisc_divider_desc *dividers; + u32 num_dividers; + const struct ultrarisc_gate_desc *gates; + u32 num_gates; + u32 num_clks; +}; + +int ultrarisc_clk_probe(struct platform_device *pdev, + const struct ultrarisc_clk_soc_data *soc_data); + +#endif /* __ULTRARISC_CLK_ULTRARISC_H */ diff --git a/drivers/clk/visconti/clkc.c b/drivers/clk/visconti/clkc.c index d0b193b5d0b3..4018d1298880 100644 --- a/drivers/clk/visconti/clkc.c +++ b/drivers/clk/visconti/clkc.c @@ -81,9 +81,9 @@ static struct clk_hw *visconti_clk_register_gate(struct device *dev, u8 rs_idx, spinlock_t *lock) { + struct clk_init_data init = {}; struct visconti_clk_gate *gate; struct clk_parent_data *pdata; - struct clk_init_data init; struct clk_hw *hw; int ret; diff --git a/drivers/clk/x86/clk-pmc-atom.c b/drivers/clk/x86/clk-pmc-atom.c index 99291ba65da7..08c83e0abc41 100644 --- a/drivers/clk/x86/clk-pmc-atom.c +++ b/drivers/clk/x86/clk-pmc-atom.c @@ -160,6 +160,9 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id, return ERR_PTR(-ENOMEM); init.name = kasprintf(GFP_KERNEL, "%s_%d", PLT_CLK_NAME_BASE, id); + if (!init.name) + return ERR_PTR(-ENOMEM); + init.ops = &plt_clk_ops; init.flags = 0; init.parent_names = parent_names; diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index 4a0136349f71..edf8c0eaca27 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -35,6 +35,10 @@ #define WZRD_DIVCLK 21 #define WZRD_CLKFBOUT_4 51 #define WZRD_CLKFBOUT_3 48 +#define WZRD_CP 18 +#define WZRD_LOCK 27 +#define WZRD_LOCK_REF_DLY 28 +#define WZRD_RES 30 #define WZRD_DUTY_CYCLE 2 #define WZRD_O_DIV 4 @@ -49,6 +53,10 @@ #define WZRD_P5FEDGE_SHIFT 15 #define WZRD_CLKOUT0_PREDIV2 BIT(11) #define WZRD_EDGE_SHIFT 8 +#define WZRD_CP_MASK GENMASK(3, 0) +#define WZRD_RES_MASK GENMASK(4, 1) +#define WZRD_LOCK_FB_DLY_MASK GENMASK(14, 10) +#define WZRD_LOCK_REF_DLY_LOCK_REF_DLY_MASK GENMASK(14, 10) #define WZRD_CLKFBOUT_MULT_SHIFT 8 #define WZRD_CLKFBOUT_MULT_MASK (0xff << WZRD_CLKFBOUT_MULT_SHIFT) @@ -105,7 +113,6 @@ #define VER_WZRD_VCO_MAX 4320000000ULL #define VER_WZRD_O_MIN 2 #define VER_WZRD_O_MAX 511 -#define WZRD_MIN_ERR 20000 #define WZRD_FRAC_POINTS 1000 /* Get the mask from width */ @@ -406,7 +413,7 @@ static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate, if (o < omin || o > omax) continue; freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o); - diff = freq - rate; + diff = abs(freq - rate); if (diff < best_diff) { best_diff = diff; divider->m = m >> 3; @@ -414,10 +421,13 @@ static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate, divider->d = d; divider->o = o >> 3; divider->o_frac = (o - (divider->o << 3)) * 125; + + if (!diff) + return 0; } } } - return best_diff < WZRD_MIN_ERR ? 0 : -EBUSY; + return best_diff != -1ULL ? 0 : -EBUSY; } static int clk_wzrd_reconfig(struct clk_wzrd_divider *divider, void __iomem *div_addr) @@ -440,6 +450,130 @@ static int clk_wzrd_reconfig(struct clk_wzrd_divider *divider, void __iomem *div WZRD_USEC_POLL, WZRD_TIMEOUT_POLL); } +struct wzrd_pll_filter { + u32 m_min; + u32 m_max; + u32 cp; + u32 res; +}; + +static const struct wzrd_pll_filter wzrd_cp_res_table[] = { + { 4, 4, 5, 15 }, + { 5, 5, 6, 15 }, + { 6, 6, 7, 15 }, + { 7, 7, 13, 15 }, + { 8, 8, 14, 15 }, + { 9, 9, 15, 15 }, + { 10, 10, 14, 7 }, + { 11, 11, 15, 7 }, + { 12, 13, 15, 11 }, + { 14, 14, 15, 13 }, + { 15, 15, 15, 3 }, + { 16, 17, 14, 5 }, + { 18, 19, 15, 5 }, + { 20, 21, 15, 9 }, + { 22, 23, 14, 14 }, + { 24, 26, 15, 14 }, + { 27, 28, 14, 1 }, + { 29, 33, 15, 1 }, + { 34, 37, 14, 6 }, + { 38, 44, 15, 6 }, + { 45, 57, 15, 10 }, + { 58, 63, 13, 12 }, + { 64, 70, 14, 12 }, + { 71, 86, 15, 12 }, + { 87, 94, 14, 2 }, + { 95, 145, 15, 2 }, + { 146, 163, 12, 4 }, + { 164, 181, 13, 4 }, + { 182, 200, 14, 4 }, + { 201, 273, 15, 4 }, + { 274, 300, 13, 8 }, + { 301, 325, 14, 8 }, + { 326, 432, 15, 8 }, +}; + +struct wzrd_lock_timing { + u32 m_min; + u32 m_max; + u32 ref_dly; + u32 fb_dly; + u32 lock_cnt; +}; + +static const struct wzrd_lock_timing wzrd_lock_table[] = { + { 4, 4, 4, 4, 1000 }, + { 5, 5, 6, 6, 1000 }, + { 6, 8, 7, 7, 1000 }, + { 9, 12, 8, 8, 1000 }, + { 13, 13, 10, 10, 1000 }, + { 14, 16, 13, 13, 1000 }, + { 17, 17, 16, 16, 825 }, + { 18, 18, 16, 16, 750 }, + { 19, 20, 16, 16, 700 }, + { 21, 21, 16, 16, 650 }, + { 22, 23, 16, 16, 625 }, + { 24, 24, 16, 16, 575 }, + { 25, 25, 16, 16, 550 }, + { 26, 28, 16, 16, 525 }, + { 29, 30, 16, 16, 475 }, + { 31, 31, 16, 16, 450 }, + { 32, 33, 16, 16, 425 }, + { 34, 36, 16, 16, 400 }, + { 37, 37, 16, 16, 375 }, + { 38, 40, 16, 16, 350 }, + { 41, 43, 16, 16, 325 }, + { 44, 47, 16, 16, 300 }, + { 48, 51, 16, 16, 275 }, + { 52, 205, 16, 16, 250 }, + { 206, 432, 16, 16, 225 }, +}; + +static void clk_wzrd_update_cp_res_lock(struct clk_wzrd_divider *divider, u32 m) +{ + u32 lock_ref_dly = 16, lock_fb_dly = 16, lock_cnt = 250, cp = 15, res = 15; + void __iomem *base = divider->base; + u32 reg; + int i; + + for (i = 0; i < ARRAY_SIZE(wzrd_cp_res_table); i++) { + if (m >= wzrd_cp_res_table[i].m_min && + m <= wzrd_cp_res_table[i].m_max) { + cp = wzrd_cp_res_table[i].cp; + res = wzrd_cp_res_table[i].res; + break; + } + } + + for (i = 0; i < ARRAY_SIZE(wzrd_lock_table); i++) { + if (m >= wzrd_lock_table[i].m_min && + m <= wzrd_lock_table[i].m_max) { + lock_ref_dly = wzrd_lock_table[i].ref_dly; + lock_fb_dly = wzrd_lock_table[i].fb_dly; + lock_cnt = wzrd_lock_table[i].lock_cnt; + break; + } + } + + reg = readl(base + WZRD_CLK_CFG_REG(1, WZRD_CP)); + reg &= ~WZRD_CP_MASK; + reg |= FIELD_PREP(WZRD_CP_MASK, cp); + writel(reg, base + WZRD_CLK_CFG_REG(1, WZRD_CP)); + + reg = readl(base + WZRD_CLK_CFG_REG(1, WZRD_RES)); + reg &= ~WZRD_RES_MASK; + reg |= FIELD_PREP(WZRD_RES_MASK, res); + writel(reg, base + WZRD_CLK_CFG_REG(1, WZRD_RES)); + + reg = lock_cnt | FIELD_PREP(WZRD_LOCK_FB_DLY_MASK, lock_fb_dly); + writel(reg, base + WZRD_CLK_CFG_REG(1, WZRD_LOCK)); + + reg = readl(base + WZRD_CLK_CFG_REG(1, WZRD_LOCK_REF_DLY)); + reg &= ~WZRD_LOCK_REF_DLY_LOCK_REF_DLY_MASK; + reg |= FIELD_PREP(WZRD_LOCK_REF_DLY_LOCK_REF_DLY_MASK, lock_ref_dly); + writel(reg, base + WZRD_CLK_CFG_REG(1, WZRD_LOCK_REF_DLY)); +} + static int clk_wzrd_dynamic_ver_all_nolock(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -471,6 +605,8 @@ static int clk_wzrd_dynamic_ver_all_nolock(struct clk_hw *hw, unsigned long rate writel(regval1, divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKFBOUT_2)); + clk_wzrd_update_cp_res_lock(divider, m); + value2 = divider->d; edged = value2 % WZRD_DUTY_CYCLE; regh = (value2 / WZRD_DUTY_CYCLE); @@ -663,8 +799,8 @@ static int clk_wzrd_determine_rate_all(struct clk_hw *hw, d = divider->d; o = divider->o; - req->rate = div_u64(req->best_parent_rate * (m * 1000 + divider->m_frac), - d * (o * 1000 + divider->o_frac)); + req->rate = mult_frac(req->best_parent_rate, m * 1000 + divider->m_frac, + d * (o * 1000 + divider->o_frac)); return 0; } diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index 6a22cbbc1235..777187744f4e 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -186,7 +186,11 @@ static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0, spin_lock_init(lock); mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0); + if (!mux_name) + goto err_mux_name; div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0); + if (!div_name) + goto err_div_name; clk_register_mux(NULL, mux_name, parents, 4, CLK_SET_RATE_NO_REPARENT, clk_ctrl, 4, 2, 0, lock); @@ -205,6 +209,10 @@ static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0, return; +err_div_name: + kfree(mux_name); +err_mux_name: + kfree(lock); err: clks[clk0] = ERR_PTR(-ENOMEM); if (two_gates) diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c index 44c609378364..fe90b50e1545 100644 --- a/drivers/clk/zynq/pll.c +++ b/drivers/clk/zynq/pll.c @@ -42,11 +42,11 @@ struct zynq_pll { #define PLL_FBDIV_MAX 66 /** - * zynq_pll_round_rate() - Round a clock frequency + * zynq_pll_determine_rate() - Round a clock frequency * @hw: Handle between common and hardware-specific interfaces - * @rate: Desired clock frequency - * @prate: Clock frequency of parent clock - * Return: frequency closest to @rate the hardware can generate. + * @req: Clock rate request, updated with the frequency closest to the + * requested one that the hardware can generate + * Return: 0 always */ static int zynq_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c index b0b6497e7eed..c9a1f20e939b 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c @@ -90,12 +90,6 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) usleep_range(80, 100); } -static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - return 0; -} - static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -170,7 +164,7 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = { .prepare = mtk_hdmi_pll_prepare, .unprepare = mtk_hdmi_pll_unprepare, .set_rate = mtk_hdmi_pll_set_rate, - .determine_rate = mtk_hdmi_pll_determine_rate, + .determine_rate = clk_determine_rate_noop, .recalc_rate = mtk_hdmi_pll_recalc_rate, }; diff --git a/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c b/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c index 3b1d202f89dc..5efd7a38f4da 100644 --- a/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c +++ b/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c @@ -21,12 +21,6 @@ struct airoha_cpu_pmdomain_priv { struct generic_pm_domain pd; }; -static int airoha_cpu_pmdomain_clk_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - return 0; -} - static unsigned long airoha_cpu_pmdomain_clk_get(struct clk_hw *hw, unsigned long parent_rate) { @@ -48,7 +42,7 @@ static int airoha_cpu_pmdomain_clk_is_enabled(struct clk_hw *hw) static const struct clk_ops airoha_cpu_pmdomain_clk_ops = { .recalc_rate = airoha_cpu_pmdomain_clk_get, .is_enabled = airoha_cpu_pmdomain_clk_is_enabled, - .determine_rate = airoha_cpu_pmdomain_clk_determine_rate, + .determine_rate = clk_determine_rate_noop, }; static int airoha_cpu_pmdomain_set_performance_state(struct generic_pm_domain *domain, diff --git a/drivers/pmdomain/mediatek/mtk-mfg-pmdomain.c b/drivers/pmdomain/mediatek/mtk-mfg-pmdomain.c index 9a8a38d98cce..1417ffc22b3e 100644 --- a/drivers/pmdomain/mediatek/mtk-mfg-pmdomain.c +++ b/drivers/pmdomain/mediatek/mtk-mfg-pmdomain.c @@ -310,25 +310,6 @@ static unsigned long mtk_mfg_recalc_rate_gpu(struct clk_hw *hw, return readl(mfg->shared_mem + GF_REG_FREQ_OUT_GPU) * HZ_PER_KHZ; } -static int mtk_mfg_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - /* - * The determine_rate callback needs to be implemented to avoid returning - * the current clock frequency, rather than something even remotely - * close to the frequency that was asked for. - * - * Instead of writing considerable amounts of possibly slow code just to - * somehow figure out which of the three PLLs to round for, or even to - * do a search through one of two OPP tables in order to find the closest - * OPP of a frequency, just return the rate as-is. This avoids devfreq - * "rounding" a request for the lowest frequency to the possibly very - * high current frequency, breaking the powersave governor in the process. - */ - - return 0; -} - static unsigned long mtk_mfg_recalc_rate_stack(struct clk_hw *hw, unsigned long parent_rate) { @@ -339,12 +320,12 @@ static unsigned long mtk_mfg_recalc_rate_stack(struct clk_hw *hw, static const struct clk_ops mtk_mfg_clk_gpu_ops = { .recalc_rate = mtk_mfg_recalc_rate_gpu, - .determine_rate = mtk_mfg_determine_rate, + .determine_rate = clk_determine_rate_noop, }; static const struct clk_ops mtk_mfg_clk_stack_ops = { .recalc_rate = mtk_mfg_recalc_rate_stack, - .determine_rate = mtk_mfg_determine_rate, + .determine_rate = clk_determine_rate_noop, }; static const struct clk_init_data mtk_mfg_clk_gpu_init = { diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index d009eb0849a3..3168ab1eea88 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -83,6 +83,17 @@ config RESET_EIC7700 The driver supports eic7700 series chips and provides functionality for asserting and deasserting resets on the chip. +config RESET_EIC7700_HSP + tristate "EIC7700 HSP Reset controller" + depends on ARCH_ESWIN || COMPILE_TEST + select AUXILIARY_BUS + help + This enables the HSP reset controller driver for ESWIN SoCs. This + driver is specific to ESWIN SoCs and should only be enabled if using + such hardware. + The driver supports EIC7700 series chips and provides functionality + for asserting and deasserting resets on the chip. + config RESET_EYEQ bool "Mobileye EyeQ reset controller" depends on EYEQ || COMPILE_TEST @@ -300,6 +311,19 @@ config RESET_SKY1 help This enables the reset controller for Cix Sky1. +config RESET_SKY1_AUDSS + tristate "Cix Sky1 Audio Subsystem reset controller" + depends on ARCH_CIX || COMPILE_TEST + select AUXILIARY_BUS + default CLK_SKY1_AUDSS + help + Support for block-level software reset lines in the Cix Sky1 + Audio Subsystem (AUDSS) Clock and Reset Unit. Sixteen reset + outputs for audio peripherals are controlled through the CRU + register map. The driver binds as an auxiliary device from + the AUDSS clock driver. Say M or Y here if you want to build + this driver. + config RESET_SOCFPGA bool "SoCFPGA Reset Driver" if COMPILE_TEST && (!ARM || !ARCH_INTEL_SOCFPGA) default ARM && ARCH_INTEL_SOCFPGA diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 3e52569bd276..45ad17062462 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o obj-$(CONFIG_RESET_EIC7700) += reset-eic7700.o +obj-$(CONFIG_RESET_EIC7700_HSP) += reset-eic7700-hsp.o obj-$(CONFIG_RESET_EYEQ) += reset-eyeq.o obj-$(CONFIG_RESET_GPIO) += reset-gpio.o obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o @@ -39,6 +40,7 @@ obj-$(CONFIG_RESET_RZV2H_USB2PHY) += reset-rzv2h-usb2phy.o obj-$(CONFIG_RESET_SCMI) += reset-scmi.o obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o obj-$(CONFIG_RESET_SKY1) += reset-sky1.o +obj-$(CONFIG_RESET_SKY1_AUDSS) += reset-sky1-audss.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o diff --git a/drivers/reset/reset-eic7700-hsp.c b/drivers/reset/reset-eic7700-hsp.c new file mode 100644 index 000000000000..1575ee4a20d6 --- /dev/null +++ b/drivers/reset/reset-eic7700-hsp.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd.. + * All rights reserved. + * + * ESWIN EIC7700 HSP Reset Driver + * + * Authors: Xuyang Dong + */ + +#include +#include +#include +#include +#include + +#include + +/** + * struct eic7700_hsp_reset_data - reset controller information structure + * @rcdev: reset controller entity + * @regmap: regmap handle containing the memory-mapped reset registers + */ +struct eic7700_hsp_reset_data { + struct reset_controller_dev rcdev; + struct regmap *regmap; +}; + +struct eic7700_hsp_reg { + u32 reg; + u32 bit; + bool active_low; +}; + +static inline struct eic7700_hsp_reset_data * +to_eic7700_hsp_reset(struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct eic7700_hsp_reset_data, rcdev); +} + +static const struct eic7700_hsp_reg eic7700_hsp_reset[] = { + [EIC7700_HSP_RST_SATA_P0] = {0x340, BIT(0), false}, + [EIC7700_HSP_RST_SATA_PHY] = {0x340, BIT(1), false}, + [EIC7700_HSP_RST_USB0] = {0x800, BIT(24), true}, + [EIC7700_HSP_RST_USB1] = {0x900, BIT(24), true}, + [EIC7700_HSP_RST_USB0_PHY] = {0x800, BIT(25), false}, + [EIC7700_HSP_RST_USB1_PHY] = {0x900, BIT(25), false}, +}; + +static int eic7700_hsp_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct eic7700_hsp_reset_data *data = to_eic7700_hsp_reset(rcdev); + + return regmap_assign_bits(data->regmap, eic7700_hsp_reset[id].reg, + eic7700_hsp_reset[id].bit, + !eic7700_hsp_reset[id].active_low); +} + +static int eic7700_hsp_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct eic7700_hsp_reset_data *data = to_eic7700_hsp_reset(rcdev); + + return regmap_assign_bits(data->regmap, eic7700_hsp_reset[id].reg, + eic7700_hsp_reset[id].bit, + eic7700_hsp_reset[id].active_low); +} + +static const struct reset_control_ops eic7700_hsp_reset_ops = { + .assert = eic7700_hsp_reset_assert, + .deassert = eic7700_hsp_reset_deassert, +}; + +static int eic7700_hsp_reset_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct eic7700_hsp_reset_data *data; + struct device *dev = &adev->dev; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->regmap = dev_get_regmap(dev->parent, NULL); + if (!data->regmap) + return dev_err_probe(dev, -ENODEV, "failed to get regmap!\n"); + + data->rcdev.owner = THIS_MODULE; + data->rcdev.ops = &eic7700_hsp_reset_ops; + data->rcdev.of_node = dev->parent->of_node; + data->rcdev.dev = dev; + data->rcdev.nr_resets = ARRAY_SIZE(eic7700_hsp_reset); + + return devm_reset_controller_register(dev, &data->rcdev); +} + +static const struct auxiliary_device_id eic7700_hsp_reset_ids[] = { + { .name = "clk_eic7700_hsp.hsp-reset", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(auxiliary, eic7700_hsp_reset_ids); + +static struct auxiliary_driver eic7700_hsp_reset_driver = { + .probe = eic7700_hsp_reset_probe, + .id_table = eic7700_hsp_reset_ids, +}; + +module_auxiliary_driver(eic7700_hsp_reset_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Xuyang Dong "); +MODULE_DESCRIPTION("ESWIN EIC7700 HSP Reset Controller Driver"); diff --git a/drivers/reset/reset-eyeq.c b/drivers/reset/reset-eyeq.c index 7b9ab574bd65..f2533086bb76 100644 --- a/drivers/reset/reset-eyeq.c +++ b/drivers/reset/reset-eyeq.c @@ -1,10 +1,11 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Reset driver for the Mobileye EyeQ5, EyeQ6L and EyeQ6H platforms. + * Reset driver for the Mobileye EyeQ5, EyeQ6L, EyeQ6H and EyeQ7H platforms. * * Controllers live in a shared register region called OLB. EyeQ5 and EyeQ6L * have a single OLB instance for a single reset controller. EyeQ6H has seven - * OLB instances; three host reset controllers. + * OLB instances; three host reset controllers. EyeQ7H has fourteen OLB instances; + * eleven host reset controllers. * * Each reset controller has one or more domain. Domains are of a given type * (see enum eqr_domain_type), with a valid offset mask (up to 32 resets per @@ -73,6 +74,43 @@ * 9. PMA0 10. PMA1 11. MPC0 12. MPC1 * 13. MPC2 14. MPC3 15. PERIPH * + * Known resets in EyeQ7H acc domain 0 (type EQR_EYEQ7H_ACRP) + * 0. VMP0 1. XVMP1 2. VMP2 3. VMP3 + * 4. MPC0 5. MPC1 6. PMA0 7. PMA1 + * + * Known resets in EyeQ7H acc domain 1 (type EQR_EYEQ7H_ACC) + * 0. NCORE0 1. NCORE1 2. NCORE0_M 3. NCORE1_M + * 4. NCORE_NOC 5. VMP_NOC 6. MPC_NOC 7. PMA_NOC + * + * Known resets in EyeQ7H ddr (type EQR_EYEQ7H_CFG) + * 0. APB 1. DMI 2. DFI 3. PHY_SMS + * 4. CTL_SMS + * + * Known resets in EyeQ7H east (type EQR_EYEQ7H_CFG) + * 0. ISP 1. VEU 2. LBIST + * + * Known resets in EyeQ7H periph (type EQR_EYEQ6H_SARCR) + * 0. gpio 1.EXT TIMER 2.UART 3. SPI + * 4. I2C0 5. I2C1 6.I2C2 7. I2S + * + * Known resets in EyeQ7H south domain 0 (type EQR_EYEQ7H_CFG) + * 0. PCI_PHY 1. PCI_CTL 2. S_NOC 3. GBE_PHY + * 4. GBE_CTL + * + * Known resets in EyeQ7H south domain 1 (type EQR_EYEQ7H_CFG) + * 0. XSPI 1. UFS 2. VDIO + * + * Known resets in EyeQ7H west (type EQR_EYEQ7H_CFG) + * 0. GPU 1. CAU 2. LBIST 3. GPU_LBIST + * + * Known resets in EyeQ7H xnn domain 0 (type EQR_EYEQ7H_ACRP) + * 0. XNN0 1. XNN1 2.XNN2 + * + * Known resets in EyeQ7H xnn domain 1 (type EQR_EYEQ7H_ACC) + * 0. XNN0 1. XNN1 2. XNN2 3. XNN3 + * 4. NCORE 5. L2_0 6. L2_1 7. SMS_0 + * 8. SMS_1 + * * Abbreviations: * - PMA: Programmable Macro Array * - MPC: Multi-threaded Processing Clusters @@ -113,6 +151,11 @@ enum eqr_domain_type { EQR_EYEQ5_ACRP, EQR_EYEQ5_PCIE, EQR_EYEQ6H_SARCR, + EQR_EYEQ7H_ACC, + EQR_EYEQ7H_ACRP, + EQR_EYEQ7H_CFG, + + EQR_NB_DOM_TYPES /* number of domain types, keep at the end */ }; /* @@ -137,16 +180,34 @@ enum eqr_domain_type { #define EQR_EYEQ6H_SARCR_RST_STATUS (0x008) #define EQR_EYEQ6H_SARCR_CLK_REQUEST (0x00C) +/* + * Domain type EQR_EYEQ7H_ACC register offsets. + */ +#define EQR_EYEQ7H_ACC_CLK_EN (0x000) +#define EQR_EYEQ7H_ACC_RST_EN (0x004) + +/* + * Domain type EQR_EYEQ7H_ACRP register masks. + * Registers are: base + 4 * offset. + */ +#define EQR_EYEQ7H_ACRP_PD_REQ BIT(0) +#define EQR_EYEQ7H_ACRP_MBIST_CFG GENMASK(3, 1) +#define EQR_EYEQ7H_ACRP_ST_POWER_DOWN BIT(13) +#define EQR_EYEQ7H_ACRP_ST_ACTIVE BIT(14) + struct eqr_busy_wait_timings { unsigned long sleep_us; unsigned long timeout_us; }; -static const struct eqr_busy_wait_timings eqr_timings[] = { +static const struct eqr_busy_wait_timings eqr_timings[EQR_NB_DOM_TYPES] = { [EQR_EYEQ5_SARCR] = {1, 10}, [EQR_EYEQ5_ACRP] = {1, 40 * USEC_PER_MSEC}, /* LBIST implies long timeout. */ /* EQR_EYEQ5_PCIE does no busy waiting. */ [EQR_EYEQ6H_SARCR] = {1, 400}, + /* EQR_EYEQ7H_ACC does no busy waiting. */ + [EQR_EYEQ7H_ACRP] = {1, 40 * USEC_PER_MSEC}, + /* EQR_EYEQ7H_CFG does no busy waiting. */ }; #define EQR_MAX_DOMAIN_COUNT 3 @@ -220,10 +281,6 @@ static int eqr_busy_wait_locked(struct eqr_private *priv, struct device *dev, sleep_us, timeout_us); break; - case EQR_EYEQ5_PCIE: - ret = 0; /* No busy waiting. */ - break; - case EQR_EYEQ6H_SARCR: /* * Wait until both bits change: @@ -240,6 +297,23 @@ static int eqr_busy_wait_locked(struct eqr_private *priv, struct device *dev, &rst_status, &clk_status); break; + case EQR_EYEQ7H_ACRP: + reg = base + 4 * offset; + if (assert) + mask = EQR_EYEQ7H_ACRP_ST_POWER_DOWN; + else + mask = EQR_EYEQ7H_ACRP_ST_ACTIVE; + + ret = readl_poll_timeout(reg, val, !!(val & mask), + sleep_us, timeout_us); + break; + + case EQR_EYEQ5_PCIE: + case EQR_EYEQ7H_ACC: + case EQR_EYEQ7H_CFG: + ret = 0; /* No busy waiting. */ + break; + default: WARN_ON(1); ret = -EINVAL; @@ -284,6 +358,28 @@ static void eqr_assert_locked(struct eqr_private *priv, u32 domain, u32 offset) writel(val, base + EQR_EYEQ6H_SARCR_CLK_REQUEST); break; + case EQR_EYEQ7H_ACC: + /* RST_REQUEST and CLK_REQUEST must be kept in sync. */ + val = readl(base + EQR_EYEQ7H_ACC_RST_EN); + val &= ~BIT(offset); + writel(val, base + EQR_EYEQ7H_ACC_RST_EN); + writel(val, base + EQR_EYEQ7H_ACC_CLK_EN); + break; + + case EQR_EYEQ7H_ACRP: + /* set powerdown and leave MBIST bits at zero */ + reg = base + 4 * offset; + val = readl(reg) & ~EQR_EYEQ7H_ACRP_MBIST_CFG; + writel(val | EQR_EYEQ7H_ACRP_PD_REQ, reg); + break; + + case EQR_EYEQ7H_CFG: + /* clear clock enable and NRESET bits */ + val = readl(base); + val &= ~GENMASK(2 * offset + 1, 2 * offset); + writel(val, base); + break; + default: WARN_ON(1); break; @@ -338,6 +434,28 @@ static void eqr_deassert_locked(struct eqr_private *priv, u32 domain, writel(val, base + EQR_EYEQ6H_SARCR_CLK_REQUEST); break; + case EQR_EYEQ7H_ACC: + /* RST_REQUEST and CLK_REQUEST must be kept in sync. */ + val = readl(base + EQR_EYEQ7H_ACC_RST_EN); + val |= BIT(offset); + writel(val, base + EQR_EYEQ7H_ACC_RST_EN); + writel(val, base + EQR_EYEQ7H_ACC_CLK_EN); + break; + + case EQR_EYEQ7H_ACRP: + /* clear powerdown and leave MBIST bits at zero */ + reg = base + 4 * offset; + val = readl(reg) & ~EQR_EYEQ7H_ACRP_MBIST_CFG; + writel(val & ~EQR_EYEQ7H_ACRP_PD_REQ, reg); + break; + + case EQR_EYEQ7H_CFG: + /* set clock enable and NRESET bits */ + val = readl(base); + val |= GENMASK(2 * offset + 1, 2 * offset); + writel(val, base); + break; + default: WARN_ON(1); break; @@ -384,6 +502,14 @@ static int eqr_status(struct reset_controller_dev *rcdev, unsigned long id) case EQR_EYEQ6H_SARCR: reg = base + EQR_EYEQ6H_SARCR_RST_STATUS; return !(readl(reg) & BIT(offset)); + case EQR_EYEQ7H_ACC: + reg = base + EQR_EYEQ7H_ACC_RST_EN; + return !(readl(reg) & BIT(offset)); + case EQR_EYEQ7H_ACRP: + reg = base + 4 * offset; + return !(readl(reg) & EQR_EYEQ7H_ACRP_ST_ACTIVE); + case EQR_EYEQ7H_CFG: + return !(readl(base) & BIT(2 * offset)); default: return -EINVAL; } @@ -557,6 +683,113 @@ static const struct eqr_match_data eqr_eyeq6h_acc_data = { .domains = eqr_eyeq6h_acc_domains, }; +static const struct eqr_domain_descriptor eqr_eyeq7h_acc_domains[] = { + { + .type = EQR_EYEQ7H_ACRP, + .valid_mask = 0xFF, + .offset = 0x000, + }, + { + .type = EQR_EYEQ7H_ACC, + .valid_mask = 0xFF, + .offset = 0x060, + }, +}; + +static const struct eqr_match_data eqr_eyeq7h_acc_data = { + .domain_count = ARRAY_SIZE(eqr_eyeq7h_acc_domains), + .domains = eqr_eyeq7h_acc_domains, +}; + +static const struct eqr_domain_descriptor eqr_eyeq7h_ddr_domains[] = { + { + .type = EQR_EYEQ7H_CFG, + .valid_mask = 0x1F, + .offset = 0x008, + }, +}; + +static const struct eqr_match_data eqr_eyeq7h_ddr_data = { + .domain_count = ARRAY_SIZE(eqr_eyeq7h_ddr_domains), + .domains = eqr_eyeq7h_ddr_domains, +}; + +static const struct eqr_domain_descriptor eqr_eyeq7h_east_domains[] = { + { + .type = EQR_EYEQ7H_CFG, + .valid_mask = 0x7, + .offset = 0x060, + }, +}; + +static const struct eqr_match_data eqr_eyeq7h_east_data = { + .domain_count = ARRAY_SIZE(eqr_eyeq7h_east_domains), + .domains = eqr_eyeq7h_east_domains, +}; + +/* Periph OLBs each have an instance. */ +static const struct eqr_domain_descriptor eqr_eyeq7h_per_domains[] = { + { + .type = EQR_EYEQ6H_SARCR, + .valid_mask = 0xFF, + .offset = 0x030, + }, +}; + +static const struct eqr_match_data eqr_eyeq7h_per_data = { + .domain_count = ARRAY_SIZE(eqr_eyeq7h_per_domains), + .domains = eqr_eyeq7h_per_domains, +}; + +static const struct eqr_domain_descriptor eqr_eyeq7h_south_domains[] = { + { + .type = EQR_EYEQ7H_CFG, + .valid_mask = 0x1F, + .offset = 0x070, + }, + { + .type = EQR_EYEQ7H_CFG, + .valid_mask = 0x7, + .offset = 0x074, + }, +}; + +static const struct eqr_match_data eqr_eyeq7h_south_data = { + .domain_count = ARRAY_SIZE(eqr_eyeq7h_south_domains), + .domains = eqr_eyeq7h_south_domains, +}; + +static const struct eqr_domain_descriptor eqr_eyeq7h_west_domains[] = { + { + .type = EQR_EYEQ7H_CFG, + .valid_mask = 0xf, + .offset = 0x068, + }, +}; + +static const struct eqr_match_data eqr_eyeq7h_west_data = { + .domain_count = ARRAY_SIZE(eqr_eyeq7h_west_domains), + .domains = eqr_eyeq7h_west_domains, +}; + +static const struct eqr_domain_descriptor eqr_eyeq7h_xnn_domains[] = { + { + .type = EQR_EYEQ7H_ACRP, + .valid_mask = 0x7, + .offset = 0x000, + }, + { + .type = EQR_EYEQ7H_ACC, + .valid_mask = 0x1FF, + .offset = 0x060, + }, +}; + +static const struct eqr_match_data eqr_eyeq7h_xnn_data = { + .domain_count = ARRAY_SIZE(eqr_eyeq7h_xnn_domains), + .domains = eqr_eyeq7h_xnn_domains, +}; + /* * Table describes OLB system-controller compatibles. * It does not get used to match against devicetree node. @@ -568,15 +801,35 @@ static const struct of_device_id eqr_match_table[] = { { .compatible = "mobileye,eyeq6h-west-olb", .data = &eqr_eyeq6h_we_data }, { .compatible = "mobileye,eyeq6h-east-olb", .data = &eqr_eyeq6h_we_data }, { .compatible = "mobileye,eyeq6h-acc-olb", .data = &eqr_eyeq6h_acc_data }, + { .compatible = "mobileye,eyeq7h-acc0-olb", .data = &eqr_eyeq7h_acc_data }, + { .compatible = "mobileye,eyeq7h-acc1-olb", .data = &eqr_eyeq7h_acc_data }, + { .compatible = "mobileye,eyeq7h-ddr0-olb", .data = &eqr_eyeq7h_ddr_data }, + { .compatible = "mobileye,eyeq7h-ddr1-olb", .data = &eqr_eyeq7h_ddr_data }, + { .compatible = "mobileye,eyeq7h-east-olb", .data = &eqr_eyeq7h_east_data }, + { .compatible = "mobileye,eyeq7h-periph-east-olb", .data = &eqr_eyeq7h_per_data }, + { .compatible = "mobileye,eyeq7h-periph-west-olb", .data = &eqr_eyeq7h_per_data }, + { .compatible = "mobileye,eyeq7h-south-olb", .data = &eqr_eyeq7h_south_data }, + { .compatible = "mobileye,eyeq7h-west-olb", .data = &eqr_eyeq7h_west_data }, + { .compatible = "mobileye,eyeq7h-xnn0-olb", .data = &eqr_eyeq7h_xnn_data }, + { .compatible = "mobileye,eyeq7h-xnn1-olb", .data = &eqr_eyeq7h_xnn_data }, {} }; MODULE_DEVICE_TABLE(of, eqr_match_table); static const struct auxiliary_device_id eqr_id_table[] = { { .name = "clk_eyeq.reset" }, - { .name = "clk_eyeq.reset_west" }, - { .name = "clk_eyeq.reset_east" }, { .name = "clk_eyeq.reset_acc" }, + { .name = "clk_eyeq.reset_acc0" }, + { .name = "clk_eyeq.reset_acc1" }, + { .name = "clk_eyeq.reset_ddr0" }, + { .name = "clk_eyeq.reset_ddr1" }, + { .name = "clk_eyeq.reset_east" }, + { .name = "clk_eyeq.reset_periph_east" }, + { .name = "clk_eyeq.reset_periph_west" }, + { .name = "clk_eyeq.reset_south" }, + { .name = "clk_eyeq.reset_west" }, + { .name = "clk_eyeq.reset_xnn0" }, + { .name = "clk_eyeq.reset_xnn1" }, {} }; MODULE_DEVICE_TABLE(auxiliary, eqr_id_table); diff --git a/drivers/reset/reset-sky1-audss.c b/drivers/reset/reset-sky1-audss.c new file mode 100644 index 000000000000..d9735db681c7 --- /dev/null +++ b/drivers/reset/reset-sky1-audss.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Cix Sky1 Audio Subsystem reset controller driver + * + * Copyright 2026 Cix Technology Group Co., Ltd. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#define SKY1_RESET_SLEEP_US 50 + +#define AUDSS_SW_RST 0x78 + +struct sky1_audss_reset_map { + unsigned int offset; + unsigned int mask; +}; + +struct sky1_audss_reset { + struct reset_controller_dev rcdev; + struct regmap *regmap; + const struct sky1_audss_reset_map *map; +}; + +static const struct sky1_audss_reset_map sky1_audss_reset_map[] = { + [AUDSS_I2S0_SW_RST] = { AUDSS_SW_RST, BIT(0) }, + [AUDSS_I2S1_SW_RST] = { AUDSS_SW_RST, BIT(1) }, + [AUDSS_I2S2_SW_RST] = { AUDSS_SW_RST, BIT(2) }, + [AUDSS_I2S3_SW_RST] = { AUDSS_SW_RST, BIT(3) }, + [AUDSS_I2S4_SW_RST] = { AUDSS_SW_RST, BIT(4) }, + [AUDSS_I2S5_SW_RST] = { AUDSS_SW_RST, BIT(5) }, + [AUDSS_I2S6_SW_RST] = { AUDSS_SW_RST, BIT(6) }, + [AUDSS_I2S7_SW_RST] = { AUDSS_SW_RST, BIT(7) }, + [AUDSS_I2S8_SW_RST] = { AUDSS_SW_RST, BIT(8) }, + [AUDSS_I2S9_SW_RST] = { AUDSS_SW_RST, BIT(9) }, + [AUDSS_WDT_SW_RST] = { AUDSS_SW_RST, BIT(10) }, + [AUDSS_TIMER_SW_RST] = { AUDSS_SW_RST, BIT(11) }, + [AUDSS_MB0_SW_RST] = { AUDSS_SW_RST, BIT(12) }, + [AUDSS_MB1_SW_RST] = { AUDSS_SW_RST, BIT(13) }, + [AUDSS_HDA_SW_RST] = { AUDSS_SW_RST, BIT(14) }, + [AUDSS_DMAC_SW_RST] = { AUDSS_SW_RST, BIT(15) }, +}; + +static struct sky1_audss_reset *to_sky1_audss_reset(struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct sky1_audss_reset, rcdev); +} + +static int sky1_audss_reset_set(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) +{ + struct sky1_audss_reset *priv = to_sky1_audss_reset(rcdev); + const struct sky1_audss_reset_map *signal = &priv->map[id]; + int ret; + + ret = regmap_assign_bits(priv->regmap, signal->offset, + signal->mask, !assert); + if (ret) + return ret; + + fsleep(SKY1_RESET_SLEEP_US); + return 0; +} + +static int sky1_audss_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return sky1_audss_reset_set(rcdev, id, true); +} + +static int sky1_audss_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return sky1_audss_reset_set(rcdev, id, false); +} + +static const struct reset_control_ops sky1_audss_reset_ops = { + .assert = sky1_audss_reset_assert, + .deassert = sky1_audss_reset_deassert, +}; + +static int sky1_audss_reset_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct sky1_audss_reset *priv; + struct device *dev = &adev->dev; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->regmap = dev_get_regmap(dev->parent, NULL); + if (!priv->regmap) + return dev_err_probe(dev, -ENODEV, "failed to get parent regmap\n"); + + priv->map = sky1_audss_reset_map; + priv->rcdev.owner = THIS_MODULE; + priv->rcdev.nr_resets = ARRAY_SIZE(sky1_audss_reset_map); + priv->rcdev.ops = &sky1_audss_reset_ops; + priv->rcdev.of_node = dev->of_node; + priv->rcdev.dev = dev; + + return devm_reset_controller_register(dev, &priv->rcdev); +} + +static const struct auxiliary_device_id sky1_audss_reset_ids[] = { + { .name = "clk_sky1_audss.reset" }, + { } +}; +MODULE_DEVICE_TABLE(auxiliary, sky1_audss_reset_ids); + +static struct auxiliary_driver sky1_audss_reset_driver = { + .probe = sky1_audss_reset_probe, + .id_table = sky1_audss_reset_ids, +}; +module_auxiliary_driver(sky1_audss_reset_driver); + +MODULE_AUTHOR("Joakim Zhang "); +MODULE_DESCRIPTION("Cix Sky1 Audio Subsystem reset driver"); +MODULE_LICENSE("GPL"); diff --git a/include/dt-bindings/clock/amlogic,a9-aoclkc.h b/include/dt-bindings/clock/amlogic,a9-aoclkc.h new file mode 100644 index 000000000000..a7d704d4b58e --- /dev/null +++ b/include/dt-bindings/clock/amlogic,a9-aoclkc.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2026 Amlogic, Inc. All rights reserved. + */ + +#ifndef __AMLOGIC_A9_AO_CLKC_H +#define __AMLOGIC_A9_AO_CLKC_H + +#define CLKID_AO_XTAL_IN 0 +#define CLKID_AO_XTAL 1 +#define CLKID_AO_SYS 2 +#define CLKID_AO_SYS_I3C 3 +#define CLKID_AO_SYS_RTC_REG 4 +#define CLKID_AO_SYS_CLKTREE 5 +#define CLKID_AO_SYS_RST_CTRL 6 +#define CLKID_AO_SYS_PAD 7 +#define CLKID_AO_SYS_RTC_DIG 8 +#define CLKID_AO_SYS_IRQ 9 +#define CLKID_AO_SYS_PWRCTRL 10 +#define CLKID_AO_SYS_PWM_A 11 +#define CLKID_AO_SYS_PWM_B 12 +#define CLKID_AO_SYS_PWM_C 13 +#define CLKID_AO_SYS_PWM_D 14 +#define CLKID_AO_SYS_PWM_E 15 +#define CLKID_AO_SYS_PWM_F 16 +#define CLKID_AO_SYS_PWM_G 17 +#define CLKID_AO_SYS_I2C_A 18 +#define CLKID_AO_SYS_I2C_B 19 +#define CLKID_AO_SYS_I2C_C 20 +#define CLKID_AO_SYS_I2C_D 21 +#define CLKID_AO_SYS_SED 22 +#define CLKID_AO_SYS_IR_CTRL 23 +#define CLKID_AO_SYS_UART_B 24 +#define CLKID_AO_SYS_UART_C 25 +#define CLKID_AO_SYS_UART_D 26 +#define CLKID_AO_SYS_UART_E 27 +#define CLKID_AO_SYS_SPISG_0 28 +#define CLKID_AO_SYS_RTC_SECURE 29 +#define CLKID_AO_SYS_CEC 30 +#define CLKID_AO_SYS_AOCPU 31 +#define CLKID_AO_SYS_SRAM 32 +#define CLKID_AO_SYS_SPISG_1 33 +#define CLKID_AO_SYS_SPISG_2 34 +#define CLKID_AO_PWM_A_SEL 35 +#define CLKID_AO_PWM_A_DIV 36 +#define CLKID_AO_PWM_A 37 +#define CLKID_AO_PWM_B_SEL 38 +#define CLKID_AO_PWM_B_DIV 39 +#define CLKID_AO_PWM_B 40 +#define CLKID_AO_PWM_C_SEL 41 +#define CLKID_AO_PWM_C_DIV 42 +#define CLKID_AO_PWM_C 43 +#define CLKID_AO_PWM_D_SEL 44 +#define CLKID_AO_PWM_D_DIV 45 +#define CLKID_AO_PWM_D 46 +#define CLKID_AO_PWM_E_SEL 47 +#define CLKID_AO_PWM_E_DIV 48 +#define CLKID_AO_PWM_E 49 +#define CLKID_AO_PWM_F_SEL 50 +#define CLKID_AO_PWM_F_DIV 51 +#define CLKID_AO_PWM_F 52 +#define CLKID_AO_PWM_G_SEL 53 +#define CLKID_AO_PWM_G_DIV 54 +#define CLKID_AO_PWM_G 55 +#define CLKID_AO_RTC_DUALDIV_IN 56 +#define CLKID_AO_RTC_DUALDIV_DIV 57 +#define CLKID_AO_RTC_DUALDIV_SEL 58 +#define CLKID_AO_RTC_DUALDIV 59 +#define CLKID_AO_RTC 60 +#define CLKID_AO_CEC_DUALDIV_IN 61 +#define CLKID_AO_CEC_DUALDIV_DIV 62 +#define CLKID_AO_CEC_DUALDIV_SEL 63 +#define CLKID_AO_CEC_DUALDIV 64 +#define CLKID_AO_CEC 65 + +#endif /* __AMLOGIC_A9_AO_CLKC_H */ diff --git a/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h new file mode 100644 index 000000000000..09487a414197 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h @@ -0,0 +1,351 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2026 Amlogic, Inc. All rights reserved. + */ + +#ifndef __AMLOGIC_A9_PERIPHERALS_CLKC_H +#define __AMLOGIC_A9_PERIPHERALS_CLKC_H + +#define CLKID_SYS_AM_AXI 0 +#define CLKID_SYS_DOS 1 +#define CLKID_SYS_MIPI_DSI0 2 +#define CLKID_SYS_ETH_PHY 3 +#define CLKID_SYS_AMFC 4 +#define CLKID_SYS_MALI 5 +#define CLKID_SYS_NNA 6 +#define CLKID_SYS_ETH_AXI 7 +#define CLKID_SYS_DP_APB 8 +#define CLKID_SYS_EDPTX_APB 9 +#define CLKID_SYS_U3HSG 10 +#define CLKID_SYS_AUCPU 11 +#define CLKID_SYS_GLB 12 +#define CLKID_SYS_COMBO_DPHY_APB 13 +#define CLKID_SYS_HDMIRX_APB 14 +#define CLKID_SYS_HDMIRX_PCLK 15 +#define CLKID_SYS_MIPI_DSI0_PHY 16 +#define CLKID_SYS_CAN0 17 +#define CLKID_SYS_CAN1 18 +#define CLKID_SYS_SD_EMMC_A 19 +#define CLKID_SYS_SD_EMMC_B 20 +#define CLKID_SYS_SD_EMMC_C 21 +#define CLKID_SYS_SC 22 +#define CLKID_SYS_ACODEC 23 +#define CLKID_SYS_MIPI_ISP 24 +#define CLKID_SYS_MSR 25 +#define CLKID_SYS_AUDIO 26 +#define CLKID_SYS_MIPI_DSI1 27 +#define CLKID_SYS_MIPI_DSI1_PHY 28 +#define CLKID_SYS_ETH 29 +#define CLKID_SYS_ETH_1G_MAC 30 +#define CLKID_SYS_UART_A 31 +#define CLKID_SYS_UART_F 32 +#define CLKID_SYS_TS_A55 33 +#define CLKID_SYS_ETH_1G_AXI 34 +#define CLKID_SYS_TS_DOS 35 +#define CLKID_SYS_U3DRD_B 36 +#define CLKID_SYS_TS_CORE 37 +#define CLKID_SYS_TS_PLL 38 +#define CLKID_SYS_CSI_DIG_CLKIN 39 +#define CLKID_SYS_CVE 40 +#define CLKID_SYS_GE2D 41 +#define CLKID_SYS_SPISG 42 +#define CLKID_SYS_U2H 43 +#define CLKID_SYS_PCIE_MAC_A 44 +#define CLKID_SYS_U3DRD_A 45 +#define CLKID_SYS_U2DRD 46 +#define CLKID_SYS_PCIE_PHY 47 +#define CLKID_SYS_PCIE_MAC_B 48 +#define CLKID_SYS_PERIPH 49 +#define CLKID_SYS_PIO 50 +#define CLKID_SYS_I3C 51 +#define CLKID_SYS_I2C_M_E 52 +#define CLKID_SYS_I2C_M_F 53 +#define CLKID_SYS_HDMITX_APB 54 +#define CLKID_SYS_I2C_M_I 55 +#define CLKID_SYS_I2C_M_G 56 +#define CLKID_SYS_I2C_M_H 57 +#define CLKID_SYS_HDMI20_AES 58 +#define CLKID_SYS_CSI2_HOST 59 +#define CLKID_SYS_CSI2_ADAPT 60 +#define CLKID_SYS_DSPA 61 +#define CLKID_SYS_PP_DMA 62 +#define CLKID_SYS_PP_WRAPPER 63 +#define CLKID_SYS_VPU_INTR 64 +#define CLKID_SYS_CSI2_PHY 65 +#define CLKID_SYS_SARADC 66 +#define CLKID_SYS_PWM_J 67 +#define CLKID_SYS_PWM_I 68 +#define CLKID_SYS_PWM_H 69 +#define CLKID_SYS_PWM_N 70 +#define CLKID_SYS_PWM_M 71 +#define CLKID_SYS_PWM_L 72 +#define CLKID_SYS_PWM_K 73 +#define CLKID_SD_EMMC_A_SEL 74 +#define CLKID_SD_EMMC_A_DIV 75 +#define CLKID_SD_EMMC_A 76 +#define CLKID_SD_EMMC_B_SEL 77 +#define CLKID_SD_EMMC_B_DIV 78 +#define CLKID_SD_EMMC_B 79 +#define CLKID_SD_EMMC_C_SEL 80 +#define CLKID_SD_EMMC_C_DIV 81 +#define CLKID_SD_EMMC_C 82 +#define CLKID_PWM_H_SEL 83 +#define CLKID_PWM_H_DIV 84 +#define CLKID_PWM_H 85 +#define CLKID_PWM_I_SEL 86 +#define CLKID_PWM_I_DIV 87 +#define CLKID_PWM_I 88 +#define CLKID_PWM_J_SEL 89 +#define CLKID_PWM_J_DIV 90 +#define CLKID_PWM_J 91 +#define CLKID_PWM_K_SEL 92 +#define CLKID_PWM_K_DIV 93 +#define CLKID_PWM_K 94 +#define CLKID_PWM_L_SEL 95 +#define CLKID_PWM_L_DIV 96 +#define CLKID_PWM_L 97 +#define CLKID_PWM_M_SEL 98 +#define CLKID_PWM_M_DIV 99 +#define CLKID_PWM_M 100 +#define CLKID_PWM_N_SEL 101 +#define CLKID_PWM_N_DIV 102 +#define CLKID_PWM_N 103 +#define CLKID_SPISG0_SEL 104 +#define CLKID_SPISG0_DIV 105 +#define CLKID_SPISG0 106 +#define CLKID_SPISG1_SEL 107 +#define CLKID_SPISG1_DIV 108 +#define CLKID_SPISG1 109 +#define CLKID_SPISG2_SEL 110 +#define CLKID_SPISG2_DIV 111 +#define CLKID_SPISG2 112 +#define CLKID_SARADC_SEL 113 +#define CLKID_SARADC_DIV 114 +#define CLKID_SARADC 115 +#define CLKID_AMFC_SEL 116 +#define CLKID_AMFC_DIV 117 +#define CLKID_AMFC 118 +#define CLKID_NNA_SEL 119 +#define CLKID_NNA_DIV 120 +#define CLKID_NNA 121 +#define CLKID_USB_250M_SEL 122 +#define CLKID_USB_250M_DIV 123 +#define CLKID_USB_250M 124 +#define CLKID_USB_48M_PRE_SEL 125 +#define CLKID_USB_48M_PRE_DIV 126 +#define CLKID_USB_48M_PRE 127 +#define CLKID_PCIE0_TL_SEL 128 +#define CLKID_PCIE0_TL_DIV 129 +#define CLKID_PCIE0_TL 130 +#define CLKID_PCIE1_TL_SEL 131 +#define CLKID_PCIE1_TL_DIV 132 +#define CLKID_PCIE1_TL 133 +#define CLKID_CMPR_SEL 134 +#define CLKID_CMPR_DIV 135 +#define CLKID_CMPR 136 +#define CLKID_DEWARPA_SEL 137 +#define CLKID_DEWARPA_DIV 138 +#define CLKID_DEWARPA 139 +#define CLKID_SC_PRE_SEL 140 +#define CLKID_SC_PRE_DIV 141 +#define CLKID_SC_PRE 142 +#define CLKID_SC 143 +#define CLKID_DPTX_APB2_SEL 144 +#define CLKID_DPTX_APB2_DIV 145 +#define CLKID_DPTX_APB2 146 +#define CLKID_DPTX_AUD_SEL 147 +#define CLKID_DPTX_AUD_DIV 148 +#define CLKID_DPTX_AUD 149 +#define CLKID_ISP_SEL 150 +#define CLKID_ISP_DIV 151 +#define CLKID_ISP 152 +#define CLKID_CVE_SEL 153 +#define CLKID_CVE_DIV 154 +#define CLKID_CVE 155 +#define CLKID_VGE_SEL 156 +#define CLKID_VGE_DIV 157 +#define CLKID_VGE 158 +#define CLKID_PP_SEL 159 +#define CLKID_PP_DIV 160 +#define CLKID_PP 161 +#define CLKID_GLB_SEL 162 +#define CLKID_GLB_DIV 163 +#define CLKID_GLB 164 +#define CLKID_USB_48M_DUALDIV_IN 165 +#define CLKID_USB_48M_DUALDIV_DIV 166 +#define CLKID_USB_48M_DUALDIV_SEL 167 +#define CLKID_USB_48M_DUALDIV 168 +#define CLKID_USB_48M 169 +#define CLKID_CAN0_PE_SEL 170 +#define CLKID_CAN0_PE_DIV 171 +#define CLKID_CAN0_PE 172 +#define CLKID_CAN1_PE_SEL 173 +#define CLKID_CAN1_PE_DIV 174 +#define CLKID_CAN1_PE 175 +#define CLKID_CAN0_FILTER_SEL 176 +#define CLKID_CAN0_FILTER_DIV 177 +#define CLKID_CAN0_FILTER 178 +#define CLKID_CAN1_FILTER_SEL 179 +#define CLKID_CAN1_FILTER_DIV 180 +#define CLKID_CAN1_FILTER 181 +#define CLKID_I3C_SEL 182 +#define CLKID_I3C_DIV 183 +#define CLKID_I3C 184 +#define CLKID_TS_DIV 185 +#define CLKID_TS 186 +#define CLKID_ETH_125M_DIV 187 +#define CLKID_ETH_125M 188 +#define CLKID_ETH_RMII_SEL 189 +#define CLKID_ETH_RMII_DIV 190 +#define CLKID_ETH_RMII 191 +#define CLKID_GEN_SEL 192 +#define CLKID_GEN_DIV 193 +#define CLKID_GEN 194 +#define CLKID_CLK24M_IN 195 +#define CLKID_CLK12_24M 196 +#define CLKID_MALI_0_SEL 197 +#define CLKID_MALI_0_DIV 198 +#define CLKID_MALI_0 199 +#define CLKID_MALI_1_SEL 200 +#define CLKID_MALI_1_DIV 201 +#define CLKID_MALI_1 202 +#define CLKID_MALI 203 +#define CLKID_MALI_STACK_0_SEL 204 +#define CLKID_MALI_STACK_0_DIV 205 +#define CLKID_MALI_STACK_0 206 +#define CLKID_MALI_STACK_1_SEL 207 +#define CLKID_MALI_STACK_1_DIV 208 +#define CLKID_MALI_STACK_1 209 +#define CLKID_MALI_STACK 210 +#define CLKID_DSPA_0_SEL 211 +#define CLKID_DSPA_0_DIV 212 +#define CLKID_DSPA_0 213 +#define CLKID_DSPA_1_SEL 214 +#define CLKID_DSPA_1_DIV 215 +#define CLKID_DSPA_1 216 +#define CLKID_DSPA 217 +#define CLKID_HEVCF_0_SEL 218 +#define CLKID_HEVCF_0_DIV 219 +#define CLKID_HEVCF_0 220 +#define CLKID_HEVCF_1_SEL 221 +#define CLKID_HEVCF_1_DIV 222 +#define CLKID_HEVCF_1 223 +#define CLKID_HEVCF 224 +#define CLKID_HCODEC_0_SEL 225 +#define CLKID_HCODEC_0_DIV 226 +#define CLKID_HCODEC_0 227 +#define CLKID_HCODEC_1_SEL 228 +#define CLKID_HCODEC_1_DIV 229 +#define CLKID_HCODEC_1 230 +#define CLKID_HCODEC 231 +#define CLKID_VPU_0_SEL 232 +#define CLKID_VPU_0_DIV 233 +#define CLKID_VPU_0 234 +#define CLKID_VPU_1_SEL 235 +#define CLKID_VPU_1_DIV 236 +#define CLKID_VPU_1 237 +#define CLKID_VPU 238 +#define CLKID_VAPB_0_SEL 239 +#define CLKID_VAPB_0_DIV 240 +#define CLKID_VAPB_0 241 +#define CLKID_VAPB_1_SEL 242 +#define CLKID_VAPB_1_DIV 243 +#define CLKID_VAPB_1 244 +#define CLKID_VAPB 245 +#define CLKID_GE2D 246 +#define CLKID_VPU_CLKB_TMP_SEL 247 +#define CLKID_VPU_CLKB_TMP_DIV 248 +#define CLKID_VPU_CLKB_TMP 249 +#define CLKID_VPU_CLKB_DIV 250 +#define CLKID_VPU_CLKB 251 +#define CLKID_HDMITX_SYS_SEL 252 +#define CLKID_HDMITX_SYS_DIV 253 +#define CLKID_HDMITX_SYS 254 +#define CLKID_HDMITX_PRIF_SEL 255 +#define CLKID_HDMITX_PRIF_DIV 256 +#define CLKID_HDMITX_PRIF 257 +#define CLKID_HDMITX_200M_SEL 258 +#define CLKID_HDMITX_200M_DIV 259 +#define CLKID_HDMITX_200M 260 +#define CLKID_HDMITX_AUD_SEL 261 +#define CLKID_HDMITX_AUD_DIV 262 +#define CLKID_HDMITX_AUD 263 +#define CLKID_HDMIRX_5M_SEL 264 +#define CLKID_HDMIRX_5M_DIV 265 +#define CLKID_HDMIRX_5M 266 +#define CLKID_HDMIRX_2M_SEL 267 +#define CLKID_HDMIRX_2M_DIV 268 +#define CLKID_HDMIRX_2M 269 +#define CLKID_HDMIRX_CFG_SEL 270 +#define CLKID_HDMIRX_CFG_DIV 271 +#define CLKID_HDMIRX_CFG 272 +#define CLKID_HDMIRX_HDCP2X_SEL 273 +#define CLKID_HDMIRX_HDCP2X_DIV 274 +#define CLKID_HDMIRX_HDCP2X 275 +#define CLKID_HDMIRX_ACR_REF_SEL 276 +#define CLKID_HDMIRX_ACR_REF_DIV 277 +#define CLKID_HDMIRX_ACR_REF 278 +#define CLKID_HDMIRX_METER_SEL 279 +#define CLKID_HDMIRX_METER_DIV 280 +#define CLKID_HDMIRX_METER 281 +#define CLKID_VID_LOCK_SEL 282 +#define CLKID_VID_LOCK_DIV 283 +#define CLKID_VID_LOCK 284 +#define CLKID_VDIN_MEAS_SEL 285 +#define CLKID_VDIN_MEAS_DIV 286 +#define CLKID_VDIN_MEAS 287 +#define CLKID_VID_PLL_DIV 288 +#define CLKID_VID_PLL_SEL 289 +#define CLKID_VID_PLL 290 +#define CLKID_VID_PLL_VCLK 291 +#define CLKID_VCLK0_SEL 292 +#define CLKID_VCLK0_IN 293 +#define CLKID_VCLK0_DIV 294 +#define CLKID_VCLK0 295 +#define CLKID_VCLK0_DIV1_EN 296 +#define CLKID_VCLK0_DIV2_EN 297 +#define CLKID_VCLK0_DIV2 298 +#define CLKID_VCLK0_DIV4_EN 299 +#define CLKID_VCLK0_DIV4 300 +#define CLKID_VCLK0_DIV6_EN 301 +#define CLKID_VCLK0_DIV6 302 +#define CLKID_VCLK0_DIV12_EN 303 +#define CLKID_VCLK0_DIV12 304 +#define CLKID_VCLK1_SEL 305 +#define CLKID_VCLK1_IN 306 +#define CLKID_VCLK1_DIV 307 +#define CLKID_VCLK1 308 +#define CLKID_VCLK1_DIV1_EN 309 +#define CLKID_VCLK1_DIV2_EN 310 +#define CLKID_VCLK1_DIV2 311 +#define CLKID_VCLK1_DIV4_EN 312 +#define CLKID_VCLK1_DIV4 313 +#define CLKID_VCLK1_DIV6_EN 314 +#define CLKID_VCLK1_DIV6 315 +#define CLKID_VCLK1_DIV12_EN 316 +#define CLKID_VCLK1_DIV12 317 +#define CLKID_VDAC_SEL 318 +#define CLKID_VDAC 319 +#define CLKID_ENCODER0_SEL 320 +#define CLKID_ENCODER0 321 +#define CLKID_ENCODER1_SEL 322 +#define CLKID_ENCODER1 323 +#define CLKID_HDMITX0_PIXEL_SEL 324 +#define CLKID_HDMITX0_PIXEL 325 +#define CLKID_HDMITX0_FE_SEL 326 +#define CLKID_HDMITX0_FE 327 +#define CLKID_HDMITX1_PIXEL_SEL 328 +#define CLKID_HDMITX1_PIXEL 329 +#define CLKID_HDMITX1_FE_SEL 330 +#define CLKID_HDMITX1_FE 331 +#define CLKID_CSI_PHY_SEL 332 +#define CLKID_CSI_PHY_DIV 333 +#define CLKID_CSI_PHY 334 +#define CLKID_DSI0_MEAS_SEL 335 +#define CLKID_DSI0_MEAS_DIV 336 +#define CLKID_DSI0_MEAS 337 +#define CLKID_DSI1_MEAS_SEL 338 +#define CLKID_DSI1_MEAS_DIV 339 +#define CLKID_DSI1_MEAS 340 + +#endif /* __AMLOGIC_A9_PERIPHERALS_CLKC_H */ diff --git a/include/dt-bindings/clock/aspeed,ast2700-scu.h b/include/dt-bindings/clock/aspeed,ast2700-scu.h index bacf712e8e04..138f78ce5f07 100644 --- a/include/dt-bindings/clock/aspeed,ast2700-scu.h +++ b/include/dt-bindings/clock/aspeed,ast2700-scu.h @@ -163,5 +163,7 @@ #define SCU1_CLK_GATE_PORTDUSB2CLK 85 #define SCU1_CLK_GATE_LTPI1TXCLK 86 #define SCU1_CLK_I3C 87 +#define SCU1_CLK_HPLL_DIV4 88 +#define SCU1_CLK_PECI 89 #endif diff --git a/include/dt-bindings/clock/cix,sky1-audss-cru.h b/include/dt-bindings/clock/cix,sky1-audss-cru.h new file mode 100644 index 000000000000..8c58ef8bf682 --- /dev/null +++ b/include/dt-bindings/clock/cix,sky1-audss-cru.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright 2026 Cix Technology Group Co., Ltd. + */ + +#ifndef _DT_BINDINGS_CLOCK_CIX_SKY1_AUDSS_CRU_H +#define _DT_BINDINGS_CLOCK_CIX_SKY1_AUDSS_CRU_H + +#define CLK_AUD_CLK4_DIV2 0 +#define CLK_AUD_CLK4_DIV4 1 +#define CLK_AUD_CLK5_DIV2 2 + +#define CLK_DSP_CLK 3 +#define CLK_DSP_BCLK 4 +#define CLK_DSP_PBCLK 5 + +#define CLK_SRAM_AXI 6 + +#define CLK_HDA_SYS 7 +#define CLK_HDA_HDA 8 + +#define CLK_DMAC_AXI 9 + +#define CLK_WDG_APB 10 +#define CLK_WDG_WDG 11 + +#define CLK_TIMER_APB 12 +#define CLK_TIMER_TIMER 13 + +#define CLK_MB_0_APB 14 /* MB0: ap->dsp */ +#define CLK_MB_1_APB 15 /* MB1: dsp->ap */ + +#define CLK_I2S0_APB 16 +#define CLK_I2S1_APB 17 +#define CLK_I2S2_APB 18 +#define CLK_I2S3_APB 19 +#define CLK_I2S4_APB 20 +#define CLK_I2S5_APB 21 +#define CLK_I2S6_APB 22 +#define CLK_I2S7_APB 23 +#define CLK_I2S8_APB 24 +#define CLK_I2S9_APB 25 +#define CLK_I2S0 26 +#define CLK_I2S1 27 +#define CLK_I2S2 28 +#define CLK_I2S3 29 +#define CLK_I2S4 30 +#define CLK_I2S5 31 +#define CLK_I2S6 32 +#define CLK_I2S7 33 +#define CLK_I2S8 34 +#define CLK_I2S9 35 + +#define CLK_MCLK0 36 +#define CLK_MCLK1 37 +#define CLK_MCLK2 38 +#define CLK_MCLK3 39 +#define CLK_MCLK4 40 + +#endif diff --git a/include/dt-bindings/clock/clock.h b/include/dt-bindings/clock/clock.h new file mode 100644 index 000000000000..155e2653a120 --- /dev/null +++ b/include/dt-bindings/clock/clock.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +/* + * Copyright 2025 NXP + */ + +#ifndef __DT_BINDINGS_CLOCK_H +#define __DT_BINDINGS_CLOCK_H + +#define CLK_SSC_NO_SPREAD 0 +#define CLK_SSC_CENTER_SPREAD 1 +#define CLK_SSC_UP_SPREAD 2 +#define CLK_SSC_DOWN_SPREAD 3 + +#endif /* __DT_BINDINGS_CLOCK_H */ diff --git a/include/dt-bindings/clock/eswin,eic7700-hspcrg.h b/include/dt-bindings/clock/eswin,eic7700-hspcrg.h new file mode 100644 index 000000000000..1d1ff15c1154 --- /dev/null +++ b/include/dt-bindings/clock/eswin,eic7700-hspcrg.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd.. + * All rights reserved. + * + * Device Tree binding constants for EIC7700 HSP clock controller. + * + * Authors: Xuyang Dong + */ + +#ifndef _DT_BINDINGS_ESWIN_EIC7700_HSPCRG_CLOCK_H_ +#define _DT_BINDINGS_ESWIN_EIC7700_HSPCRG_CLOCK_H_ + +#define EIC7700_HSP_CLK_FAC_CFG_DIV2 0 +#define EIC7700_HSP_CLK_FAC_CFG_DIV4 1 +#define EIC7700_HSP_CLK_FAC_MMC_DIV10 2 +#define EIC7700_HSP_CLK_MUX_EMMC_3MUX1 3 +#define EIC7700_HSP_CLK_MUX_SD0_3MUX1 4 +#define EIC7700_HSP_CLK_MUX_SD1_3MUX1 5 +#define EIC7700_HSP_CLK_MUX_EMMC_CQE_2MUX1 6 +#define EIC7700_HSP_CLK_MUX_SD0_CQE_2MUX1 7 +#define EIC7700_HSP_CLK_MUX_SD1_CQE_2MUX1 8 +#define EIC7700_HSP_CLK_GATE_MSHC0_TMR 9 +#define EIC7700_HSP_CLK_GATE_EMMC 10 +#define EIC7700_HSP_CLK_GATE_MSHC1_TMR 11 +#define EIC7700_HSP_CLK_GATE_SD0 12 +#define EIC7700_HSP_CLK_GATE_MSHC2_TMR 13 +#define EIC7700_HSP_CLK_GATE_SD1 14 +#define EIC7700_HSP_CLK_GATE_USB0 15 +#define EIC7700_HSP_CLK_GATE_USB1 16 +#define EIC7700_HSP_CLK_GATE_SATA 17 + +#endif /* _DT_BINDINGS_ESWIN_EIC7700_HSPCRG_CLOCK_H_ */ diff --git a/include/dt-bindings/clock/mobileye,eyeq7h-clk.h b/include/dt-bindings/clock/mobileye,eyeq7h-clk.h new file mode 100644 index 000000000000..76e06a0abd02 --- /dev/null +++ b/include/dt-bindings/clock/mobileye,eyeq7h-clk.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2025 Mobileye Vision Technologies Ltd. + */ + +#ifndef _DT_BINDINGS_CLOCK_MOBILEYE_EYEQ7H_CLK_H +#define _DT_BINDINGS_CLOCK_MOBILEYE_EYEQ7H_CLK_H + +/* ACC0 and ACC1 OLBs PLL and dividers */ +#define EQ7HC_ACC_PLL_VMP 0 +#define EQ7HC_ACC_PLL_MPC 1 +#define EQ7HC_ACC_PLL_PMA 2 +#define EQ7HC_ACC_PLL_NOC 3 +#define EQ7HC_ACC_DIV_PMA 4 +#define EQ7HC_ACC_DIV_NCORE 5 +#define EQ7HC_ACC_DIV_CFG 6 + +/* DDR0 and DDR1 OLBs PLL and dividers */ +#define EQ7HC_DDR_PLL 0 +#define EQ7HC_DDR_DIV_APB 1 +#define EQ7HC_DDR_DIV_PLLREF 2 +#define EQ7HC_DDR_DIV_DFI 3 + +/* east OLB PLL and dividers */ +#define EQ7HC_EAST_PLL_106P6 0 +#define EQ7HC_EAST_DIV_REF_106P6 1 +#define EQ7HC_EAST_PLL_NOC 2 +#define EQ7HC_EAST_PLL_ISP 3 +#define EQ7HC_EAST_PLL_VEU 4 +#define EQ7HC_EAST_DIV_REF_DDR_PHY 5 +#define EQ7HC_EAST_DIV_CORE 6 +#define EQ7HC_EAST_DIV_CORE_MBIST 7 +#define EQ7HC_EAST_DIV_ISRAM_MBIST 8 +#define EQ7HC_EAST_DIV_CFG 9 +#define EQ7HC_EAST_DIV_VEU_CORE 10 +#define EQ7HC_EAST_DIV_VEU_MBIST 11 +#define EQ7HC_EAST_DIV_VEU_OCP 12 +#define EQ7HC_EAST_DIV_LBITS 13 +#define EQ7HC_EAST_DIV_ISP0_CORE 14 + +/* MIPS0, MIPS1 and MIPS2 OLBs PLL and dividers */ +#define EQ7HC_MIPS_PLL_CPU 0 +#define EQ7HC_MIPS_DIV_CM 1 + +/* periph east OLB PLL and dividers */ +#define EQ7HC_PERIPH_EAST_PLL_PER 0 +#define EQ7HC_PERIPH_EAST_DIV_PER 1 + +/* periph west OLB PLL and dividers */ +#define EQ7HC_PERIPH_WEST_PLL_PER 0 +#define EQ7HC_PERIPH_WEST_PLL_I2S 1 +#define EQ7HC_PERIPH_WEST_DIV_PER 2 +#define EQ7HC_PERIPH_WEST_DIV_I2S 3 + +/* south OLB PLL and dividers */ +#define EQ7HC_SOUTH_PLL_100P0 0 +#define EQ7HC_SOUTH_DIV_REF_100P0 1 +#define EQ7HC_SOUTH_PLL_XSPI 2 +#define EQ7HC_SOUTH_PLL_VDIO 3 +#define EQ7HC_SOUTH_PLL_PER 4 +#define EQ7HC_SOUTH_DIV_VDO_DSI_SYS 5 +#define EQ7HC_SOUTH_DIV_PMA_CMN_REF 6 +#define EQ7HC_SOUTH_DIV_REF_UFS 7 +#define EQ7HC_SOUTH_DIV_XSPI_SYS 8 +#define EQ7HC_SOUTH_DIV_XSPI_MBIST 9 +#define EQ7HC_SOUTH_DIV_NOC_S 10 +#define EQ7HC_SOUTH_DIV_PCIE_SYS 11 +#define EQ7HC_SOUTH_DIV_PCIE_SYS_MBIST 12 +#define EQ7HC_SOUTH_DIV_PCIE_GBE_PHY 13 +#define EQ7HC_SOUTH_DIV_UFS_CORE 14 +#define EQ7HC_SOUTH_DIV_UFS_SMS 15 +#define EQ7HC_SOUTH_DIV_UFS_ROM_SMS 16 +#define EQ7HC_SOUTH_DIV_ETH_SYS 17 +#define EQ7HC_SOUTH_DIV_ETH_MBIST 18 +#define EQ7HC_SOUTH_DIV_CFG_S 19 +#define EQ7HC_SOUTH_DIV_TSU 20 +#define EQ7HC_SOUTH_DIV_VDIO 21 +#define EQ7HC_SOUTH_DIV_VDIO_CORE 22 +#define EQ7HC_SOUTH_DIV_VDIO_CORE_MBIST 23 +#define EQ7HC_SOUTH_DIV_VDO_CORE_MBIST 24 +#define EQ7HC_SOUTH_DIV_VDO_P 25 +#define EQ7HC_SOUTH_DIV_VDIO_CFG 26 +#define EQ7HC_SOUTH_DIV_VDIO_TXCLKESC 27 + +/* west OLB PLL and dividers */ +#define EQ7HC_WEST_PLL_106P6 0 +#define EQ7HC_WEST_DIV_REF_106P6 1 +#define EQ7HC_WEST_PLL_NOC 2 +#define EQ7HC_WEST_PLL_GPU 3 +#define EQ7HC_WEST_PLL_SSI 4 +#define EQ7HC_WEST_DIV_GPU 5 +#define EQ7HC_WEST_DIV_GPU_MBIST 6 +#define EQ7HC_WEST_DIV_LBITS 7 +#define EQ7HC_WEST_DIV_MIPS_TIMER 8 +#define EQ7HC_WEST_DIV_SSI_CORE 9 +#define EQ7HC_WEST_DIV_SSI_CORE_MBIST 10 +#define EQ7HC_WEST_DIV_SSI_ROM 11 +#define EQ7HC_WEST_DIV_SSI_ROM_MBIST 12 +#define EQ7HC_WEST_DIV_REF_DDR_PHY 13 +#define EQ7HC_WEST_DIV_CORE 14 +#define EQ7HC_WEST_DIV_CORE_MBIST 15 +#define EQ7HC_WEST_DIV_CFG 16 +#define EQ7HC_WEST_DIV_CAU 17 +#define EQ7HC_WEST_DIV_CAU_MBIST 18 + +/* XNN0 and XNN1 OLBs PLL and dividers */ +#define EQ7HC_XNN_PLL_XNN0 0 +#define EQ7HC_XNN_PLL_XNN1 1 +#define EQ7HC_XNN_PLL_XNN2 2 +#define EQ7HC_XNN_PLL_CLSTR 3 +#define EQ7HC_XNN_DIV_XNN0 4 +#define EQ7HC_XNN_DIV_XNN1 5 +#define EQ7HC_XNN_DIV_XNN2 6 +#define EQ7HC_XNN_DIV_CLSTR 7 +#define EQ7HC_XNN_DIV_I2 8 +#define EQ7HC_XNN_DIV_I2_SMS 9 +#define EQ7HC_XNN_DIV_CFG 10 + +#endif diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h index 3d00c98b9654..89e982f771db 100644 --- a/include/dt-bindings/clock/mt8173-clk.h +++ b/include/dt-bindings/clock/mt8173-clk.h @@ -243,6 +243,13 @@ #define CLK_IMG_FD 7 #define CLK_IMG_NR_CLK 8 +/* MFG_SYS */ + +#define CLK_MFG_AXI 0 +#define CLK_MFG_MEM 1 +#define CLK_MFG_G3D 2 +#define CLK_MFG_26M 3 + /* MM_SYS */ #define CLK_MM_SMI_COMMON 1 diff --git a/include/dt-bindings/clock/qcom,gcc-mdm9607.h b/include/dt-bindings/clock/qcom,gcc-mdm9607.h index 357a680a40da..246bce28137e 100644 --- a/include/dt-bindings/clock/qcom,gcc-mdm9607.h +++ b/include/dt-bindings/clock/qcom,gcc-mdm9607.h @@ -13,7 +13,6 @@ #define GPLL2 4 #define GPLL2_EARLY 5 #define PCNOC_BFDCD_CLK_SRC 6 -#define SYSTEM_NOC_BFDCD_CLK_SRC 7 #define GCC_SMMU_CFG_CLK 8 #define APSS_AHB_CLK_SRC 9 #define GCC_QDSS_DAP_CLK 10 diff --git a/include/dt-bindings/clock/qcom,hawi-videocc.h b/include/dt-bindings/clock/qcom,hawi-videocc.h new file mode 100644 index 000000000000..8c97079ff1a7 --- /dev/null +++ b/include/dt-bindings/clock/qcom,hawi-videocc.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_HAWI_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_HAWI_H + +/* VIDEO_CC clocks */ +#define VIDEO_CC_AHB_CLK 0 +#define VIDEO_CC_AHB_CLK_SRC 1 +#define VIDEO_CC_CX_AXI0_CLK 2 +#define VIDEO_CC_CX_DBGCH_XO_CLK 3 +#define VIDEO_CC_CX_XO_CLK 4 +#define VIDEO_CC_DBGCH_XO_CLK 5 +#define VIDEO_CC_MVS0_CLK 6 +#define VIDEO_CC_MVS0_CLK_SRC 7 +#define VIDEO_CC_MVS0_SHIFT_CLK 8 +#define VIDEO_CC_MVS0_VPP0_CLK 9 +#define VIDEO_CC_MVS0_VPP0_VPP1_GATING_CLK 10 +#define VIDEO_CC_MVS0_VPP1_CLK 11 +#define VIDEO_CC_MVS0A_CLK 12 +#define VIDEO_CC_MVS0A_CLK_SRC 13 +#define VIDEO_CC_MVS0B_CLK 14 +#define VIDEO_CC_MVS0B_CLK_SRC 15 +#define VIDEO_CC_MVS0C_CLK 16 +#define VIDEO_CC_MVS0C_CLK_SRC 17 +#define VIDEO_CC_MVS0C_CTL_FREERUN_CLK 18 +#define VIDEO_CC_MVS0C_DEBUG_CLK 19 +#define VIDEO_CC_MVS0C_FREERUN_CLK 20 +#define VIDEO_CC_MVS0C_SHIFT_CLK 21 +#define VIDEO_CC_PLL0 22 +#define VIDEO_CC_PLL0_OUT_EVEN 23 +#define VIDEO_CC_PLL1 24 +#define VIDEO_CC_PLL2 25 +#define VIDEO_CC_PLL3 26 +#define VIDEO_CC_SLEEP_CLK 27 +#define VIDEO_CC_XO_CLK 28 +#define VIDEO_CC_XO_CLK_SRC 29 + +/* VIDEO_CC power domains */ +#define VIDEO_CC_AXI0_CX_INT_GDSC 0 +#define VIDEO_CC_MM_INT_GDSC 1 +#define VIDEO_CC_MVS0_GDSC 2 +#define VIDEO_CC_MVS0_VPP0_GDSC 3 +#define VIDEO_CC_MVS0_VPP1_GDSC 4 +#define VIDEO_CC_MVS0A_GDSC 5 +#define VIDEO_CC_MVS0C_GDSC 6 + +/* VIDEO_CC resets */ +#define VIDEO_CC_AXI0_CX_INT_BCR 0 +#define VIDEO_CC_INTERFACE_BCR 1 +#define VIDEO_CC_MM_INT_BCR 2 +#define VIDEO_CC_MVS0_BCR 3 +#define VIDEO_CC_MVS0_VPP0_BCR 4 +#define VIDEO_CC_MVS0_VPP1_BCR 5 +#define VIDEO_CC_MVS0A_BCR 6 +#define VIDEO_CC_MVS0C_CLK_ARES 7 +#define VIDEO_CC_MVS0C_BCR 8 +#define VIDEO_CC_MVS0C_CTL_FREERUN_CLK_ARES 9 +#define VIDEO_CC_MVS0C_FREERUN_CLK_ARES 10 +#define VIDEO_CC_XO_CLK_ARES 11 + +#endif diff --git a/include/dt-bindings/clock/qcom,ipq9650-gcc.h b/include/dt-bindings/clock/qcom,ipq9650-gcc.h index afd17c00d96e..2d43ca36c09c 100644 --- a/include/dt-bindings/clock/qcom,ipq9650-gcc.h +++ b/include/dt-bindings/clock/qcom,ipq9650-gcc.h @@ -169,4 +169,9 @@ #define GPLL2 160 #define GPLL2_OUT_MAIN 161 #define GPLL4 162 +#define GCC_REFGEN_CORE_CLK_SRC 163 +#define GCC_REFGEN_PCIE_CORE_CLK 164 +#define GCC_REFGEN_PCIE_HCLK 165 +#define GCC_REFGEN_CMN_UPHY_HCLK 166 +#define GCC_REFGEN_CMN_UPHY_CORE_CLK 167 #endif diff --git a/include/dt-bindings/clock/qcom,maili-gcc.h b/include/dt-bindings/clock/qcom,maili-gcc.h new file mode 100644 index 000000000000..9bea90adb988 --- /dev/null +++ b/include/dt-bindings/clock/qcom,maili-gcc.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_MAILI_H +#define _DT_BINDINGS_CLK_QCOM_GCC_MAILI_H + +#include "qcom,hawi-gcc.h" + +/* Maili has below additional clocks on top of Hawi */ +#define GCC_QUPV3_WRAP5_CORE_2X_CLK 188 +#define GCC_QUPV3_WRAP5_CORE_CLK 189 +#define GCC_QUPV3_WRAP5_QSPI_REF_CLK 190 +#define GCC_QUPV3_WRAP5_QSPI_REF_CLK_SRC 191 +#define GCC_QUPV3_WRAP5_S0_CLK 192 +#define GCC_QUPV3_WRAP5_S0_CLK_SRC 193 +#define GCC_QUPV3_WRAP_5_M_AHB_CLK 194 +#define GCC_QUPV3_WRAP_5_S_AHB_CLK 195 + +#endif diff --git a/include/dt-bindings/clock/qcom,maili-videocc.h b/include/dt-bindings/clock/qcom,maili-videocc.h new file mode 100644 index 000000000000..f8461048b04d --- /dev/null +++ b/include/dt-bindings/clock/qcom,maili-videocc.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_MAILI_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_MAILI_H + +/* VIDEO_CC clocks */ +#define VIDEO_CC_AHB_CLK 0 +#define VIDEO_CC_AHB_CLK_SRC 1 +#define VIDEO_CC_MVS0_CLK 2 +#define VIDEO_CC_MVS0_CLK_SRC 3 +#define VIDEO_CC_MVS0_FREERUN_CLK 4 +#define VIDEO_CC_MVS0_SHIFT_CLK 5 +#define VIDEO_CC_MVS0_VPP0_CLK 6 +#define VIDEO_CC_MVS0_VPP0_FREERUN_CLK 7 +#define VIDEO_CC_MVS0B_CLK 8 +#define VIDEO_CC_MVS0B_CLK_SRC 9 +#define VIDEO_CC_MVS0B_FREERUN_CLK 10 +#define VIDEO_CC_MVS0C_CLK 11 +#define VIDEO_CC_MVS0C_CLK_SRC 12 +#define VIDEO_CC_MVS0C_DEBUG_CLK 13 +#define VIDEO_CC_MVS0C_FREERUN_CLK 14 +#define VIDEO_CC_MVS0C_SHIFT_CLK 15 +#define VIDEO_CC_PLL0 16 +#define VIDEO_CC_PLL1 17 +#define VIDEO_CC_PLL2 18 +#define VIDEO_CC_SLEEP_CLK 19 +#define VIDEO_CC_TS_XO_CLK 20 +#define VIDEO_CC_XO_CLK 21 +#define VIDEO_CC_XO_CLK_SRC 22 + +/* VIDEO_CC power domains */ +#define VIDEO_CC_MVS0_GDSC 0 +#define VIDEO_CC_MVS0_VPP0_GDSC 1 +#define VIDEO_CC_MVS0C_GDSC 2 + +/* VIDEO_CC resets */ +#define VIDEO_CC_INTERFACE_BCR 0 +#define VIDEO_CC_MVS0_BCR 1 +#define VIDEO_CC_MVS0_CLK_ARES 2 +#define VIDEO_CC_MVS0_FREERUN_CLK_ARES 3 +#define VIDEO_CC_MVS0_VPP0_BCR 4 +#define VIDEO_CC_MVS0C_BCR 5 +#define VIDEO_CC_MVS0C_CLK_ARES 6 +#define VIDEO_CC_MVS0C_FREERUN_CLK_ARES 7 +#define VIDEO_CC_XO_CLK_ARES 8 + +#endif diff --git a/include/dt-bindings/clock/qcom,nord-dispcc.h b/include/dt-bindings/clock/qcom,nord-dispcc.h new file mode 100644 index 000000000000..219facbbda10 --- /dev/null +++ b/include/dt-bindings/clock/qcom,nord-dispcc.h @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_DISP_CC_NORD_H +#define _DT_BINDINGS_CLK_QCOM_DISP_CC_NORD_H + +/* DISP_CC_0 and DISP_CC_1 clocks */ +#define MDSS_DISP_CC_ACMU_CLK 0 +#define MDSS_DISP_CC_MDSS_ACCU_SHIFT_CLK 1 +#define MDSS_DISP_CC_MDSS_AHB1_CLK 2 +#define MDSS_DISP_CC_MDSS_AHB_CLK 3 +#define MDSS_DISP_CC_MDSS_AHB_CLK_SRC 4 +#define MDSS_DISP_CC_MDSS_BYTE0_CLK 5 +#define MDSS_DISP_CC_MDSS_BYTE0_CLK_SRC 6 +#define MDSS_DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 7 +#define MDSS_DISP_CC_MDSS_BYTE0_INTF_CLK 8 +#define MDSS_DISP_CC_MDSS_BYTE1_CLK 9 +#define MDSS_DISP_CC_MDSS_BYTE1_CLK_SRC 10 +#define MDSS_DISP_CC_MDSS_BYTE1_DIV_CLK_SRC 11 +#define MDSS_DISP_CC_MDSS_BYTE1_INTF_CLK 12 +#define MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK 13 +#define MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK_SRC 14 +#define MDSS_DISP_CC_MDSS_DPTX0_CRYPTO_CLK 15 +#define MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK 16 +#define MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK_SRC 17 +#define MDSS_DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC 18 +#define MDSS_DISP_CC_MDSS_DPTX0_LINK_INTF_CLK 19 +#define MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK 20 +#define MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC 21 +#define MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK 22 +#define MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC 23 +#define MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK 24 +#define MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK_SRC 25 +#define MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK 26 +#define MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK_SRC 27 +#define MDSS_DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK 28 +#define MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK 29 +#define MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK_SRC 30 +#define MDSS_DISP_CC_MDSS_DPTX1_CRYPTO_CLK 31 +#define MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK 32 +#define MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK_SRC 33 +#define MDSS_DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC 34 +#define MDSS_DISP_CC_MDSS_DPTX1_LINK_INTF_CLK 35 +#define MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK 36 +#define MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC 37 +#define MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK 38 +#define MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC 39 +#define MDSS_DISP_CC_MDSS_DPTX1_PIXEL2_CLK 40 +#define MDSS_DISP_CC_MDSS_DPTX1_PIXEL2_CLK_SRC 41 +#define MDSS_DISP_CC_MDSS_DPTX1_PIXEL3_CLK 42 +#define MDSS_DISP_CC_MDSS_DPTX1_PIXEL3_CLK_SRC 43 +#define MDSS_DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK 44 +#define MDSS_DISP_CC_MDSS_DPTX2_AUX_CLK 45 +#define MDSS_DISP_CC_MDSS_DPTX2_AUX_CLK_SRC 46 +#define MDSS_DISP_CC_MDSS_DPTX2_CRYPTO_CLK 47 +#define MDSS_DISP_CC_MDSS_DPTX2_LINK_CLK 48 +#define MDSS_DISP_CC_MDSS_DPTX2_LINK_CLK_SRC 49 +#define MDSS_DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC 50 +#define MDSS_DISP_CC_MDSS_DPTX2_LINK_INTF_CLK 51 +#define MDSS_DISP_CC_MDSS_DPTX2_PIXEL0_CLK 52 +#define MDSS_DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC 53 +#define MDSS_DISP_CC_MDSS_DPTX2_PIXEL1_CLK 54 +#define MDSS_DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC 55 +#define MDSS_DISP_CC_MDSS_DPTX3_AUX_CLK 56 +#define MDSS_DISP_CC_MDSS_DPTX3_AUX_CLK_SRC 57 +#define MDSS_DISP_CC_MDSS_DPTX3_CRYPTO_CLK 58 +#define MDSS_DISP_CC_MDSS_DPTX3_LINK_CLK 59 +#define MDSS_DISP_CC_MDSS_DPTX3_LINK_CLK_SRC 60 +#define MDSS_DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC 61 +#define MDSS_DISP_CC_MDSS_DPTX3_LINK_INTF_CLK 62 +#define MDSS_DISP_CC_MDSS_DPTX3_PIXEL0_CLK 63 +#define MDSS_DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC 64 +#define MDSS_DISP_CC_MDSS_ESC0_CLK 65 +#define MDSS_DISP_CC_MDSS_ESC0_CLK_SRC 66 +#define MDSS_DISP_CC_MDSS_ESC1_CLK 67 +#define MDSS_DISP_CC_MDSS_ESC1_CLK_SRC 68 +#define MDSS_DISP_CC_MDSS_MDP1_CLK 69 +#define MDSS_DISP_CC_MDSS_MDP_CLK 70 +#define MDSS_DISP_CC_MDSS_MDP_CLK_SRC 71 +#define MDSS_DISP_CC_MDSS_MDP_LUT1_CLK 72 +#define MDSS_DISP_CC_MDSS_MDP_LUT_CLK 73 +#define MDSS_DISP_CC_MDSS_NON_GDSC_AHB_CLK 74 +#define MDSS_DISP_CC_MDSS_PCLK0_CLK 75 +#define MDSS_DISP_CC_MDSS_PCLK0_CLK_SRC 76 +#define MDSS_DISP_CC_MDSS_PCLK1_CLK 77 +#define MDSS_DISP_CC_MDSS_PCLK1_CLK_SRC 78 +#define MDSS_DISP_CC_MDSS_PCLK2_CLK 79 +#define MDSS_DISP_CC_MDSS_PCLK2_CLK_SRC 80 +#define MDSS_DISP_CC_MDSS_RSCC_AHB_CLK 81 +#define MDSS_DISP_CC_MDSS_RSCC_VSYNC_CLK 82 +#define MDSS_DISP_CC_MDSS_VSYNC1_CLK 83 +#define MDSS_DISP_CC_MDSS_VSYNC_CLK 84 +#define MDSS_DISP_CC_MDSS_VSYNC_CLK_SRC 85 +#define MDSS_DISP_CC_PLL0 86 +#define MDSS_DISP_CC_PLL1 87 +#define MDSS_DISP_CC_PLL2 88 +#define MDSS_DISP_CC_PLL3 89 +#define MDSS_DISP_CC_SLEEP_CLK 90 +#define MDSS_DISP_CC_SLEEP_CLK_SRC 91 +#define MDSS_DISP_CC_SM_DIV_CLK_SRC 92 +#define MDSS_DISP_CC_XO_CLK 93 +#define MDSS_DISP_CC_XO_CLK_SRC 94 + +/* DISP_CC_0 and DISP_CC_1 power domains */ +#define MDSS_DISP_CC_MDSS_CORE_GDSC 0 +#define MDSS_DISP_CC_MDSS_CORE_INT2_GDSC 1 + +/* DISP_CC_0 and DISP_CC_1 resets */ +#define MDSS_DISP_CC_MDSS_CORE_BCR 0 +#define MDSS_DISP_CC_MDSS_CORE_INT2_BCR 1 +#define MDSS_DISP_CC_MDSS_RSCC_BCR 2 + +#endif diff --git a/include/dt-bindings/clock/qcom,nord-gpu2cc.h b/include/dt-bindings/clock/qcom,nord-gpu2cc.h new file mode 100644 index 000000000000..3886af669c61 --- /dev/null +++ b/include/dt-bindings/clock/qcom,nord-gpu2cc.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_2_CC_NORD_H +#define _DT_BINDINGS_CLK_QCOM_GPU_2_CC_NORD_H + +/* GPU_2_CC clocks */ +#define GPU_2_CC_AHB_CLK 0 +#define GPU_2_CC_CRC_AHB_CLK 1 +#define GPU_2_CC_CX_ACCU_SHIFT_CLK 2 +#define GPU_2_CC_CX_FF_CLK 3 +#define GPU_2_CC_CX_GMU_CLK 4 +#define GPU_2_CC_CXO_AON_CLK 5 +#define GPU_2_CC_CXO_CLK 6 +#define GPU_2_CC_DEMET_CLK 7 +#define GPU_2_CC_FF_CLK_SRC 8 +#define GPU_2_CC_FREQ_MEASURE_CLK 9 +#define GPU_2_CC_GMU_CLK_SRC 10 +#define GPU_2_CC_GPU_SMMU_VOTE_CLK 11 +#define GPU_2_CC_HUB_AON_CLK 12 +#define GPU_2_CC_HUB_CLK_SRC 13 +#define GPU_2_CC_HUB_CX_INT_CLK 14 +#define GPU_2_CC_MEMNOC_GFX_CLK 15 +#define GPU_2_CC_MND1X_0_GFX3D_CLK 16 +#define GPU_2_CC_MND1X_1_GFX3D_CLK 17 +#define GPU_2_CC_PLL0 18 +#define GPU_2_CC_PLL1 19 +#define GPU_2_CC_SLEEP_CLK 20 + +/* GPU_2_CC power domains */ +#define GPU_2_CC_CX_GDSC 0 +#define GPU_2_CC_GX_GDSC 1 + +/* GPU_2_CC resets */ +#define GPU_2_CC_ACD_BCR 0 +#define GPU_2_CC_CB_BCR 1 +#define GPU_2_CC_CX_BCR 2 +#define GPU_2_CC_FAST_HUB_BCR 3 +#define GPU_2_CC_FF_BCR 4 +#define GPU_2_CC_GFX3D_AON_BCR 5 +#define GPU_2_CC_GMU_BCR 6 +#define GPU_2_CC_GX_BCR 7 +#define GPU_2_CC_XO_BCR 8 + +#endif diff --git a/include/dt-bindings/clock/qcom,nord-gpucc.h b/include/dt-bindings/clock/qcom,nord-gpucc.h new file mode 100644 index 000000000000..3cc348be5668 --- /dev/null +++ b/include/dt-bindings/clock/qcom,nord-gpucc.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_NORD_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_NORD_H + +/* GPU_CC clocks */ +#define GPU_CC_ACD_GFX3D_CLK 0 +#define GPU_CC_ACMU_CLK 1 +#define GPU_CC_AHB_CLK 2 +#define GPU_CC_CRC_AHB_CLK 3 +#define GPU_CC_CX_ACCU_SHIFT_CLK 4 +#define GPU_CC_CX_FF_CLK 5 +#define GPU_CC_CX_GMU_CLK 6 +#define GPU_CC_CXO_AON_CLK 7 +#define GPU_CC_CXO_CLK 8 +#define GPU_CC_DEMET_CLK 9 +#define GPU_CC_DPM_CLK 10 +#define GPU_CC_FF_CLK_SRC 11 +#define GPU_CC_FREQ_MEASURE_CLK 12 +#define GPU_CC_GMU_CLK_SRC 13 +#define GPU_CC_GPU_SMMU_VOTE_CLK 14 +#define GPU_CC_HUB_AON_CLK 15 +#define GPU_CC_HUB_CLK_SRC 16 +#define GPU_CC_HUB_CX_INT_CLK 17 +#define GPU_CC_HUB_DIV_CLK_SRC 18 +#define GPU_CC_MEMNOC_GFX_CLK 19 +#define GPU_CC_MND1X_GFX3D_CLK 20 +#define GPU_CC_PLL0 21 +#define GPU_CC_PLL1 22 +#define GPU_CC_SLEEP_CLK 23 + +/* GPU_CC power domains */ +#define GPU_CC_CX_GDSC 0 +#define GPU_CC_GX_GDSC 1 + +/* GPU_CC resets */ +#define GPU_CC_ACD_BCR 0 +#define GPU_CC_CB_BCR 1 +#define GPU_CC_CX_BCR 2 +#define GPU_CC_FAST_HUB_BCR 3 +#define GPU_CC_GFX3D_AON_BCR 4 +#define GPU_CC_GX_BCR 5 +#define GPU_CC_XO_BCR 6 + +#endif diff --git a/include/dt-bindings/clock/qcom,shikra-audiocorecc.h b/include/dt-bindings/clock/qcom,shikra-audiocorecc.h new file mode 100644 index 000000000000..0e64a42523f1 --- /dev/null +++ b/include/dt-bindings/clock/qcom,shikra-audiocorecc.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_AUDIO_CORE_CC_SHIKRA_H +#define _DT_BINDINGS_CLK_QCOM_AUDIO_CORE_CC_SHIKRA_H + +/* AUDIO_CORE_CC clocks */ +#define AUDIO_CORE_CC_DIG_PLL_OUT_AUX 0 +#define AUDIO_CORE_CC_DIG_PLL_OUT_AUX2 1 +#define AUDIO_CORE_CC_DIG_PLL 2 +#define AUDIO_CORE_CC_AIF_IF0_CLK_SRC 3 +#define AUDIO_CORE_CC_AIF_IF0_EBIT_CLK 4 +#define AUDIO_CORE_CC_AIF_IF0_IBIT_CLK 5 +#define AUDIO_CORE_CC_AIF_IF1_CLK_SRC 6 +#define AUDIO_CORE_CC_AIF_IF1_EBIT_CLK 7 +#define AUDIO_CORE_CC_AIF_IF1_IBIT_CLK 8 +#define AUDIO_CORE_CC_AIF_IF2_CLK_SRC 9 +#define AUDIO_CORE_CC_AIF_IF2_EBIT_CLK 10 +#define AUDIO_CORE_CC_AIF_IF2_IBIT_CLK 11 +#define AUDIO_CORE_CC_AIF_IF3_CLK_SRC 12 +#define AUDIO_CORE_CC_AIF_IF3_EBIT_CLK 13 +#define AUDIO_CORE_CC_AIF_IF3_IBIT_CLK 14 +#define AUDIO_CORE_CC_AUD_DMA_CLK 15 +#define AUDIO_CORE_CC_AUD_DMA_CLK_SRC 16 +#define AUDIO_CORE_CC_AUD_DMA_MEM_CLK 17 +#define AUDIO_CORE_CC_BUS_CLK 18 +#define AUDIO_CORE_CC_BUS_CLK_SRC 19 +#define AUDIO_CORE_CC_CDIV_TX_MCLK_DIV_CLK_SRC 20 +#define AUDIO_CORE_CC_EXT_MCLKA_CLK_SRC 21 +#define AUDIO_CORE_CC_EXT_MCLKA_OUT_CLK 22 +#define AUDIO_CORE_CC_EXT_MCLKB_CLK_SRC 23 +#define AUDIO_CORE_CC_EXT_MCLKB_OUT_CLK 24 +#define AUDIO_CORE_CC_IM_SLEEP_CLK 25 +#define AUDIO_CORE_CC_LPAIF_PCMOE_CLK 26 +#define AUDIO_CORE_CC_LPAIF_PCMOE_CLK_SRC 27 +#define AUDIO_CORE_CC_RX_MCLK_2X_CLK 28 +#define AUDIO_CORE_CC_RX_MCLK_CLK 29 +#define AUDIO_CORE_CC_SAMPLING_CLK 30 +#define AUDIO_CORE_CC_TX_MCLK_2X_CLK 31 +#define AUDIO_CORE_CC_TX_MCLK_CLK 32 +#define AUDIO_CORE_CC_TX_MCLK_RCG_CLK_SRC 33 + +/* AUDIO_CORE_CSR resets */ +#define AUDIO_CORE_CSR_RX_SWR_CGCR 0 +#define AUDIO_CORE_CSR_TX_SWR_CGCR 1 + +#endif diff --git a/include/dt-bindings/clock/renesas,r8a78000-cpg.h b/include/dt-bindings/clock/renesas,r8a78000-cpg.h new file mode 100644 index 000000000000..7fd09a3fb353 --- /dev/null +++ b/include/dt-bindings/clock/renesas,r8a78000-cpg.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2026 Glider bv + */ +#ifndef __DT_BINDINGS_CLOCK_RENESAS_R8A78000_CPG_H__ +#define __DT_BINDINGS_CLOCK_RENESAS_R8A78000_CPG_H__ + +/* R-Car X5H Clock Pulse Generator Clocks */ + +#define R8A78000_CPG_SGASYNCD4_PERW_BUS 0 +#define R8A78000_CPG_SGASYNCD8_PERW_BUS 1 +#define R8A78000_CPG_SGASYNCD16_PERW_BUS 2 + +#endif /* __DT_BINDINGS_CLOCK_RENESAS_R8A78000_CPG_H__ */ diff --git a/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h b/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h index c4863e444458..aa47685f329a 100644 --- a/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h +++ b/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h @@ -34,5 +34,7 @@ #define R9A09G077_XSPI_CLK0 22 #define R9A09G077_XSPI_CLK1 23 #define R9A09G077_PCLKCAN 24 +#define R9A09G077_LCDC_CLKD 25 +#define R9A09G077_PCLKRTC 26 #endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__ */ diff --git a/include/dt-bindings/clock/renesas,r9a09g087-cpg-mssr.h b/include/dt-bindings/clock/renesas,r9a09g087-cpg-mssr.h index 0d53f1e65077..1c73d0dcef18 100644 --- a/include/dt-bindings/clock/renesas,r9a09g087-cpg-mssr.h +++ b/include/dt-bindings/clock/renesas,r9a09g087-cpg-mssr.h @@ -34,5 +34,7 @@ #define R9A09G087_XSPI_CLK0 22 #define R9A09G087_XSPI_CLK1 23 #define R9A09G087_PCLKCAN 24 +#define R9A09G087_LCDC_CLKD 25 +#define R9A09G087_PCLKRTC 26 #endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G087_CPG_H__ */ diff --git a/include/dt-bindings/clock/rockchip,rv1106-cru.h b/include/dt-bindings/clock/rockchip,rv1106-cru.h new file mode 100644 index 000000000000..80244988e139 --- /dev/null +++ b/include/dt-bindings/clock/rockchip,rv1106-cru.h @@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2022 Rockchip Electronics Co. Ltd. + * Author: Elaine Zhang + */ + +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1106_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RV1106_H + +/* pll clocks */ +#define PLL_APLL 0 +#define PLL_DPLL 1 +#define PLL_CPLL 2 +#define PLL_GPLL 3 +#define ARMCLK 4 + +/* clk (clocks) */ +#define PCLK_DDRPHY 5 +#define PCLK_DDR_ROOT 6 +#define PCLK_DDRMON 7 +#define CLK_TIMER_DDRMON 8 +#define PCLK_DDRC 9 +#define PCLK_DFICTRL 10 +#define ACLK_DDR_ROOT 11 +#define ACLK_SYS_SHRM 12 +#define HCLK_NPU_ROOT 13 +#define ACLK_NPU_ROOT 14 +#define PCLK_NPU_ROOT 15 +#define HCLK_RKNN 16 +#define ACLK_RKNN 17 +#define PCLK_ACODEC 18 +#define MCLK_ACODEC_TX 19 +#define CLK_CORE_CRYPTO 20 +#define CLK_PKA_CRYPTO 21 +#define ACLK_CRYPTO 22 +#define HCLK_CRYPTO 23 +#define ACLK_DECOM 24 +#define PCLK_DECOM 25 +#define DCLK_DECOM 26 +#define ACLK_DMAC 27 +#define PCLK_DSM 28 +#define MCLK_DSM 29 +#define CCLK_SRC_EMMC 30 +#define HCLK_EMMC 31 +#define PCLK_GPIO4 32 +#define DBCLK_GPIO4 33 +#define PCLK_I2C0 34 +#define CLK_I2C0 35 +#define PCLK_I2C2 36 +#define CLK_I2C2 37 +#define PCLK_I2C3 38 +#define CLK_I2C3 39 +#define PCLK_I2C4 40 +#define CLK_I2C4 41 +#define HCLK_I2S0 42 +#define PCLK_DFT2APB 43 +#define HCLK_IVE 44 +#define ACLK_IVE 45 +#define PCLK_PWM0_PERI 46 +#define CLK_PWM0_PERI 47 +#define CLK_CAPTURE_PWM0_PERI 48 +#define PCLK_PERI_ROOT 49 +#define ACLK_PERI_ROOT 50 +#define HCLK_PERI_ROOT 51 +#define CLK_TIMER_ROOT 52 +#define ACLK_BUS_ROOT 53 +#define HCLK_SFC 54 +#define SCLK_SFC 55 +#define PCLK_UART0 56 +#define CLK_PVTM_CORE 57 +#define PCLK_UART1 58 +#define CLK_CORE_MCU_RTC 59 +#define PCLK_PWM1_PERI 60 +#define CLK_PWM1_PERI 61 +#define CLK_CAPTURE_PWM1_PERI 62 +#define PCLK_PWM2_PERI 63 +#define CLK_PWM2_PERI 64 +#define CLK_CAPTURE_PWM2_PERI 65 +#define HCLK_BOOTROM 66 +#define HCLK_SAI 67 +#define MCLK_SAI 68 +#define PCLK_SARADC 69 +#define CLK_SARADC 70 +#define PCLK_SPI1 71 +#define CLK_SPI1 72 +#define PCLK_STIMER 73 +#define CLK_STIMER0 74 +#define CLK_STIMER1 75 +#define PCLK_TIMER 76 +#define CLK_TIMER0 77 +#define CLK_TIMER1 78 +#define CLK_TIMER2 79 +#define CLK_TIMER3 80 +#define CLK_TIMER4 81 +#define CLK_TIMER5 82 +#define HCLK_TRNG_NS 83 +#define HCLK_TRNG_S 84 +#define PCLK_UART2 85 +#define HCLK_CPU 86 +#define PCLK_UART3 87 +#define CLK_CORE_MCU 88 +#define PCLK_UART4 89 +#define PCLK_DDR_HWLP 90 +#define PCLK_UART5 91 +#define ACLK_USBOTG 92 +#define CLK_REF_USBOTG 93 +#define CLK_UTMI_USBOTG 94 +#define PCLK_USBPHY 95 +#define CLK_REF_USBPHY 96 +#define PCLK_WDT_NS 97 +#define TCLK_WDT_NS 98 +#define PCLK_WDT_S 99 +#define TCLK_WDT_S 100 +#define CLK_DDR_FAIL_SAFE 101 +#define XIN_OSC0_DIV 102 +#define CLK_DEEPSLOW 103 +#define PCLK_PMU_GPIO0 104 +#define DBCLK_PMU_GPIO0 105 +#define CLK_PMU 106 +#define PCLK_PMU 107 +#define PCLK_PMU_HP_TIMER 108 +#define CLK_PMU_HP_TIMER 109 +#define CLK_PMU_32K_HP_TIMER 110 +#define PCLK_I2C1 111 +#define CLK_I2C1 112 +#define PCLK_PMU_IOC 113 +#define PCLK_PMU_MAILBOX 114 +#define CLK_PMU_MCU 115 +#define CLK_PMU_MCU_RTC 116 +#define CLK_PMU_MCU_JTAG 117 +#define CLK_PVTM_PMU 118 +#define PCLK_PVTM_PMU 119 +#define CLK_REFOUT 120 +#define CLK_100M_PMU 121 +#define PCLK_PMU_ROOT 122 +#define HCLK_PMU_ROOT 123 +#define HCLK_PMU_SRAM 124 +#define PCLK_PMU_WDT 125 +#define TCLK_PMU_WDT 126 +#define CLK_DFICTRL 127 +#define CLK_DDRMON 128 +#define CLK_DDR_PHY 129 +#define ACLK_DDRC 130 +#define CLK_CORE_DDRC_SRC 131 +#define CLK_CORE_DDRC 132 +#define CLK_50M_SRC 133 +#define CLK_100M_SRC 134 +#define CLK_150M_SRC 135 +#define CLK_200M_SRC 136 +#define CLK_250M_SRC 137 +#define CLK_300M_SRC 138 +#define CLK_339M_SRC 139 +#define CLK_400M_SRC 140 +#define CLK_450M_SRC 141 +#define CLK_500M_SRC 142 +#define CLK_I2S0_8CH_TX_SRC 143 +#define CLK_I2S0_8CH_TX_FRAC 144 +#define CLK_I2S0_8CH_TX 145 +#define CLK_I2S0_8CH_RX_SRC 146 +#define CLK_I2S0_8CH_RX_FRAC 147 +#define CLK_I2S0_8CH_RX 148 +#define I2S0_8CH_MCLKOUT 149 +#define MCLK_I2S0_8CH_RX 150 +#define MCLK_I2S0_8CH_TX 151 +#define CLK_REF_MIPI0_SRC 152 +#define CLK_REF_MIPI0_FRAC 153 +#define CLK_REF_MIPI0_OUT 154 +#define CLK_REF_MIPI1_SRC 155 +#define CLK_REF_MIPI1_FRAC 156 +#define MCLK_REF_MIPI0 157 +#define MCLK_REF_MIPI1 158 +#define CLK_REF_MIPI0 159 +#define CLK_REF_MIPI1 160 +#define CLK_UART0_SRC 161 +#define CLK_UART0_FRAC 162 +#define CLK_UART0 163 +#define SCLK_UART0 164 +#define CLK_UART1_SRC 165 +#define CLK_UART1_FRAC 166 +#define CLK_UART1 167 +#define SCLK_UART1 168 +#define CLK_UART2_SRC 169 +#define CLK_UART2_FRAC 170 +#define CLK_UART2 171 +#define SCLK_UART2 172 +#define CLK_UART3_SRC 173 +#define CLK_UART3_FRAC 174 +#define CLK_UART3 175 +#define SCLK_UART3 176 +#define CLK_UART4_SRC 177 +#define CLK_UART4_FRAC 178 +#define CLK_UART4 179 +#define SCLK_UART4 180 +#define CLK_UART5_SRC 181 +#define CLK_UART5_FRAC 182 +#define CLK_UART5 183 +#define SCLK_UART5 184 +#define CLK_VICAP_M0_SRC 185 +#define CLK_VICAP_M0_FRAC 186 +#define CLK_VICAP_M0 187 +#define SCLK_VICAP_M0 188 +#define CLK_VICAP_M1_SRC 189 +#define CLK_VICAP_M1_FRAC 190 +#define CLK_VICAP_M1 191 +#define SCLK_VICAP_M1 192 +#define DCLK_VOP_SRC 193 +#define PCLK_CRU 194 +#define PCLK_TOP_ROOT 195 +#define PCLK_SPI0 196 +#define CLK_SPI0 197 +#define SCLK_IN_SPI0 198 +#define CLK_UART_DETN_FLT 199 +#define HCLK_VEPU 200 +#define ACLK_VEPU 201 +#define CLK_CORE_VEPU 202 +#define CLK_CORE_VEPU_DVBM 203 +#define PCLK_GPIO1 204 +#define DBCLK_GPIO1 205 +#define HCLK_VEPU_PP 206 +#define ACLK_VEPU_PP 207 +#define HCLK_VEPU_ROOT 208 +#define ACLK_VEPU_COM_ROOT 209 +#define ACLK_VEPU_ROOT 210 +#define PCLK_VEPU_ROOT 211 +#define PCLK_VICAP_VEPU 212 +#define PCLK_CSIHOST0 213 +#define CLK_RXBYTECLKHS_0 214 +#define PCLK_CSIHOST1 215 +#define CLK_RXBYTECLKHS_1 216 +#define PCLK_GPIO3 217 +#define DBCLK_GPIO3 218 +#define HCLK_ISP3P2 219 +#define ACLK_ISP3P2 220 +#define CLK_CORE_ISP3P2 221 +#define PCLK_MIPICSIPHY 222 +#define CCLK_SRC_SDMMC 223 +#define HCLK_SDMMC 224 +#define CLK_SDMMC_DETN_FLT 225 +#define HCLK_VI_ROOT 226 +#define ACLK_VI_ROOT 227 +#define PCLK_VI_ROOT 228 +#define PCLK_VI_RTC_ROOT 229 +#define PCLK_VI_RTC_TEST 230 +#define PCLK_VI_RTC_PHY 231 +#define DCLK_VICAP 232 +#define PCLK_VICAP 233 +#define ACLK_VICAP 234 +#define HCLK_VICAP 235 +#define I0CLK_VICAP 236 +#define I1CLK_VICAP 237 +#define RX0PCLK_VICAP 238 +#define RX1PCLK_VICAP 239 +#define ISP0CLK_VICAP 240 +#define PCLK_GPIO2 241 +#define DBCLK_GPIO2 242 +#define ACLK_MAC 243 +#define PCLK_MAC 244 +#define CLK_GMAC0_50M_O 245 +#define CLK_GMAC0_TX_50M_O 246 +#define CLK_GMAC0_REF_50M 247 +#define CLK_GMAC0_TX_50M 248 +#define CLK_GMAC0_RX_50M 249 +#define ACLK_MAC_ROOT 250 +#define CLK_MACPHY 251 +#define CLK_OTPC_ARB 252 +#define PCLK_OTPC_NS 253 +#define CLK_SBPI_OTPC_NS 254 +#define CLK_USER_OTPC_NS 255 +#define PCLK_OTPC_S 256 +#define CLK_SBPI_OTPC_S 257 +#define CLK_USER_OTPC_S 258 +#define PCLK_OTP_MASK 259 +#define CLK_PMC_OTP 260 +#define HCLK_RGA2E 261 +#define ACLK_RGA2E 262 +#define CLK_CORE_RGA2E 263 +#define CCLK_SRC_SDIO 264 +#define HCLK_SDIO 265 +#define PCLK_TSADC 266 +#define CLK_TSADC 267 +#define CLK_TSADC_TSEN 268 +#define ACLK_VO_ROOT 269 +#define HCLK_VO_ROOT 270 +#define PCLK_VO_ROOT 271 +#define ACLK_VOP_ROOT 272 +#define HCLK_VOP 273 +#define DCLK_VOP 274 +#define ACLK_VOP 275 +#define CLK_RTC_32K 276 +#define PCLK_MAILBOX 277 + +/* mmc phase clocks */ +#define SCLK_EMMC_DRV 278 +#define SCLK_EMMC_SAMPLE 279 +#define SCLK_SDMMC_DRV 280 +#define SCLK_SDMMC_SAMPLE 281 +#define SCLK_SDIO_DRV 282 +#define SCLK_SDIO_SAMPLE 283 + +/* internal clocks */ +#define XIN_OSC0_HALF 284 +#define PCLK_DBG 285 +#define PCLK_CPU_ROOT 286 +#define CLK_RTC32K_FRAC 287 + +#endif diff --git a/include/dt-bindings/clock/samsung,exynos990.h b/include/dt-bindings/clock/samsung,exynos990.h index 47540307cb52..c06f591d9d90 100644 --- a/include/dt-bindings/clock/samsung,exynos990.h +++ b/include/dt-bindings/clock/samsung,exynos990.h @@ -434,5 +434,6 @@ #define CLK_GOUT_PERIS_TMU_TOP_PCLK 17 #define CLK_GOUT_PERIS_OTP_CON_BIRA_OSCCLK 18 #define CLK_GOUT_PERIS_OTP_CON_TOP_OSCCLK 19 +#define CLK_GOUT_PERIS_TMU_SUB_PCLK 20 #endif diff --git a/include/dt-bindings/clock/spacemit,k3-clocks.h b/include/dt-bindings/clock/spacemit,k3-clocks.h index dfae52547cda..4f1099f5da1c 100644 --- a/include/dt-bindings/clock/spacemit,k3-clocks.h +++ b/include/dt-bindings/clock/spacemit,k3-clocks.h @@ -145,6 +145,9 @@ #define CLK_MPMU_I2S3_SYSCLK 48 #define CLK_MPMU_I2S4_SYSCLK 49 #define CLK_MPMU_I2S5_SYSCLK 50 +#define CLK_MPMU_I2S_SYSCLK 51 +#define CLK_MPMU_I2S_BCLK_FACTOR 52 +#define CLK_MPMU_I2S1_SYSCLK_SRC 53 /* APBC clocks */ #define CLK_APBC_UART0 0 @@ -385,6 +388,7 @@ #define CLK_APMU_PCIE_PORTC_DBI 91 #define CLK_APMU_PCIE_PORTD_DBI 92 #define CLK_APMU_PCIE_PORTE_DBI 93 +#define CLK_APMU_UFS_REFCLK 94 /* DCIU clocks */ #define CLK_DCIU_HDMA 0 diff --git a/include/dt-bindings/clock/sun6i-rtc.h b/include/dt-bindings/clock/sun6i-rtc.h index 3bd3aa3d57ce..5132a393ca4b 100644 --- a/include/dt-bindings/clock/sun6i-rtc.h +++ b/include/dt-bindings/clock/sun6i-rtc.h @@ -6,5 +6,9 @@ #define CLK_OSC32K 0 #define CLK_OSC32K_FANOUT 1 #define CLK_IOSC 2 +#define CLK_HOSC_UFS 8 +#define CLK_HOSC_HDMI 9 +#define CLK_HOSC_SERDES0 10 +#define CLK_HOSC_SERDES1 11 #endif /* _DT_BINDINGS_CLK_SUN6I_RTC_H_ */ diff --git a/include/dt-bindings/clock/ultrarisc,dp1000-clk.h b/include/dt-bindings/clock/ultrarisc,dp1000-clk.h new file mode 100644 index 000000000000..751125f99965 --- /dev/null +++ b/include/dt-bindings/clock/ultrarisc,dp1000-clk.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +#ifndef _DT_BINDINGS_CLOCK_ULTRARISC_DP1000_CLK_H +#define _DT_BINDINGS_CLOCK_ULTRARISC_DP1000_CLK_H + +#define DP1000_CLK_SYSPLL 0 +#define DP1000_CLK_SYSPLL_DIV2 1 +#define DP1000_CLK_SUBSYS 2 +#define DP1000_CLK_GMAC 3 +#define DP1000_CLK_UART_ROOT 4 +#define DP1000_CLK_I2C_ROOT 5 +#define DP1000_CLK_SPI_ROOT 6 +#define DP1000_CLK_PCIE_DBI 7 +#define DP1000_CLK_PCIEX4_CORE 8 +#define DP1000_CLK_PCIEX16_CORE 9 +#define DP1000_CLK_PCIE_AUX 10 +#define DP1000_CLK_UART0 11 +#define DP1000_CLK_UART1 12 +#define DP1000_CLK_UART2 13 +#define DP1000_CLK_UART3 14 +#define DP1000_CLK_I2C0 15 +#define DP1000_CLK_I2C1 16 +#define DP1000_CLK_I2C2 17 +#define DP1000_CLK_I2C3 18 +#define DP1000_CLK_SPI0 19 +#define DP1000_CLK_SPI1 20 + +#endif /* _DT_BINDINGS_CLOCK_ULTRARISC_DP1000_CLK_H */ diff --git a/include/dt-bindings/reset/airoha,en7581-reset.h b/include/dt-bindings/reset/airoha,en7581-reset.h index 6544a1790b83..25e75534daa9 100644 --- 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/include/dt-bindings/reset/cix,sky1-audss-cru.h b/include/dt-bindings/reset/cix,sky1-audss-cru.h new file mode 100644 index 000000000000..55e9f3797b30 --- /dev/null +++ b/include/dt-bindings/reset/cix,sky1-audss-cru.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright 2026 Cix Technology Group Co., Ltd. + */ +#ifndef DT_BINDINGS_RESET_CIX_SKY1_AUDSS_CRU_H +#define DT_BINDINGS_RESET_CIX_SKY1_AUDSS_CRU_H + +#define AUDSS_I2S0_SW_RST 0 +#define AUDSS_I2S1_SW_RST 1 +#define AUDSS_I2S2_SW_RST 2 +#define AUDSS_I2S3_SW_RST 3 +#define AUDSS_I2S4_SW_RST 4 +#define AUDSS_I2S5_SW_RST 5 +#define AUDSS_I2S6_SW_RST 6 +#define AUDSS_I2S7_SW_RST 7 +#define AUDSS_I2S8_SW_RST 8 +#define AUDSS_I2S9_SW_RST 9 +#define AUDSS_WDT_SW_RST 10 +#define AUDSS_TIMER_SW_RST 11 +#define AUDSS_MB0_SW_RST 12 +#define AUDSS_MB1_SW_RST 13 +#define AUDSS_HDA_SW_RST 14 +#define AUDSS_DMAC_SW_RST 15 + +#endif diff --git a/include/dt-bindings/reset/eswin,eic7700-hspcrg.h b/include/dt-bindings/reset/eswin,eic7700-hspcrg.h new file mode 100644 index 000000000000..413fcd08c701 --- /dev/null +++ b/include/dt-bindings/reset/eswin,eic7700-hspcrg.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd.. + * All rights reserved. + * + * Device Tree binding constants for EIC7700 HSP reset controller. + * + * Authors: Xuyang Dong + */ + +#ifndef _DT_BINDINGS_ESWIN_EIC7700_HSPCRG_RESET_H_ +#define _DT_BINDINGS_ESWIN_EIC7700_HSPCRG_RESET_H_ + +#define EIC7700_HSP_RST_SATA_P0 0 +#define EIC7700_HSP_RST_SATA_PHY 1 +#define EIC7700_HSP_RST_USB0 2 +#define EIC7700_HSP_RST_USB1 3 +#define EIC7700_HSP_RST_USB0_PHY 4 +#define EIC7700_HSP_RST_USB1_PHY 5 + +#endif /* _DT_BINDINGS_ESWIN_EIC7700_HSPCRG_RESET_H_ */ diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index b01a38fef8cf..dc8e161f9c2c 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -6,31 +6,44 @@ #ifndef __LINUX_CLK_PROVIDER_H #define __LINUX_CLK_PROVIDER_H +#include #include #include -/* - * flags used across common struct clk. these flags should only affect the - * top-level framework. custom flags for dealing with hardware specifics - * belong in struct clk_foo +/** + * DOC: clk framework flags * - * Please update clk_flags[] in drivers/clk/clk.c when making changes here! + * Flags used across common struct clk. These flags should only affect the + * top-level framework. Custom flags for dealing with hardware specifics + * belong in struct clk_foo. + * + * * CLK_SET_RATE_GATE - must be gated across rate change + * * CLK_SET_PARENT_GATE - must be gated across re-parent + * * CLK_SET_RATE_PARENT - propagate rate change up one level + * * CLK_IGNORE_UNUSED - do not gate even if unused + * * CLK_GET_RATE_NOCACHE - do not use the cached clk rate + * * CLK_SET_RATE_NO_REPARENT - don't re-parent on rate change + * * CLK_GET_ACCURACY_NOCACHE - do not use the cached clk accuracy + * * CLK_RECALC_NEW_RATES - recalc rates after notifications + * * CLK_SET_RATE_UNGATE - clock needs to run to set rate + * * CLK_IS_CRITICAL - do not gate, ever + * * CLK_OPS_PARENT_ENABLE - parents need enable during gate/ungate, set rate and re-parent + * * CLK_DUTY_CYCLE_PARENT - duty cycle call may be forwarded to the parent clock */ -#define CLK_SET_RATE_GATE BIT(0) /* must be gated across rate change */ -#define CLK_SET_PARENT_GATE BIT(1) /* must be gated across re-parent */ -#define CLK_SET_RATE_PARENT BIT(2) /* propagate rate change up one level */ -#define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */ +/* Please update clk_flags[] in drivers/clk/clk.c when making changes here! */ +#define CLK_SET_RATE_GATE BIT(0) +#define CLK_SET_PARENT_GATE BIT(1) +#define CLK_SET_RATE_PARENT BIT(2) +#define CLK_IGNORE_UNUSED BIT(3) /* unused */ /* unused */ -#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */ -#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ -#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */ -#define CLK_RECALC_NEW_RATES BIT(9) /* recalc rates after notifications */ -#define CLK_SET_RATE_UNGATE BIT(10) /* clock needs to run to set rate */ -#define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */ -/* parents need enable during gate/ungate, set rate and re-parent */ +#define CLK_GET_RATE_NOCACHE BIT(6) +#define CLK_SET_RATE_NO_REPARENT BIT(7) +#define CLK_GET_ACCURACY_NOCACHE BIT(8) +#define CLK_RECALC_NEW_RATES BIT(9) +#define CLK_SET_RATE_UNGATE BIT(10) +#define CLK_IS_CRITICAL BIT(11) #define CLK_OPS_PARENT_ENABLE BIT(12) -/* duty cycle call may be forwarded to the parent clock */ #define CLK_DUTY_CYCLE_PARENT BIT(13) struct clk; @@ -84,6 +97,26 @@ struct clk_duty { unsigned int den; }; +enum clk_ssc_method { + CLK_SPREAD_NO = CLK_SSC_NO_SPREAD, + CLK_SPREAD_CENTER = CLK_SSC_CENTER_SPREAD, + CLK_SPREAD_UP = CLK_SSC_UP_SPREAD, + CLK_SPREAD_DOWN = CLK_SSC_DOWN_SPREAD, +}; + +/** + * struct clk_spread_spectrum - Structure encoding spread spectrum of a clock + * + * @modfreq_hz: Modulation frequency + * @spread_bp: Modulation percent in permyriad + * @method: Modulation method + */ +struct clk_spread_spectrum { + u32 modfreq_hz; + u32 spread_bp; + enum clk_ssc_method method; +}; + /** * struct clk_ops - Callback operations for hardware clocks; these are to * be provided by the clock implementation, and will be called by drivers @@ -174,6 +207,12 @@ struct clk_duty { * separately via calls to .set_parent and .set_rate. * Returns 0 on success, -EERROR otherwise. * + * @set_spread_spectrum: Optional callback used to configure the spread + * spectrum modulation frequency, percentage, and method + * to reduce EMI by spreading the clock frequency over a + * wider range. + * Returns 0 on success, -EERROR otherwise. + * * @recalc_accuracy: Recalculate the accuracy of this clock. The clock accuracy * is expressed in ppb (parts per billion). The parent accuracy is * an input parameter. @@ -249,6 +288,8 @@ struct clk_ops { int (*set_rate_and_parent)(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate, u8 index); + int (*set_spread_spectrum)(struct clk_hw *hw, + const struct clk_spread_spectrum *ss_conf); unsigned long (*recalc_accuracy)(struct clk_hw *hw, unsigned long parent_accuracy); int (*get_phase)(struct clk_hw *hw); @@ -1152,13 +1193,16 @@ struct clk_fixed_factor { #define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw) extern const struct clk_ops clk_fixed_factor_ops; +struct clk_hw * +__clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, + const char *name, const char *parent_name, + const struct clk_hw *parent_hw, const struct clk_parent_data *pdata, + unsigned long flags, unsigned int mult, unsigned int div, + unsigned long acc, unsigned int fixflags, bool devm); struct clk *clk_register_fixed_factor(struct device *dev, const char *name, const char *parent_name, unsigned long flags, unsigned int mult, unsigned int div); void clk_unregister_fixed_factor(struct clk *clk); -struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, - const char *name, const char *parent_name, unsigned long flags, - unsigned int mult, unsigned int div); struct clk_hw *clk_hw_register_fixed_factor_fwname(struct device *dev, struct device_node *np, const char *name, const char *fw_name, unsigned long flags, unsigned int mult, unsigned int div); @@ -1170,9 +1214,6 @@ struct clk_hw *clk_hw_register_fixed_factor_index(struct device *dev, const char *name, unsigned int index, unsigned long flags, unsigned int mult, unsigned int div); void clk_hw_unregister_fixed_factor(struct clk_hw *hw); -struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev, - const char *name, const char *parent_name, unsigned long flags, - unsigned int mult, unsigned int div); struct clk_hw *devm_clk_hw_register_fixed_factor_fwname(struct device *dev, struct device_node *np, const char *name, const char *fw_name, unsigned long flags, unsigned int mult, unsigned int div); @@ -1184,13 +1225,45 @@ struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev, const char *name, unsigned int index, unsigned long flags, unsigned int mult, unsigned int div); -struct clk_hw *devm_clk_hw_register_fixed_factor_parent_hw(struct device *dev, - const char *name, const struct clk_hw *parent_hw, - unsigned long flags, unsigned int mult, unsigned int div); +#define clk_hw_register_fixed_factor(dev, name, parent_name, \ + flags, mult, div) \ + __clk_hw_register_fixed_factor((dev), NULL, (name), (parent_name), \ + NULL, NULL, (flags), (mult), (div), \ + 0, 0, false) +#define clk_hw_register_fixed_factor_pdata(dev, np, name, pdata, \ + flags, mult, div, acc, fixflags) \ + __clk_hw_register_fixed_factor((dev), (np), (name), NULL, NULL, \ + (pdata), (flags), (mult), (div), \ + (acc), (fixflags), false) +#define devm_clk_hw_register_fixed_factor(dev, name, parent_name, flags, \ + mult, div) \ + __clk_hw_register_fixed_factor((dev), NULL, (name), (parent_name), \ + NULL, NULL, (flags), (mult), (div), 0, \ + 0, true) +/** + * devm_clk_hw_register_fixed_factor_parent_hw - Register a fixed factor clock with + * pointer to parent clock + * @dev: device that is registering this clock + * @name: name of this clock + * @parent_hw: pointer to parent clk + * @flags: fixed factor flags + * @mult: multiplier + * @div: divider + * + * Return: Pointer to fixed factor clk_hw structure that was registered or + * an error pointer. + */ +#define devm_clk_hw_register_fixed_factor_parent_hw(dev, name, parent_hw, \ + flags, mult, div) \ + __clk_hw_register_fixed_factor((dev), NULL, (name), NULL, \ + (parent_hw), NULL, (flags), (mult), \ + (div), 0, 0, true) -struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev, - const char *name, const struct clk_hw *parent_hw, - unsigned long flags, unsigned int mult, unsigned int div); +#define clk_hw_register_fixed_factor_parent_hw(dev, name, parent_hw, flags, \ + mult, div) \ + __clk_hw_register_fixed_factor((dev), NULL, (name), NULL, \ + (parent_hw), NULL, (flags), (mult), \ + (div), 0, 0, false) /** * struct clk_fractional_divider - adjustable fractional divider clock * @@ -1431,11 +1504,14 @@ int clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long flags); int clk_hw_determine_rate_no_reparent(struct clk_hw *hw, struct clk_rate_request *req); +int clk_determine_rate_noop(struct clk_hw *hw, struct clk_rate_request *req); void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent); void clk_hw_get_rate_range(struct clk_hw *hw, unsigned long *min_rate, unsigned long *max_rate); void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate, unsigned long max_rate); +int clk_hw_set_spread_spectrum(struct clk_hw *hw, + const struct clk_spread_spectrum *ss_conf); static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *src) { diff --git a/include/linux/clk.h b/include/linux/clk.h index 998ba3f261da..db9cf184fd99 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -502,6 +502,22 @@ int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, */ int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks, struct clk_bulk_data *clks); +/** + * devm_clk_bulk_get_enable - Get and enable bulk clocks (managed) + * @dev: device for clock "consumer" + * @num_clks: the number of clk_bulk_data + * @clks: pointer to the clk_bulk_data table of consumer + * + * Behaves the same as devm_clk_bulk_get() but also prepares and enables the + * clocks in one operation with management. The clks will automatically be + * disabled, unprepared and freed when the device is unbound. + * + * Return: 0 if all clocks specified in clk_bulk_data table are obtained and + * enabled successfully. Otherwise returns valid IS_ERR() condition containing + * errno. + */ +int __must_check devm_clk_bulk_get_enable(struct device *dev, int num_clks, + struct clk_bulk_data *clks); /** * devm_clk_bulk_get_optional_enable - Get and enable optional bulk clocks (managed) * @dev: device for clock "consumer" @@ -951,8 +967,8 @@ int clk_set_parent(struct clk *clk, struct clk *parent); * clk_get_parent - get the parent clock source for this clock * @clk: clock source * - * Returns struct clk corresponding to parent clock source, or - * valid IS_ERR() condition containing errno. + * Returns struct clk corresponding to parent clock source, or NULL + * if clk is NULL. */ struct clk *clk_get_parent(struct clk *clk); @@ -1052,6 +1068,13 @@ static inline int __must_check devm_clk_bulk_get_optional(struct device *dev, return 0; } +static inline int __must_check devm_clk_bulk_get_enable(struct device *dev, + int num_clks, + struct clk_bulk_data *clks) +{ + return 0; +} + static inline int __must_check devm_clk_bulk_get_optional_enable(struct device *dev, int num_clks, struct clk_bulk_data *clks) diff --git a/include/linux/clk/qcom.h b/include/linux/clk/qcom.h new file mode 100644 index 000000000000..11ac2d42ff9e --- /dev/null +++ b/include/linux/clk/qcom.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2026, Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __LINUX_CLK_QCOM_H +#define __LINUX_CLK_QCOM_H + +#include +#include +#include +#include +#include + +struct device; +struct platform_device; +struct regulator_bulk_data; + +/** + * struct qcom_clk_ref_desc - descriptor for a clkref_en gate clock + * @name: clock name exposed to the common clock framework + * @offset: clkref_en register offset from the block base + * @regulator_names: optional supply names enabled while preparing the clock + * @num_regulators: number of entries in @regulator_names + */ +struct qcom_clk_ref_desc { + const char *name; + u32 offset; + const char * const *regulator_names; + unsigned int num_regulators; +}; + +/** + * struct qcom_clk_ref - per-clock data for a clkref_en gate clock + * @hw: common clock framework hardware clock handle + * @regmap: register map backing the clkref_en register + * @desc: clock descriptor copied at registration time + * @regulators: optional bulk regulator handles for @desc.regulator_names + */ +struct qcom_clk_ref { + struct clk_hw hw; + struct regmap *regmap; + struct qcom_clk_ref_desc desc; + struct regulator_bulk_data *regulators; +}; + +#if IS_ENABLED(CONFIG_COMMON_CLK_QCOM) + +int qcom_clk_ref_probe(struct platform_device *pdev, + const struct regmap_config *config, + const struct qcom_clk_ref_desc * const *descs, + size_t num_clk_refs); + +#else + +static inline int +qcom_clk_ref_probe(struct platform_device *pdev, + const struct regmap_config *config, + const struct qcom_clk_ref_desc * const *descs, + size_t num_clk_refs) +{ + return -EOPNOTSUPP; +} + +#endif + +#endif diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h index 0949400f44de..c9495558cd5c 100644 --- a/include/linux/clk/renesas.h +++ b/include/linux/clk/renesas.h @@ -53,6 +53,9 @@ static inline void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) { } * various parameters used to configure a PLL. These limits ensure * the PLL operates within valid and stable ranges. * + * @input_fref: Reference input frequency to the PLL (in Hz). If set + * to 0, a default value of 24MHz is used. + * * @fout: Output frequency range (in MHz) * @fout.min: Minimum allowed output frequency * @fout.max: Maximum allowed output frequency @@ -78,6 +81,8 @@ static inline void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) { } * @k.max: Maximum delta-sigma value */ struct rzv2h_pll_limits { + u32 input_fref; + struct { u32 min; u32 max; @@ -184,28 +189,31 @@ struct rzv2h_pll_div_pars { .k = { .min = -32768, .max = 32767 }, \ } \ -#ifdef CONFIG_CLK_RZV2H -bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits, - struct rzv2h_pll_pars *pars, u64 freq_millihz); +#ifdef CONFIG_CLK_RZV2H_CPG_LIB +bool rzv2h_cpg_get_pll_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_pars *pars, u64 freq_millihz); -bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, - struct rzv2h_pll_div_pars *pars, - const u8 *table, u8 table_size, u64 freq_millihz); +bool rzv2h_cpg_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_div_pars *pars, + const u8 *table, u8 table_size, u64 freq_millihz); #else -static inline bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits, - struct rzv2h_pll_pars *pars, - u64 freq_millihz) +static inline bool rzv2h_cpg_get_pll_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_pars *pars, + u64 freq_millihz) { return false; } -static inline bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, - struct rzv2h_pll_div_pars *pars, - const u8 *table, u8 table_size, - u64 freq_millihz) +static inline bool rzv2h_cpg_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_div_pars *pars, + const u8 *table, u8 table_size, + u64 freq_millihz) { return false; } #endif +#define rzv2h_get_pll_pars rzv2h_cpg_get_pll_pars +#define rzv2h_get_pll_divs_pars rzv2h_cpg_get_pll_divs_pars + #endif diff --git a/include/soc/spacemit/k3-syscon.h b/include/soc/spacemit/k3-syscon.h index a68255dd641f..959d8d0786fe 100644 --- a/include/soc/spacemit/k3-syscon.h +++ b/include/soc/spacemit/k3-syscon.h @@ -45,7 +45,8 @@ #define POSR_PLL7_LOCK BIT(30) #define POSR_PLL8_LOCK BIT(31) #define MPMU_SUCCR 0x0014 -#define MPMU_ISCCR 0x0044 +#define MPMU_ISCCR0 0x0040 +#define MPMU_ISCCR1 0x0044 #define MPMU_WDTPCR 0x0200 #define MPMU_RIPCCR 0x0210 #define MPMU_ACGR 0x1024