diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml index eb24a5687639..fc37786ac7ed 100644 --- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml @@ -23,6 +23,7 @@ description: | All these identifiers can be found in: [1]: . + [2]: . The clocks are provided inside a system controller node. @@ -50,6 +51,12 @@ properties: description: ID of the controller reset line const: 1 + '#phy-cells': + description: + The first cell indicates the serdes phy number, see [2] for the + available serdes port. + const: 1 + required: - compatible - reg @@ -65,12 +72,23 @@ allOf: reg: minItems: 2 + '#phy-cells': false + - if: properties: compatible: - enum: - - airoha,en7581-scu - - econet,en751221-scu + const: econet,en751221-scu + then: + properties: + reg: + maxItems: 1 + + '#phy-cells': false + + - if: + properties: + compatible: + const: airoha,en7581-scu then: properties: reg: diff --git a/Documentation/devicetree/bindings/clock/anlogic,dr1v90-cru.yaml b/Documentation/devicetree/bindings/clock/anlogic,dr1v90-cru.yaml new file mode 100644 index 000000000000..482640bcf644 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/anlogic,dr1v90-cru.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/anlogic,dr1v90-cru.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Anlogic DR1V90 Clock and Reset Unit (CRU) + +maintainers: + - Junhui Liu + +properties: + compatible: + const: anlogic,dr1v90-cru + + reg: + maxItems: 1 + + clocks: + minItems: 1 + maxItems: 3 + description: + The main oscillator is always required. Either or both of the external CAN + and WDT clocks may also be provided if the board routes them to the SoC. + + clock-names: + minItems: 1 + items: + - const: osc + - enum: [can_ext, wdt_ext] + - const: wdt_ext + + "#clock-cells": + const: 1 + description: + Refer for valid indices. + + "#reset-cells": + const: 1 + description: + Refer for valid indices. + +required: + - compatible + - reg + - clocks + - clock-names + - "#clock-cells" + - "#reset-cells" + +additionalProperties: false + +examples: + - | + clock-controller@f8801000 { + compatible = "anlogic,dr1v90-cru"; + reg = <0xf8801000 0x400>; + clocks = <&osc>, <&can_ext>, <&wdt_ext>; + clock-names = "osc", "can_ext", "wdt_ext"; + #clock-cells = <1>; + #reset-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/clock/clk-palmas-clk32kg-clocks.txt b/Documentation/devicetree/bindings/clock/clk-palmas-clk32kg-clocks.txt deleted file mode 100644 index 4208886d834a..000000000000 --- a/Documentation/devicetree/bindings/clock/clk-palmas-clk32kg-clocks.txt +++ /dev/null @@ -1,35 +0,0 @@ -* Palmas 32KHz clocks * - -Palmas device has two clock output pins for 32KHz, KG and KG_AUDIO. - -This binding uses the common clock binding ./clock-bindings.txt. - -Required properties: -- compatible : "ti,palmas-clk32kg" for clk32kg clock - "ti,palmas-clk32kgaudio" for clk32kgaudio clock -- #clock-cells : shall be set to 0. - -Optional property: -- ti,external-sleep-control: The external enable input pins controlled the - enable/disable of clocks. The external enable input pins ENABLE1, - ENABLE2 and NSLEEP. The valid values for the external pins are: - PALMAS_EXT_CONTROL_PIN_ENABLE1 for ENABLE1 pin - PALMAS_EXT_CONTROL_PIN_ENABLE2 for ENABLE2 pin - PALMAS_EXT_CONTROL_PIN_NSLEEP for NSLEEP pin - Option 0 or missing this property means the clock is enabled/disabled - via register access and these pins do not have any control. - The macros of external control pins for DTS is defined at - dt-bindings/mfd/palmas.h - -Example: - #include - ... - palmas: tps65913@58 { - ... - clk32kg: palmas_clk32k@0 { - compatible = "ti,palmas-clk32kg"; - #clock-cells = <0>; - ti,external-sleep-control = ; - }; - ... - }; diff --git a/Documentation/devicetree/bindings/clock/clock-nexus-node.yaml b/Documentation/devicetree/bindings/clock/clock-nexus-node.yaml new file mode 100644 index 000000000000..ff3283bd5fb1 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/clock-nexus-node.yaml @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/clock-nexus-node.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Clock Nexus + +description: > + A nexus node allows to remap a clock specifier list in a consumer node + through a container or a connector node in a generic way. With this + remapping, the consumer node needs to know only about the nexus + node. Resources behind the nexus node are decoupled by the nexus node + itself. + +maintainers: + - Miquel Raynal + +select: true + +properties: + clock-map: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + +dependentRequired: + clock-map: ['#clock-cells'] + +additionalProperties: true + +# See the original pwm-nexus-node.yaml description for examples diff --git a/Documentation/devicetree/bindings/clock/hi3660-clock.txt b/Documentation/devicetree/bindings/clock/hi3660-clock.txt deleted file mode 100644 index 946da7cee54f..000000000000 --- a/Documentation/devicetree/bindings/clock/hi3660-clock.txt +++ /dev/null @@ -1,47 +0,0 @@ -* Hisilicon Hi3660 Clock Controller - -The Hi3660 clock controller generates and supplies clock to various -controllers within the Hi3660 SoC. - -Required Properties: - -- compatible: the compatible should be one of the following strings to - indicate the clock controller functionality. - - - "hisilicon,hi3660-crgctrl" - - "hisilicon,hi3660-pctrl" - - "hisilicon,hi3660-pmuctrl" - - "hisilicon,hi3660-sctrl" - - "hisilicon,hi3660-iomcu" - - "hisilicon,hi3660-stub-clk" - -- reg: physical base address of the controller and length of memory mapped - region. - -- #clock-cells: should be 1. - -Optional Properties: - -- mboxes: Phandle to the mailbox for sending message to MCU. - (See: ../mailbox/hisilicon,hi3660-mailbox.txt for more info) - -Each clock is assigned an identifier and client nodes use this identifier -to specify the clock which they consume. - -All these identifier could be found in . - -Examples: - crg_ctrl: clock-controller@fff35000 { - compatible = "hisilicon,hi3660-crgctrl", "syscon"; - reg = <0x0 0xfff35000 0x0 0x1000>; - #clock-cells = <1>; - }; - - uart0: serial@fdf02000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0 0xfdf02000 0x0 0x1000>; - interrupts = ; - clocks = <&crg_ctrl HI3660_CLK_MUX_UART0>, - <&crg_ctrl HI3660_PCLK>; - clock-names = "uartclk", "apb_pclk"; - }; diff --git a/Documentation/devicetree/bindings/clock/hi3670-clock.txt b/Documentation/devicetree/bindings/clock/hi3670-clock.txt deleted file mode 100644 index 66f3697eca78..000000000000 --- a/Documentation/devicetree/bindings/clock/hi3670-clock.txt +++ /dev/null @@ -1,43 +0,0 @@ -* Hisilicon Hi3670 Clock Controller - -The Hi3670 clock controller generates and supplies clock to various -controllers within the Hi3670 SoC. - -Required Properties: - -- compatible: the compatible should be one of the following strings to - indicate the clock controller functionality. - - - "hisilicon,hi3670-crgctrl" - - "hisilicon,hi3670-pctrl" - - "hisilicon,hi3670-pmuctrl" - - "hisilicon,hi3670-sctrl" - - "hisilicon,hi3670-iomcu" - - "hisilicon,hi3670-media1-crg" - - "hisilicon,hi3670-media2-crg" - -- reg: physical base address of the controller and length of memory mapped - region. - -- #clock-cells: should be 1. - -Each clock is assigned an identifier and client nodes use this identifier -to specify the clock which they consume. - -All these identifier could be found in . - -Examples: - crg_ctrl: clock-controller@fff35000 { - compatible = "hisilicon,hi3670-crgctrl", "syscon"; - reg = <0x0 0xfff35000 0x0 0x1000>; - #clock-cells = <1>; - }; - - uart0: serial@fdf02000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0 0xfdf02000 0x0 0x1000>; - interrupts = ; - clocks = <&crg_ctrl HI3670_CLK_GATE_UART0>, - <&crg_ctrl HI3670_PCLK>; - clock-names = "uartclk", "apb_pclk"; - }; diff --git a/Documentation/devicetree/bindings/clock/hi6220-clock.txt b/Documentation/devicetree/bindings/clock/hi6220-clock.txt deleted file mode 100644 index 17ac4a3dd26a..000000000000 --- a/Documentation/devicetree/bindings/clock/hi6220-clock.txt +++ /dev/null @@ -1,52 +0,0 @@ -* Hisilicon Hi6220 Clock Controller - -Clock control registers reside in different Hi6220 system controllers, -please refer the following document to know more about the binding rules -for these system controllers: - -Documentation/devicetree/bindings/arm/hisilicon/hisilicon.yaml - -Required Properties: - -- compatible: the compatible should be one of the following strings to - indicate the clock controller functionality. - - - "hisilicon,hi6220-acpu-sctrl" - - "hisilicon,hi6220-aoctrl" - - "hisilicon,hi6220-sysctrl" - - "hisilicon,hi6220-mediactrl" - - "hisilicon,hi6220-pmctrl" - - "hisilicon,hi6220-stub-clk" - -- reg: physical base address of the controller and length of memory mapped - region. - -- #clock-cells: should be 1. - -Optional Properties: - -- hisilicon,hi6220-clk-sram: phandle to the syscon managing the SoC internal sram; - the driver need use the sram to pass parameters for frequency change. - -- mboxes: use the label reference for the mailbox as the first parameter, the - second parameter is the channel number. - -Example 1: - sys_ctrl: sys_ctrl@f7030000 { - compatible = "hisilicon,hi6220-sysctrl", "syscon"; - reg = <0x0 0xf7030000 0x0 0x2000>; - #clock-cells = <1>; - }; - -Example 2: - stub_clock: stub_clock { - compatible = "hisilicon,hi6220-stub-clk"; - hisilicon,hi6220-clk-sram = <&sram>; - #clock-cells = <1>; - mboxes = <&mailbox 1>; - }; - -Each clock is assigned an identifier and client nodes use this identifier -to specify the clock which they consume. - -All these identifier could be found in . diff --git a/Documentation/devicetree/bindings/clock/hisilicon,clocks.yaml b/Documentation/devicetree/bindings/clock/hisilicon,clocks.yaml new file mode 100644 index 000000000000..345c6d0e7a13 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/hisilicon,clocks.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/hisilicon,clocks.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Hisilicon Hi6220/Hi3660/Hi3670 Clock Controllers + +maintainers: + - Wei Xu + +description: > + The Hi3670 clock controller generates and supplies clock to various + controllers within the Hi3670 SoC. + + All these identifiers can be found in: + dt-bindings/clock/hi3660-clock.h. + dt-bindings/clock/hi3670-clock.h. + dt-bindings/clock/hi6220-clock.h. + +properties: + compatible: + items: + - enum: + - hisilicon,hi3660-crgctrl + - hisilicon,hi3660-pctrl + - hisilicon,hi3660-pmuctrl + - hisilicon,hi3660-sctrl + - hisilicon,hi3660-iomcu + - hisilicon,hi3670-crgctrl + - hisilicon,hi3670-pctrl + - hisilicon,hi3670-pmuctrl + - hisilicon,hi3670-sctrl + - hisilicon,hi3670-iomcu + - hisilicon,hi3670-media1-crg + - hisilicon,hi3670-media2-crg + - hisilicon,hi6220-acpu-sctrl + - const: syscon + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + +required: + - compatible + - reg + - '#clock-cells' + +additionalProperties: false diff --git a/Documentation/devicetree/bindings/clock/hisilicon,hi6220-stub-clk.yaml b/Documentation/devicetree/bindings/clock/hisilicon,hi6220-stub-clk.yaml new file mode 100644 index 000000000000..4dd6a01bfd9d --- /dev/null +++ b/Documentation/devicetree/bindings/clock/hisilicon,hi6220-stub-clk.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/hisilicon,hi6220-stub-clk.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Hisilicon Stub Clock Controller + +maintainers: + - Wei Xu + +description: > + Each clock is assigned an identifier and client nodes use this identifier + to specify the clock which they consume. + + All these identifiers can be found in: + dt-bindings/clock/hi3660-clock.h. + dt-bindings/clock/hi6220-clock.h. + +properties: + compatible: + enum: + - hisilicon,hi3660-stub-clk + - hisilicon,hi6220-stub-clk + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + + hisilicon,hi6220-clk-sram: + description: + syscon managing the SoC internal SRAM; driver needs the SRAM to pass + parameters for frequency change. + $ref: /schemas/types.yaml#/definitions/phandle + + mboxes: + maxItems: 1 + + mbox-names: + const: mbox-tx + +required: + - compatible + - '#clock-cells' + - mboxes + +additionalProperties: false diff --git a/Documentation/devicetree/bindings/clock/nuvoton,ma35d1-clk.yaml b/Documentation/devicetree/bindings/clock/nuvoton,ma35d1-clk.yaml index 8f0c43683729..9649feda8d7a 100644 --- a/Documentation/devicetree/bindings/clock/nuvoton,ma35d1-clk.yaml +++ b/Documentation/devicetree/bindings/clock/nuvoton,ma35d1-clk.yaml @@ -29,7 +29,18 @@ properties: const: 1 clocks: - maxItems: 1 + minItems: 1 + maxItems: 2 + description: + The controller takes 2 crystal oscillator inputs from the board. + HXT is a 24 MHz crystal feeding the internal PLLs. LXT is a 32.768 + kHz crystal, for RTC and low power operations. + + clock-names: + minItems: 1 + items: + - const: hxt + - const: lxt nuvoton,pll-mode: description: @@ -58,6 +69,7 @@ examples: compatible = "nuvoton,ma35d1-clk"; reg = <0x40460200 0x100>; #clock-cells = <1>; - clocks = <&clk_hxt>; + clocks = <&clk_hxt>, <&clk_lxt>; + clock-names = "hxt", "lxt"; }; ... diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8952.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8952.yaml new file mode 100644 index 000000000000..035f2f7451cd --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8952.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,gcc-msm8952.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Global Clock & Reset Controller on MSM8952 + +maintainers: + - Muzaffer Kadir + +description: | + Qualcomm global clock control module provides the clocks, resets and power + domains on MSM8952. + + See also: + include/dt-bindings/clock/qcom,gcc-msm8952.h + +properties: + compatible: + enum: + - qcom,gcc-msm8952 + + clocks: + items: + - description: XO source + - description: Always-on XO source + - description: DSI phy instance 0 dsi clock + - description: DSI phy instance 0 byte clock + + power-domains: + items: + - description: CX power domain + +required: + - compatible + - clocks + - power-domains + - '#power-domain-cells' + +allOf: + - $ref: qcom,gcc.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + #include + + clock-controller@1800000 { + compatible = "qcom,gcc-msm8952"; + reg = <0x01800000 0x80000>; + clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, + <&rpmcc RPM_SMD_XO_A_CLK_SRC>, + <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>, + <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>; + power-domains = <&rpmpd RPMPD_VDDCX>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; +... diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sdm845.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sdm845.yaml index a7523a414341..41767eb11651 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc-sdm845.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sdm845.yaml @@ -31,11 +31,13 @@ properties: maxItems: 5 power-domains: - maxItems: 1 + items: + - description: CX power domain required: - compatible - '#power-domain-cells' + - power-domains allOf: - $ref: qcom,gcc.yaml# @@ -85,6 +87,7 @@ examples: # Example for GCC for SDM845: - | #include + #include clock-controller@100000 { compatible = "qcom,gcc-sdm845"; reg = <0x100000 0x1f0000>; @@ -94,6 +97,7 @@ examples: <&pcie0_lane>, <&pcie1_lane>; clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", "pcie_0_pipe_clk", "pcie_1_pipe_clk"; + power-domains = <&rpmhpd SDM845_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sm6350.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sm6350.yaml index 819e855eaf9a..098a108b8123 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc-sm6350.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sm6350.yaml @@ -31,10 +31,15 @@ properties: - const: bi_tcxo_ao - const: sleep_clk + power-domains: + items: + - description: CX power domain + required: - compatible - clocks - clock-names + - power-domains - '#power-domain-cells' allOf: @@ -45,12 +50,14 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,gcc-sm6350"; reg = <0x00100000 0x1f0000>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>; + power-domains = <&rpmhpd RPMHPD_CX>; clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk"; #clock-cells = <1>; #reset-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sm8150.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sm8150.yaml index 5f3f69fe9ddb..82d67b0d82d0 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc-sm8150.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sm8150.yaml @@ -30,10 +30,15 @@ properties: - const: bi_tcxo - const: sleep_clk + power-domains: + items: + - description: CX power domain + required: - compatible - clocks - clock-names + - power-domains - '#power-domain-cells' allOf: @@ -44,12 +49,14 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,gcc-sm8150"; reg = <0x00100000 0x1f0000>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>; clock-names = "bi_tcxo", "sleep_clk"; + power-domains = <&rpmhpd SM8150_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sm8250.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sm8250.yaml index f4cd5a509c60..5f9aae728245 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc-sm8250.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sm8250.yaml @@ -32,10 +32,15 @@ properties: - const: bi_tcxo_ao - const: sleep_clk + power-domains: + items: + - description: CX power domain + required: - compatible - clocks - clock-names + - power-domains - '#power-domain-cells' allOf: @@ -46,6 +51,7 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,gcc-sm8250"; reg = <0x00100000 0x1f0000>; @@ -53,6 +59,7 @@ examples: <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>; clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk"; + power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sm8350.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sm8350.yaml index 97ffae3b5522..7f3947db5807 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc-sm8350.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sm8350.yaml @@ -51,10 +51,15 @@ properties: - const: usb3_uni_phy_sec_gcc_usb30_pipe_clk # Optional clock minItems: 2 + power-domains: + items: + - description: CX power domain + required: - compatible - clocks - clock-names + - power-domains - '#power-domain-cells' allOf: @@ -65,12 +70,14 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,gcc-sm8350"; reg = <0x00100000 0x1f0000>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>; clock-names = "bi_tcxo", "sleep_clk"; + power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sm8450.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sm8450.yaml index 3169ac05e1d8..793ee9e3ff10 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc-sm8450.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sm8450.yaml @@ -47,10 +47,15 @@ properties: - const: usb3_phy_wrapper_gcc_usb30_pipe_clk # Optional clock minItems: 2 + power-domains: + items: + - description: CX power domain + required: - compatible - clocks - clock-names + - power-domains - '#power-domain-cells' allOf: @@ -61,11 +66,13 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,gcc-sm8450"; reg = <0x00100000 0x001f4200>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>; clock-names = "bi_tcxo", "sleep_clk"; + power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml index a4f9af8fa187..91e17f126a9b 100644 --- a/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml @@ -25,6 +25,7 @@ properties: compatible: enum: - qcom,ipq5018-cmn-pll + - qcom,ipq5210-cmn-pll - qcom,ipq5332-cmn-pll - qcom,ipq5424-cmn-pll - qcom,ipq6018-cmn-pll diff --git a/Documentation/devicetree/bindings/clock/qcom,kuno-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,kuno-gcc.yaml new file mode 100644 index 000000000000..7ae37033a1af --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,kuno-gcc.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,kuno-gcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Global Clock & Reset Controller on Kuno + +maintainers: + - Hardeep Sharma + +description: | + Qualcomm global clock control module provides the clocks and resets on Kuno. + + See also: include/dt-bindings/clock/qcom,kuno-gcc.h + +properties: + compatible: + const: qcom,kuno-gcc + + clocks: + items: + - description: Board XO source + - description: Board active-only XO source + - description: Sleep clock source + - description: PCIe pipe clock source + +required: + - compatible + - clocks + - '#power-domain-cells' + +allOf: + - $ref: qcom,gcc.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + clock-controller@80000 { + compatible = "qcom,kuno-gcc"; + reg = <0x00080000 0x1f4200>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&rpmhcc RPMH_CXO_CLK_A>, + <&sleep_clk>, + <&pcie_pipe_clk>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; +... diff --git a/Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml index 4a828e102d25..c87248531563 100644 --- a/Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml @@ -31,10 +31,15 @@ properties: - const: bi_tcxo_ao - const: sleep_clk + power-domains: + items: + - description: CX power domain + required: - compatible - clocks - clock-names + - power-domains - '#power-domain-cells' allOf: @@ -45,6 +50,7 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,qcs615-gcc"; reg = <0x00100000 0x1f0000>; @@ -52,6 +58,7 @@ examples: <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>; clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk"; + power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,qcs8300-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,qcs8300-gcc.yaml index 081bc452081f..a2f6e97f1848 100644 --- a/Documentation/devicetree/bindings/clock/qcom,qcs8300-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,qcs8300-gcc.yaml @@ -33,9 +33,14 @@ properties: - description: UFS Phy Tx symbol 0 clock source - description: USB3 Phy wrapper pipe clock source + power-domains: + items: + - description: CX power domain + required: - compatible - clocks + - power-domains - '#power-domain-cells' allOf: @@ -46,6 +51,7 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,qcs8300-gcc"; reg = <0x00100000 0xc7018>; @@ -59,6 +65,7 @@ examples: <&ufs_phy_rx_symbol_1_clk>, <&ufs_phy_tx_symbol_0_clk>, <&usb3_phy_wrapper_gcc_usb30_prim_pipe_clk>; + power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml index 17332aa55886..aa532f208f5a 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml @@ -56,6 +56,11 @@ properties: - qcom,rpmcc-shikra - const: qcom,rpmcc-qcm2290 - const: qcom,rpmcc + - items: + - enum: + - qcom,rpmcc-msm8952 + - const: qcom,rpmcc-msm8976 + - const: qcom,rpmcc '#clock-cells': const: 1 diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml index 2b446aca5207..5c9b653bc2aa 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml @@ -22,6 +22,7 @@ properties: - qcom,glymur-rpmh-clk - qcom,hawi-rpmh-clk - qcom,kaanapali-rpmh-clk + - qcom,kuno-rpmh-clk - qcom,milos-rpmh-clk - qcom,nord-rpmh-clk - qcom,qcs615-rpmh-clk @@ -39,6 +40,7 @@ properties: - qcom,sdx75-rpmh-clk - qcom,sm4450-rpmh-clk - qcom,sm6350-rpmh-clk + - qcom,sm7250-rpmh-clk - qcom,sm8150-rpmh-clk - qcom,sm8250-rpmh-clk - qcom,sm8350-rpmh-clk diff --git a/Documentation/devicetree/bindings/clock/qcom,sdx75-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sdx75-gcc.yaml index 29a0b29bcb81..75a38e9f3248 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sdx75-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sdx75-gcc.yaml @@ -38,9 +38,14 @@ properties: - description: PCIE Pipe clock source - description: USB3 phy wrapper pipe clock source + power-domains: + items: + - description: CX power domain + required: - compatible - clocks + - power-domains - '#power-domain-cells' allOf: @@ -51,6 +56,7 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@80000 { compatible = "qcom,sdx75-gcc"; reg = <0x80000 0x1f7400>; @@ -59,6 +65,7 @@ examples: <&emac1_sgmiiphy_mac_rclk>, <&emac1_sgmiiphy_mac_tclk>, <&emac1_sgmiiphy_rclk>, <&emac1_sgmiiphy_tclk>, <&pcie20_phy_aux_clk>, <&pcie_1_pipe_clk>, <&pcie_2_pipe_clk>, <&pcie_pipe_clk>, <&usb3_phy_wrapper_gcc_usb30_pipe_clk>; + power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,sm4450-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm4450-gcc.yaml index 9cfe859bacc9..e143300e7be9 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm4450-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm4450-gcc.yaml @@ -29,9 +29,14 @@ properties: - description: UFS Phy Tx symbol 0 clock source - description: USB3 Phy wrapper pipe clock source + power-domains: + items: + - description: CX power domain + required: - compatible - clocks + - power-domains - '#power-domain-cells' allOf: @@ -42,12 +47,14 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,sm4450-gcc"; reg = <0x00100000 0x001f4200>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>, <&ufs_mem_phy 0>, <&ufs_mem_phy 1>, <&ufs_mem_phy 2>, <&usb_1_qmpphy>; + power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,sm6375-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm6375-gcc.yaml index 66dfa72fa975..b4ad2ad14d85 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm6375-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm6375-gcc.yaml @@ -4,10 +4,13 @@ $id: http://devicetree.org/schemas/clock/qcom,sm6375-gcc.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Qualcomm Global Clock & Reset Controller on SM6375 +title: Qualcomm Global Clock & Reset Controller on SM6375 and SM7150 maintainers: - Konrad Dybcio + - Bjorn Andersson + - Danila Tikhonov + - David Wronek description: | Qualcomm global clock control module provides the clocks, resets and power @@ -20,7 +23,9 @@ allOf: properties: compatible: - const: qcom,sm6375-gcc + enum: + - qcom,sm6375-gcc + - qcom,sm7150-gcc clocks: items: diff --git a/Documentation/devicetree/bindings/clock/qcom,sm7150-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm7150-gcc.yaml deleted file mode 100644 index 3878808f811e..000000000000 --- a/Documentation/devicetree/bindings/clock/qcom,sm7150-gcc.yaml +++ /dev/null @@ -1,53 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/clock/qcom,sm7150-gcc.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Qualcomm Global Clock & Reset Controller on SM7150 - -maintainers: - - Bjorn Andersson - - Danila Tikhonov - - David Wronek - -description: | - Qualcomm global clock control module provides the clocks, resets and power - domains on SM7150 - - See also: include/dt-bindings/clock/qcom,sm7150-gcc.h - -properties: - compatible: - const: qcom,sm7150-gcc - - clocks: - items: - - description: Board XO source - - description: Board XO Active-Only source - - description: Sleep clock source - -required: - - compatible - - clocks - - '#power-domain-cells' - -allOf: - - $ref: qcom,gcc.yaml# - -unevaluatedProperties: false - -examples: - - | - #include - clock-controller@100000 { - compatible = "qcom,sm7150-gcc"; - reg = <0x00100000 0x001f0000>; - clocks = <&rpmhcc RPMH_CXO_CLK>, - <&rpmhcc RPMH_CXO_CLK_A>, - <&sleep_clk>; - #clock-cells = <1>; - #reset-cells = <1>; - #power-domain-cells = <1>; - }; -... diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-gcc.yaml index c4e9b9bb63f5..f9423aff5dea 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8550-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-gcc.yaml @@ -31,9 +31,14 @@ properties: - description: UFS Phy Tx symbol 0 clock source - description: USB3 Phy wrapper pipe clock source + power-domains: + items: + - description: CX power domain + required: - compatible - clocks + - power-domains - '#power-domain-cells' allOf: @@ -44,6 +49,7 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,sm8550-gcc"; reg = <0x00100000 0x001f4200>; @@ -55,6 +61,7 @@ examples: <&ufs_mem_phy 1>, <&ufs_mem_phy 2>, <&usb_1_qmpphy>; + power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml index 1f3332275c17..f199655790da 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml @@ -36,7 +36,6 @@ properties: - qcom,sm8550-tcsr - qcom,sm8650-tcsr - qcom,sm8750-tcsr - - qcom,x1e80100-tcsr - const: syscon - items: - enum: diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8650-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8650-gcc.yaml index c7143e2abc80..543105b277d5 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8650-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8650-gcc.yaml @@ -32,9 +32,14 @@ properties: - description: UFS Phy Tx symbol 0 clock source - description: USB3 Phy wrapper pipe clock source + power-domains: + items: + - description: CX power domain + required: - compatible - clocks + - power-domains - '#power-domain-cells' allOf: @@ -45,6 +50,7 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,sm8650-gcc"; reg = <0x00100000 0x001f4200>; @@ -58,6 +64,7 @@ examples: <&ufs_mem_phy 1>, <&ufs_mem_phy 2>, <&usb_1_qmpphy>; + power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml index 0114d347b26f..59da3eb2b073 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml @@ -34,9 +34,14 @@ properties: - description: UFS Phy Tx symbol 0 clock source - description: USB3 Phy wrapper pipe clock source + power-domains: + items: + - description: CX power domain + required: - compatible - clocks + - power-domains - '#power-domain-cells' allOf: @@ -47,6 +52,7 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@100000 { compatible = "qcom,sm8750-gcc"; reg = <0x00100000 0x001f4200>; @@ -58,6 +64,7 @@ examples: <&ufs_mem_phy 1>, <&ufs_mem_phy 2>, <&usb_1_qmpphy>; + power-domains = <&rpmhpd RPMHPD_CX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/qcom,x1e80100-tcsr.yaml b/Documentation/devicetree/bindings/clock/qcom,x1e80100-tcsr.yaml new file mode 100644 index 000000000000..8163c679fc54 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,x1e80100-tcsr.yaml @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,x1e80100-tcsr.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm TCSR Clock Controller on X1E80100 + +maintainers: + - Bjorn Andersson + - Taniya Das + +description: | + Qualcomm TCSR clock control module provides the clocks on X1E80100 + + See also: + - include/dt-bindings/clock/qcom,x1e80100-tcsr.h + +properties: + compatible: + items: + - enum: + - qcom,x1e80100-tcsr + - const: syscon + + clocks: + items: + - description: TCXO pad clock + + reg: + maxItems: 1 + + '#clock-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-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-qreftx0-0p9-supply: true + vdda-qreftx0-1p2-supply: true + vdda-qreftx1-0p9-supply: true + vdda-qreftx1-1p2-supply: true + vdda-refgen0-0p9-supply: true + vdda-refgen0-1p2-supply: true + vdda-refgen2-0p9-supply: true + vdda-refgen2-1p2-supply: true + +required: + - compatible + - clocks + - '#clock-cells' + - 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-qrefrx3-0p9-supply + - vdda-qrefrx4-0p9-supply + - vdda-qreftx0-0p9-supply + - vdda-qreftx0-1p2-supply + - vdda-qreftx1-0p9-supply + - vdda-qreftx1-1p2-supply + - vdda-refgen0-0p9-supply + - vdda-refgen0-1p2-supply + - vdda-refgen2-0p9-supply + - vdda-refgen2-1p2-supply + +additionalProperties: false + +examples: + - | + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@1fc0000 { + compatible = "qcom,x1e80100-tcsr", "syscon"; + reg = <0x0 0x1fc0000 0x0 0x30000>; + clocks = <&rpmhcc RPMH_CXO_CLK>; + #clock-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-qrefrx3-0p9-supply = <&vreg_l1a>; + vdda-qrefrx4-0p9-supply = <&vreg_l1a>; + vdda-qreftx0-0p9-supply = <&vreg_l1a>; + vdda-qreftx0-1p2-supply = <&vreg_l2a>; + vdda-qreftx1-0p9-supply = <&vreg_l1a>; + vdda-qreftx1-1p2-supply = <&vreg_l2a>; + vdda-refgen0-0p9-supply = <&vreg_l1a>; + vdda-refgen0-1p2-supply = <&vreg_l2a>; + vdda-refgen2-0p9-supply = <&vreg_l1a>; + vdda-refgen2-1p2-supply = <&vreg_l2a>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos5515-cmu.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos5515-cmu.yaml new file mode 100644 index 000000000000..1be8962cda1c --- /dev/null +++ b/Documentation/devicetree/bindings/clock/samsung,exynos5515-cmu.yaml @@ -0,0 +1,145 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/samsung,exynos5515-cmu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung Exynos5515 SoC clock controller + +maintainers: + - Aiden Isik + - Chanwoo Choi + - Krzysztof Kozlowski + +description: | + Exynos5515 clock controller is comprised of several CMU units, generating + clocks for different domains. Those CMU units are modeled as separate device + tree nodes, and might depend on each other. The root clock in that root tree + is an external clock: OSCCLK (26 MHz). This external clock must be defined + as a fixed-rate clock in dts. + + CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and + dividers; all other clocks of function blocks (other CMUs) are usually + derived from CMU_TOP. + + Each clock is assigned an identifier and client nodes can use this identifier + to specify the clock which they consume. All clocks available for usage + in clock consumer nodes are defined as preprocessor macros in + 'include/dt-bindings/clock/samsung,exynos5515-cmu.h' header. + +properties: + compatible: + enum: + - samsung,exynos5515-cmu-fsys + - samsung,exynos5515-cmu-peri + - samsung,exynos5515-cmu-top + + clocks: + minItems: 1 + maxItems: 5 + + clock-names: + minItems: 1 + maxItems: 5 + + "#clock-cells": + const: 1 + + reg: + maxItems: 1 + + samsung,sysreg: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to system registers interface. + +required: + - compatible + - clocks + - clock-names + - "#clock-cells" + - reg + - samsung,sysreg + +allOf: + - if: + properties: + compatible: + contains: + enum: + - samsung,exynos5515-cmu-fsys + + then: + properties: + clocks: + items: + - description: External reference clock (26MHz) + - description: CMU_FSYS BUS clock (from CMU_TOP) + - description: CMU_FSYS MMC card clock (from CMU_TOP) + - description: CMU_FSYS MMC embedded clock (from CMU_TOP) + - description: CMU_FSYS USB20DRD clock (from CMU_TOP) + + clock-names: + items: + - const: oscclk + - const: bus + - const: mmc_card + - const: mmc_embd + - const: usb20drd + + - if: + properties: + compatible: + contains: + enum: + - samsung,exynos5515-cmu-peri + + then: + properties: + clocks: + items: + - description: External reference clock (26MHz) + - description: CMU_PERI BUS clock (from CMU_TOP) + - description: CMU_PERI IP clock (from CMU_TOP) + - description: CMU_PERI UART clock (from CMU_TOP) + + clock-names: + items: + - const: oscclk + - const: bus + - const: ip + - const: uart + + - if: + properties: + compatible: + contains: + const: samsung,exynos5515-cmu-top + + then: + properties: + clocks: + items: + - description: External reference clock (26 MHz) + + clock-names: + items: + - const: oscclk + +additionalProperties: false + +examples: + - | + #include + + cmu_top: clock-controller@15410000 { + compatible = "samsung,exynos5515-cmu-top"; + reg = <0x15410000 0x10000>; + #clock-cells = <1>; + + clocks = <&oscclk>; + clock-names = "oscclk"; + samsung,sysreg = <&sysreg_top>; + }; + +... diff --git a/Documentation/devicetree/bindings/clock/ti,palmas-clk32kg.yaml b/Documentation/devicetree/bindings/clock/ti,palmas-clk32kg.yaml new file mode 100644 index 000000000000..c2a49be9b95a --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti,palmas-clk32kg.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ti,palmas-clk32kg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments Palmas 32KHz Clocks + +maintainers: + - Eduard Bostina + +description: + The Palmas device family has two clock output pins for 32KHz, + KG and KG_AUDIO. + +allOf: + - $ref: /schemas/clock/clock.yaml# + +properties: + compatible: + enum: + - ti,palmas-clk32kg + - ti,palmas-clk32kgaudio + + "#clock-cells": + const: 0 + + ti,external-sleep-control: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1, 2, 3 ] + description: | + The external enable input pins control the enable/disable of clocks. + The valid values (defined in dt-bindings/mfd/palmas.h) are: + 1: PALMAS_EXT_CONTROL_PIN_ENABLE1 + 2: PALMAS_EXT_CONTROL_PIN_ENABLE2 + 3: PALMAS_EXT_CONTROL_PIN_NSLEEP + Option 0 or missing this property means the clock is enabled/disabled + via register access and these pins do not have any control. + +required: + - compatible + - "#clock-cells" + +unevaluatedProperties: false + +examples: + - | + #include + + pmic { + clock-controller { + compatible = "ti,palmas-clk32kg"; + #clock-cells = <0>; + ti,external-sleep-control = ; + }; + }; diff --git a/Documentation/devicetree/bindings/clock/ti/adpll.txt b/Documentation/devicetree/bindings/clock/ti/adpll.txt deleted file mode 100644 index 3122360adcf3..000000000000 --- a/Documentation/devicetree/bindings/clock/ti/adpll.txt +++ /dev/null @@ -1,39 +0,0 @@ -Binding for Texas Instruments ADPLL clock. - -This binding uses the common clock binding[1]. It assumes a -register-mapped ADPLL with two to three selectable input clocks -and three to four children. - -[1] Documentation/devicetree/bindings/clock/clock-bindings.txt - -Required properties: -- compatible : shall be one of "ti,dm814-adpll-s-clock" or - "ti,dm814-adpll-lj-clock" depending on the type of the ADPLL -- #clock-cells : from common clock binding; shall be set to 1. -- clocks : link phandles of parent clocks clkinp and clkinpulow, note - that the adpll-s-clock also has an optional clkinphif -- reg : address and length of the register set for controlling the ADPLL. - -Examples: - adpll_mpu_ck: adpll@40 { - #clock-cells = <1>; - compatible = "ti,dm814-adpll-s-clock"; - reg = <0x40 0x40>; - clocks = <&devosc_ck &devosc_ck &devosc_ck>; - clock-names = "clkinp", "clkinpulow", "clkinphif"; - clock-output-names = "481c5040.adpll.dcoclkldo", - "481c5040.adpll.clkout", - "481c5040.adpll.clkoutx2", - "481c5040.adpll.clkouthif"; - }; - - adpll_dsp_ck: adpll@80 { - #clock-cells = <1>; - compatible = "ti,dm814-adpll-lj-clock"; - reg = <0x80 0x30>; - clocks = <&devosc_ck &devosc_ck>; - clock-names = "clkinp", "clkinpulow"; - clock-output-names = "481c5080.adpll.dcoclkldo", - "481c5080.adpll.clkout", - "481c5080.adpll.clkoutldo"; - }; diff --git a/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt deleted file mode 100644 index c9894538315b..000000000000 --- a/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt +++ /dev/null @@ -1,96 +0,0 @@ -Binding for TI DaVinci PLL Controllers - -The PLL provides clocks to most of the components on the SoC. In addition -to the PLL itself, this controller also contains bypasses, gates, dividers, -an multiplexers for various clock signals. - -Required properties: -- compatible: shall be one of: - - "ti,da850-pll0" for PLL0 on DA850/OMAP-L138/AM18XX - - "ti,da850-pll1" for PLL1 on DA850/OMAP-L138/AM18XX -- reg: physical base address and size of the controller's register area. -- clocks: phandles corresponding to the clock names -- clock-names: names of the clock sources - depends on compatible string - - for "ti,da850-pll0", shall be "clksrc", "extclksrc" - - for "ti,da850-pll1", shall be "clksrc" - -Optional properties: -- ti,clkmode-square-wave: Indicates that the board is supplying a square - wave input on the OSCIN pin instead of using a crystal oscillator. - This property is only valid when compatible = "ti,da850-pll0". - - -Optional child nodes: - -pllout - Describes the main PLL clock output (before POSTDIV). The node name must - be "pllout". - - Required properties: - - #clock-cells: shall be 0 - -sysclk - Describes the PLLDIVn divider clocks that provide the SYSCLKn clock - domains. The node name must be "sysclk". Consumers of this node should - use "n" in "SYSCLKn" as the index parameter for the clock cell. - - Required properties: - - #clock-cells: shall be 1 - -auxclk - Describes the AUXCLK output of the PLL. The node name must be "auxclk". - This child node is only valid when compatible = "ti,da850-pll0". - - Required properties: - - #clock-cells: shall be 0 - -obsclk - Describes the OBSCLK output of the PLL. The node name must be "obsclk". - - Required properties: - - #clock-cells: shall be 0 - - -Examples: - - pll0: clock-controller@11000 { - compatible = "ti,da850-pll0"; - reg = <0x11000 0x1000>; - clocks = <&ref_clk>, <&pll1_sysclk 3>; - clock-names = "clksrc", "extclksrc"; - ti,clkmode-square-wave; - - pll0_pllout: pllout { - #clock-cells = <0>; - }; - - pll0_sysclk: sysclk { - #clock-cells = <1>; - }; - - pll0_auxclk: auxclk { - #clock-cells = <0>; - }; - - pll0_obsclk: obsclk { - #clock-cells = <0>; - }; - }; - - pll1: clock-controller@21a000 { - compatible = "ti,da850-pll1"; - reg = <0x21a000 0x1000>; - clocks = <&ref_clk>; - clock-names = "clksrc"; - - pll0_sysclk: sysclk { - #clock-cells = <1>; - }; - - pll0_obsclk: obsclk { - #clock-cells = <0>; - }; - }; - -Also see: -- Documentation/devicetree/bindings/clock/clock-bindings.txt diff --git a/Documentation/devicetree/bindings/clock/ti/davinci/ti,da850-pll.yaml b/Documentation/devicetree/bindings/clock/ti/davinci/ti,da850-pll.yaml new file mode 100644 index 000000000000..c6563290a702 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti/davinci/ti,da850-pll.yaml @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ti/davinci/ti,da850-pll.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI DaVinci PLL Controllers + +maintainers: + - David Lechner + +description: + The PLL provides clocks to most of the components on the SoC. In addition to + the PLL itself, this controller also contains bypasses, gates, dividers, an + multiplexers for various clock signals. + +properties: + compatible: + enum: + - ti,da850-pll0 + - ti,da850-pll1 + + reg: + maxItems: 1 + + clocks: + minItems: 1 + items: + - description: Primary reference clock input + - description: External clock source + + clock-names: + minItems: 1 + items: + - const: clksrc + - const: extclksrc + + ti,clkmode-square-wave: + type: boolean + description: + Indicates that the board is supplying a square wave input on the OSCIN + pin instead of using a crystal oscillator. + + pllout: + type: object + description: + Main PLL clock output before POSTDIV. + + properties: + '#clock-cells': + const: 0 + + required: + - '#clock-cells' + + additionalProperties: false + + sysclk: + type: object + description: + PLLDIVn divider clocks that provide the SYSCLKn clock domains. Consumers + of this node should use "n" in "SYSCLKn" as the index parameter for the + clock cell. + + properties: + '#clock-cells': + const: 1 + + required: + - '#clock-cells' + + additionalProperties: false + + auxclk: + type: object + description: + AUXCLK output of the PLL + + properties: + '#clock-cells': + const: 0 + + required: + - '#clock-cells' + + additionalProperties: false + + obsclk: + type: object + description: + the OBSCLK output of the PLL. + + properties: + '#clock-cells': + const: 0 + + required: + - '#clock-cells' + + additionalProperties: false + +required: + - compatible + - reg + - clocks + - clock-names + +additionalProperties: false + +allOf: + - if: + properties: + compatible: + const: ti,da850-pll1 + then: + properties: + clocks: + maxItems: 1 + clock-names: + maxItems: 1 + ti,clkmode-square-wave: false + auxclk: false + +examples: + - | + clock-controller@11000 { + compatible = "ti,da850-pll0"; + reg = <0x11000 0x1000>; + clocks = <&ref_clk>, <&pll1_sysclk 3>; + clock-names = "clksrc", "extclksrc"; + ti,clkmode-square-wave; + + pllout { + #clock-cells = <0>; + }; + + sysclk { + #clock-cells = <1>; + }; + + auxclk { + #clock-cells = <0>; + }; + + obsclk { + #clock-cells = <0>; + }; + }; + + - | + clock-controller@21a000 { + compatible = "ti,da850-pll1"; + reg = <0x21a000 0x1000>; + clocks = <&ref_clk>; + clock-names = "clksrc"; + + sysclk { + #clock-cells = <1>; + }; + + obsclk { + #clock-cells = <0>; + }; + }; diff --git a/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt b/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt deleted file mode 100644 index 68504079f99f..000000000000 --- a/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt +++ /dev/null @@ -1,94 +0,0 @@ -Device Tree Clock bindings for ATL (Audio Tracking Logic) of DRA7 SoC. - -The ATL IP is used to generate clock to be used to synchronize baseband and -audio codec. A single ATL IP provides four ATL clock instances sharing the same -functional clock but can be configured to provide different clocks. -ATL can maintain a clock averages to some desired frequency based on the bws/aws -signals - can compensate the drift between the two ws signal. - -In order to provide the support for ATL and its output clocks (which can be used -internally within the SoC or external components) two sets of bindings is needed: - -Clock tree binding: -This binding uses the common clock binding[1]. -To be able to integrate the ATL clocks with DT clock tree. -Provides ccf level representation of the ATL clocks to be used by drivers. -Since the clock instances are part of a single IP this binding is used as a node -for the DT clock tree, the IP driver is needed to handle the actual configuration -of the IP. - -[1] Documentation/devicetree/bindings/clock/clock-bindings.txt - -Required properties: -- compatible : shall be "ti,dra7-atl-clock" -- #clock-cells : from common clock binding; shall be set to 0. -- clocks : link phandles to functional clock of ATL - -Binding for the IP driver: -This binding is used to configure the IP driver which is going to handle the -configuration of the IP for the ATL clock instances. - -Required properties: -- compatible : shall be "ti,dra7-atl" -- reg : base address for the ATL IP -- ti,provided-clocks : List of phandles to the clocks associated with the ATL -- clocks : link phandles to functional clock of ATL -- clock-names : Shall be set to "fck" -- ti,hwmods : Shall be set to "atl" - -Optional properties: -Configuration of ATL instances: -- atl{0/1/2/3} { - - bws : Baseband word select signal selection - - aws : Audio word select signal selection -}; - -For valid word select signals, see the dt-bindings/clock/ti-dra7-atl.h include -file. - -Examples: -/* clock bindings for atl provided clocks */ -atl_clkin0_ck: atl_clkin0_ck { - #clock-cells = <0>; - compatible = "ti,dra7-atl-clock"; - clocks = <&atl_gfclk_mux>; -}; - -atl_clkin1_ck: atl_clkin1_ck { - #clock-cells = <0>; - compatible = "ti,dra7-atl-clock"; - clocks = <&atl_gfclk_mux>; -}; - -atl_clkin2_ck: atl_clkin2_ck { - #clock-cells = <0>; - compatible = "ti,dra7-atl-clock"; - clocks = <&atl_gfclk_mux>; -}; - -atl_clkin3_ck: atl_clkin3_ck { - #clock-cells = <0>; - compatible = "ti,dra7-atl-clock"; - clocks = <&atl_gfclk_mux>; -}; - -/* binding for the IP */ -atl: atl@4843c000 { - compatible = "ti,dra7-atl"; - reg = <0x4843c000 0x3ff>; - ti,hwmods = "atl"; - ti,provided-clocks = <&atl_clkin0_ck>, <&atl_clkin1_ck>, - <&atl_clkin2_ck>, <&atl_clkin3_ck>; - clocks = <&atl_gfclk_mux>; - clock-names = "fck"; -}; - -#include - -&atl { - - atl2 { - bws = ; - aws = ; - }; -}; diff --git a/Documentation/devicetree/bindings/clock/ti/fapll.txt b/Documentation/devicetree/bindings/clock/ti/fapll.txt deleted file mode 100644 index 88986ef39ddd..000000000000 --- a/Documentation/devicetree/bindings/clock/ti/fapll.txt +++ /dev/null @@ -1,31 +0,0 @@ -Binding for Texas Instruments FAPLL clock. - -This binding uses the common clock binding[1]. It assumes a -register-mapped FAPLL with usually two selectable input clocks -(reference clock and bypass clock), and one or more child -syntesizers. - -[1] Documentation/devicetree/bindings/clock/clock-bindings.txt - -Required properties: -- compatible : shall be "ti,dm816-fapll-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 FAPLL. - -Examples: - main_fapll: main_fapll { - #clock-cells = <1>; - compatible = "ti,dm816-fapll-clock"; - reg = <0x400 0x40>; - clocks = <&sys_clkin_ck &sys_clkin_ck>; - clock-indices = <1>, <2>, <3>, <4>, <5>, - <6>, <7>; - clock-output-names = "main_pll_clk1", - "main_pll_clk2", - "main_pll_clk3", - "main_pll_clk4", - "main_pll_clk5", - "main_pll_clk6", - "main_pll_clk7"; - }; diff --git a/Documentation/devicetree/bindings/clock/ti/ti,dm814-adpll-clock.yaml b/Documentation/devicetree/bindings/clock/ti/ti,dm814-adpll-clock.yaml new file mode 100644 index 000000000000..9676ab2d8705 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti/ti,dm814-adpll-clock.yaml @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ti/ti,dm814-adpll-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments DM814x ADPLL Clock + +maintainers: + - Tony Lindgren + +description: + The ADPLL is a register-mapped clock generator found on TI DM814x SoCs. It + provides multiple output clocks from two or three selectable input clocks and + three to four children. + +properties: + compatible: + enum: + - ti,dm814-adpll-s-clock + - ti,dm814-adpll-lj-clock + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + + clocks: + minItems: 2 + maxItems: 3 + + clock-names: + minItems: 2 + items: + - const: clkinp + - const: clkinpulow + - const: clkinphif + + clock-output-names: + minItems: 3 + maxItems: 4 + +required: + - compatible + - reg + - '#clock-cells' + - clocks + - clock-output-names + +if: + properties: + compatible: + contains: + const: ti,dm814-adpll-s-clock +then: + properties: + clocks: + minItems: 3 + clock-names: + minItems: 3 + clock-output-names: + minItems: 4 + +else: + properties: + clocks: + maxItems: 2 + clock-names: + maxItems: 2 + clock-output-names: + maxItems: 3 + +additionalProperties: false + +examples: + - | + adpll@40 { + compatible = "ti,dm814-adpll-s-clock"; + reg = <0x40 0x40>; + #clock-cells = <1>; + clocks = <&devosc_ck &devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow", "clkinphif"; + clock-output-names = "481c5040.adpll.dcoclkldo", + "481c5040.adpll.clkout", + "481c5040.adpll.clkoutx2", + "481c5040.adpll.clkouthif"; + }; diff --git a/Documentation/devicetree/bindings/clock/ti/ti,dm816-fapll-clock.yaml b/Documentation/devicetree/bindings/clock/ti/ti,dm816-fapll-clock.yaml new file mode 100644 index 000000000000..423b7405e398 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti/ti,dm816-fapll-clock.yaml @@ -0,0 +1,71 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ti/ti,dm816-fapll-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments FAPLL clock + +maintainers: + - Tony Lindgren + - Tero Kristo + +description: + FAPLL is register-mapped with usually two selectable input clocks + (reference clock and bypass clock), and one or more child synthesizers. + +properties: + compatible: + const: ti,dm816-fapll-clock + + "#clock-cells": + const: 1 + + reg: + maxItems: 1 + + clocks: + items: + - description: parent clock clk-ref + - description: parent clock clk-bypass + + clock-indices: + description: + Maps child synthesizers to physical indices 1-7. Index 0 is physically + reserved for the Master PLL. + minItems: 1 + maxItems: 7 + items: + minimum: 1 + maximum: 7 + + clock-output-names: + description: + Names of the child synthesizer outputs. The length of this array must + match clock-indices. + minItems: 1 + maxItems: 7 + +required: + - compatible + - reg + - clocks + - "#clock-cells" + - clock-indices + - clock-output-names + +additionalProperties: false + +examples: + - | + clock-controller@400 { + #clock-cells = <1>; + compatible = "ti,dm816-fapll-clock"; + reg = <0x400 0x40>; + clocks = <&sys_clkin_ck &sys_clkin_ck>; + clock-indices = <1>, <2>, <3>, <4>, <5>, <6>, <7>; + clock-output-names = "main_pll_clk1", "main_pll_clk2", "main_pll_clk3", + "main_pll_clk4", "main_pll_clk5", "main_pll_clk6", + "main_pll_clk7"; + + }; diff --git a/Documentation/devicetree/bindings/clock/ti/ti,dra7-atl-clock.yaml b/Documentation/devicetree/bindings/clock/ti/ti,dra7-atl-clock.yaml new file mode 100644 index 000000000000..c0795f4abcfa --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti/ti,dra7-atl-clock.yaml @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ti/ti,dra7-atl-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI DRA7 ATL (Audio Tracking Logic) clock output + +maintainers: + - Peter Ujfalusi + +properties: + compatible: + const: ti,dra7-atl-clock + + "#clock-cells": + const: 0 + + clocks: + maxItems: 1 + + clock-output-names: + maxItems: 1 + +required: + - compatible + - "#clock-cells" + - clocks + +additionalProperties: false + +examples: + - | + atl_clkin0_ck { + compatible = "ti,dra7-atl-clock"; + #clock-cells = <0>; + clocks = <&atl_gfclk_mux>; + }; diff --git a/Documentation/devicetree/bindings/clock/ti/ti,dra7-atl.yaml b/Documentation/devicetree/bindings/clock/ti/ti,dra7-atl.yaml new file mode 100644 index 000000000000..f4bb233be83d --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti/ti,dra7-atl.yaml @@ -0,0 +1,100 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ti/ti,dra7-atl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI DRA7 ATL (Audio Tracking Logic) Clock Controller + +maintainers: + - Peter Ujfalusi + +description: + The ATL IP is used to generate clock to be used to synchronize baseband and + audio codec. A single ATL IP provides four ATL clock instances sharing the + same functional clock but can be configured to provide different clocks. + ATL can maintain a clock averages to some desired frequency based on the + bws/aws signals - can compensate the drift between the two ws signal. + + See also Documentation/devicetree/bindings/clock/ti/ti,dra7-atl-clock.yaml + +properties: + compatible: + const: ti,dra7-atl + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: fck + + ti,provided-clocks: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: + List of phandles to the clocks associated with the ATL. + minItems: 4 + maxItems: 4 + items: + maxItems: 1 + + ti,hwmods: + $ref: /schemas/types.yaml#/definitions/string + description: + Name of the hwmod associated with the ATL. + deprecated: true + const: atl + +patternProperties: + "^atl[0-3]$": + type: object + additionalProperties: false + description: + Configuration of ATL instances. + + properties: + bws: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Baseband word select signal selection. + maximum: 15 + + aws: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Audio word select signal selection. + maximum: 15 + + required: + - bws + - aws + +required: + - compatible + - reg + - clocks + - clock-names + - ti,provided-clocks + +additionalProperties: false + +examples: + - | + #include + + atl@4843c000 { + compatible = "ti,dra7-atl"; + reg = <0x4843c000 0x3ff>; + clocks = <&atl_gfclk_mux>; + clock-names = "fck"; + ti,provided-clocks = <&atl_clkin0_ck>, <&atl_clkin1_ck>, + <&atl_clkin2_ck>, <&atl_clkin3_ck>; + + atl2 { + bws = ; + aws = ; + }; + }; diff --git a/Documentation/devicetree/bindings/clock/zte,zx297520v3-lspcrm.yaml b/Documentation/devicetree/bindings/clock/zte,zx297520v3-lspcrm.yaml new file mode 100644 index 000000000000..b0a176ffda12 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/zte,zx297520v3-lspcrm.yaml @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/zte,zx297520v3-lspcrm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ZTE zx297520v3 SoC LSP clock and reset controller + +maintainers: + - Stefan Dösinger + +description: | + This clock and reset controller controls low speed peripherals on the board. + This is a relatively isolated subsystem containing UART, I2C, I2S and SPI + devices. The controller is responsible for bringing the devices out of reset + and enabling their clocks as needed. + + The controller receives its clock signals from the matrix controller, and + these signals need to be declared as clock inputs. + + All available clocks are defined as preprocessor macros in the + "include/dt-bindings/clock/zte,zx297520v3-clk.h" header. Resets are defined in + the "include/dt-bindings/reset/zte,zx297520v3-reset.h" header. + +properties: + compatible: + const: zte,zx297520v3-lspcrm + + reg: + maxItems: 1 + + clocks: + items: + - description: Main PLL divided by 5 output from matrixcrm (124.8 MHz) + - description: Main PLL divided by 4 output from matrixcrm (156 MHz) + - description: Main PLL divided by 6 output from matrixcrm (104 MHz) + - description: Main PLL divided by 8 output from matrixcrm (78 MHz) + - description: Main PLL divided by 12 output from matrixcrm (52 MHz) + - description: Main oscillator output from matrixcrm (26 MHz) + - description: Timer oscillator output from matrixcrm (32 kHz) + - description: LSP pclk output from matrixcrm (26 MHz) + - description: TDM wclk mux output from matrixcrm + - description: DPLL divided by 4 output from matrixcrm (122.88 MHz) + + clock-names: + items: + - const: mpll-d5 + - const: mpll-d4 + - const: mpll-d6 + - const: mpll-d8 + - const: mpll-d12 + - const: osc26m + - const: osc32k + - const: pclk + - const: tdm-wclk + - const: dpll-d4 + + resets: + maxItems: 1 + + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - "#clock-cells" + - "#reset-cells" + +additionalProperties: false + +examples: + - | + #include + #include + + clock-controller@1400000 { + compatible = "zte,zx297520v3-lspcrm"; + reg = <0x01400000 0x100>; + #clock-cells = <1>; + clocks = <&matrixcrm ZX297520V3_LSP_MPLL_D5_WCLK>, + <&matrixcrm ZX297520V3_LSP_MPLL_D4_WCLK>, + <&matrixcrm ZX297520V3_LSP_MPLL_D6_WCLK>, + <&matrixcrm ZX297520V3_LSP_MPLL_D8_WCLK>, + <&matrixcrm ZX297520V3_LSP_MPLL_D12_WCLK>, + <&matrixcrm ZX297520V3_LSP_OSC26M_WCLK>, + <&matrixcrm ZX297520V3_LSP_OSC32K_WCLK>, + <&matrixcrm ZX297520V3_LSP_PCLK>, + <&matrixcrm ZX297520V3_LSP_TDM_WCLK>, + <&matrixcrm ZX297520V3_LSP_DPLL_D4_WCLK>; + clock-names = "mpll-d5", "mpll-d4", "mpll-d6", "mpll-d8", "mpll-d12", + "osc26m", "osc32k", "pclk", "tdm-wclk", "dpll-d4"; + #reset-cells = <1>; + resets = <&matrixcrm ZX297520V3_LSP_RESET>; + }; diff --git a/Documentation/devicetree/bindings/clock/zte,zx297520v3-matrixcrm.yaml b/Documentation/devicetree/bindings/clock/zte,zx297520v3-matrixcrm.yaml new file mode 100644 index 000000000000..5e9506db7365 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/zte,zx297520v3-matrixcrm.yaml @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/zte,zx297520v3-matrixcrm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ZTE zx297520v3 SoC matrix clock and reset controller + +maintainers: + - Stefan Dösinger + +description: | + This controller contains clock and reset controls for high speed devices on + the zx297520v3 board: The CPU, RAM, SDIO and Ethernet clocks and resets are + found here. This controller requires PLL-generated clocks from Topcrm as well + as the fixed 26 MHz and 32 kHz oscillators found on this board. + + This controller also contains hardware mutex registers for synchronization + with different processors on this board. + + An additional curiosity are registers that allow setting (but not reading) the + ARM architected timer's CNTVAL. This is not exposed in the binding because + there shouldn't be a need to access it. + + All available clocks are defined as preprocessor macros in the + "include/dt-bindings/clock/zte,zx297520v3-clk.h" header. Resets are defined in + the "include/dt-bindings/reset/zte,zx297520v3-reset.h" header. + +properties: + compatible: + const: zte,zx297520v3-matrixcrm + + reg: + maxItems: 1 + + clocks: + items: + - description: 26 MHz external oscillator + - description: 32 kHz external oscillator + - description: AHB clock from topcrm + - description: Main PLL output from topcrm (usually 624 MHz) + - description: Main PLL subdivision factor 5 + - description: Dpll output from topcrm (usually 491.52 MHz) + - description: Gpll output from topcrm (usually 200 MHz) + - description: Gpll subdivision factor 2 + - description: osc26m work clock from topcrm + + clock-names: + items: + - const: osc26m + - const: osc32k + - const: ahb + - const: mpll + - const: mpll-d5 + - const: dpll + - const: gpll + - const: gpll-d2 + - const: wclk-osc26m + + "#clock-cells": + const: 1 + + "#hwlock-cells": + const: 1 + + "#reset-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - "#clock-cells" + - "#hwlock-cells" + - "#reset-cells" + +additionalProperties: false + +examples: + - | + #include + #include + + clock-controller@1306000 { + compatible = "zte,zx297520v3-matrixcrm"; + reg = <0x01306000 0x400>; + #clock-cells = <1>; + clocks = <&osc26m>, <&osc32k>, <&topcrm ZX297520V3_AHB_PCLK>, + <&topcrm ZX297520V3_MPLL>, <&topcrm ZX297520V3_MPLL_D5>, + <&topcrm ZX297520V3_DPLL>, <&topcrm ZX297520V3_GPLL>, + <&topcrm ZX297520V3_GPLL_D2>, + <&topcrm ZX297520V3_GATED_OSC26M>; + clock-names = "osc26m", "osc32k", "ahb", "mpll", "mpll-d5", "dpll", + "gpll", "gpll-d2", "wclk-osc26m"; + #hwlock-cells = <1>; + #reset-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/clock/zte,zx297520v3-topcrm.yaml b/Documentation/devicetree/bindings/clock/zte,zx297520v3-topcrm.yaml new file mode 100644 index 000000000000..8510ffde2924 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/zte,zx297520v3-topcrm.yaml @@ -0,0 +1,122 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/zte,zx297520v3-topcrm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ZTE zx297520v3 SoC top clock and reset controller + +maintainers: + - Stefan Dösinger + +description: | + The zx297520v3 top clock and reset controller generates clocks for core + devices on the board like the main bus, USB and timers. In addition to clocks + it has reset controls for peripherals, a global board reset, watchdog reset + controls and a USB status register. + + The controller has two clock inputs: a 26 MHz and a 32 kHz external + oscillator. They need to be provided as input clocks. The controller provides + PLL output frequencies to downstream clock controllers. + + The USB PHY is exposed as two PHYs, one for USB and another for HSIC. Note + that while the controls for both PHYs are always present, the PHYs themselves + may be absent. If this is the case the controller never signals that the + missing PHY is ready. + + All available clocks are defined as preprocessor macros in the + "include/dt-bindings/clock/zte,zx297520v3-clk.h" header. The resets are + defined in the "include/dt-bindings/reset/zte,zx297520v3-reset.h" header. PHY + defines are found in "include/dt-bindings/phy/zte,zx297520v3-topcrm.h". + +properties: + compatible: + items: + - const: zte,zx297520v3-topcrm + - const: syscon + + reg: + maxItems: 1 + + clocks: + items: + - description: 26 MHz external oscillator + - description: 32 kHz external oscillator + + clock-names: + items: + - const: osc26m + - const: osc32k + + interrupts: + items: + - description: IRQ reporting USB connection + - description: IRQ reporting USB disconnection + - description: IRQ reporting HSIC connection + - description: IRQ reporting HSIC disconnection + + interrupt-names: + items: + - const: usb-up + - const: usb-down + - const: hsic-up + - const: hsic-down + + "#clock-cells": + const: 1 + + "#phy-cells": + const: 1 + + "#reset-cells": + const: 1 + + reboot: + type: object + $ref: /schemas/power/reset/syscon-reboot.yaml# + unevaluatedProperties: false + description: + Reboot method for the SoC. + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + - interrupt-names + - reboot + - "#clock-cells" + - "#phy-cells" + - "#reset-cells" + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + clock-controller@13b000 { + compatible = "zte,zx297520v3-topcrm", "syscon"; + reg = <0x0013b000 0x400>; + #clock-cells = <1>; + clocks = <&osc26m>, <&osc32k>; + clock-names = "osc26m", "osc32k"; + interrupts = , + , + , + ; + interrupt-names = "usb-up", "usb-down", "hsic-up", "hsic-down"; + #phy-cells = <1>; + #reset-cells = <1>; + + reboot { + compatible = "syscon-reboot"; + mask = <0x1>; + offset = <0x0>; + value = <0x1>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 7a162e9bcab1..984f96f51c24 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2069,6 +2069,15 @@ M: Jiaxun Yang S: Supported F: drivers/rtc/rtc-goldfish.c +ANLOGIC DR1V90 CRU DRIVER +M: Junhui Liu +S: Maintained +F: Documentation/devicetree/bindings/clock/anlogic,dr1v90-cru.yaml +F: drivers/clk/anlogic/cru?dr1* +F: drivers/reset/reset-dr1v90.c +F: include/dt-bindings/clock/anlogic,dr1v90-cru.h +F: include/dt-bindings/reset/anlogic,dr1v90-cru.h + AOA (Apple Onboard Audio) ALSA DRIVER M: Johannes Berg L: linuxppc-dev@lists.ozlabs.org @@ -3963,8 +3972,15 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Odd fixes F: Documentation/arch/arm/zte/ F: Documentation/devicetree/bindings/arm/zte.yaml +F: Documentation/devicetree/bindings/clock/zte,zx297520v3-lspcrm.yaml +F: Documentation/devicetree/bindings/clock/zte,zx297520v3-matrixcrm.yaml +F: Documentation/devicetree/bindings/clock/zte,zx297520v3-topcrm.yaml F: arch/arm/boot/dts/zte/ F: arch/arm/mach-zte/ +F: drivers/clk/zte/ +F: include/dt-bindings/clock/zte,zx297520v3-clk.h +F: include/dt-bindings/phy/zte,zx297520v3-topcrm.h +F: include/dt-bindings/reset/zte,zx297520v3-reset.h ARM/ZYNQ ARCHITECTURE M: Michal Simek @@ -6635,7 +6651,7 @@ M: Jerome Brunet L: linux-clk@vger.kernel.org S: Maintained Q: http://patchwork.kernel.org/project/linux-clk/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next F: Documentation/devicetree/bindings/clock/ F: drivers/clk/ F: include/dt-bindings/clock/ @@ -16958,6 +16974,17 @@ M: Sean Wang S: Maintained F: drivers/media/rc/mtk-cir.c +MEDIATEK CLOCK DRIVERS +M: AngeloGioacchino Del Regno +L: linux-clk@vger.kernel.org +L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) +S: Maintained +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux.git +F: Documentation/devicetree/bindings/clock/mediatek,* +F: drivers/clk/mediatek/ +F: include/dt-bindings/clock/mediatek,*.h +F: include/dt-bindings/clock/mt*-clk.h + MEDIATEK DMA DRIVER M: Sean Wang L: dmaengine@vger.kernel.org @@ -22846,6 +22873,7 @@ F: drivers/media/platform/qcom/camss/ QUALCOMM CLOCK DRIVERS M: Bjorn Andersson +R: Abel Vesa L: linux-arm-msm@vger.kernel.org S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git @@ -24138,11 +24166,12 @@ N: spacemit K: spacemit RISC-V TENSTORRENT SoC SUPPORT -M: Drew Fustini +M: Drew Fustini M: Joel Stanley +M: Anirudh Srinivasan L: linux-riscv@lists.infradead.org S: Maintained -T: git https://github.com/tenstorrent/linux.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tenstorrent/linux.git F: Documentation/devicetree/bindings/clock/tenstorrent,atlantis-prcm-rcpu.yaml F: Documentation/devicetree/bindings/riscv/tenstorrent.yaml F: arch/riscv/boot/dts/tenstorrent/ diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index f9592fd9ec2b..37a8e35d4178 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -221,6 +221,7 @@ config COMMON_CLK_EN7523 bool "Clock driver for Airoha/EcoNet SoC system clocks" depends on OF depends on ARCH_AIROHA || ECONET || COMPILE_TEST + select GENERIC_PHY default ARCH_AIROHA help This driver provides the fixed clocks and gates present on Airoha @@ -450,14 +451,17 @@ config COMMON_CLK_STM32H7 config COMMON_CLK_MMP2 def_bool COMMON_CLK && (MACH_MMP2_DT || MACH_MMP3_DT) + select COMMON_CLK_MMP help Support for Marvell MMP2 and MMP3 SoC clocks config COMMON_CLK_MMP2_AUDIO - tristate "Clock driver for MMP2 Audio subsystem" - depends on COMMON_CLK_MMP2 || COMPILE_TEST - help - This driver supports clocks for Audio subsystem on MMP2 SoC. + tristate "Clock driver for MMP2 Audio subsystem" + depends on COMMON_CLK_MMP2 || COMPILE_TEST + depends on PM_CLK + select COMMON_CLK_MMP + help + This driver supports clocks for Audio subsystem on MMP2 SoC. config COMMON_CLK_BD718XX tristate "Clock driver for 32K clk gates on ROHM PMICs" @@ -507,9 +511,11 @@ config COMMON_CLK_RPMI source "drivers/clk/actions/Kconfig" source "drivers/clk/analogbits/Kconfig" +source "drivers/clk/anlogic/Kconfig" source "drivers/clk/aspeed/Kconfig" source "drivers/clk/bcm/Kconfig" source "drivers/clk/cix/Kconfig" +source "drivers/clk/davinci/Kconfig" source "drivers/clk/eswin/Kconfig" source "drivers/clk/hisilicon/Kconfig" source "drivers/clk/imgtec/Kconfig" @@ -547,6 +553,7 @@ source "drivers/clk/uniphier/Kconfig" source "drivers/clk/visconti/Kconfig" source "drivers/clk/x86/Kconfig" source "drivers/clk/xilinx/Kconfig" +source "drivers/clk/zte/Kconfig" source "drivers/clk/zynqmp/Kconfig" # Kunit test cases diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index b18af485d7f0..52d138d4ffc8 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -29,6 +29,7 @@ clk-test-y := clk_test.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_parse_clkspec.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 @@ -125,6 +126,7 @@ obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o # please keep this section sorted lexicographically by directory path name obj-y += actions/ obj-y += analogbits/ +obj-y += anlogic/ obj-y += aspeed/ obj-$(CONFIG_COMMON_CLK_AT91) += at91/ obj-$(CONFIG_ARCH_ARTPEC) += axis/ @@ -132,7 +134,7 @@ 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_DAVINCI) += davinci/ obj-$(CONFIG_COMMON_CLK_ESWIN) += eswin/ obj-$(CONFIG_COMMON_CLK_HISI) += hisilicon/ obj-y += imgtec/ @@ -143,12 +145,12 @@ obj-y += mediatek/ obj-$(CONFIG_ARCH_MESON) += meson/ obj-y += microchip/ ifeq ($(CONFIG_COMMON_CLK), y) -obj-$(CONFIG_ARCH_MMP) += mmp/ +obj-$(CONFIG_COMMON_CLK_MMP) += mmp/ endif obj-y += mstar/ obj-y += mvebu/ obj-$(CONFIG_ARCH_MXS) += mxs/ -obj-$(CONFIG_ARCH_MA35) += nuvoton/ +obj-y += nuvoton/ obj-$(CONFIG_COMMON_CLK_NXP) += nxp/ obj-$(CONFIG_COMMON_CLK_PISTACHIO) += pistachio/ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ @@ -181,5 +183,6 @@ ifeq ($(CONFIG_COMMON_CLK), y) obj-$(CONFIG_X86) += x86/ endif obj-y += xilinx/ +obj-$(CONFIG_COMMON_CLK_ZTE) += zte/ obj-$(CONFIG_ARCH_ZYNQ) += zynq/ obj-$(CONFIG_COMMON_CLK_ZYNQMP) += zynqmp/ diff --git a/drivers/clk/actions/owl-composite.h b/drivers/clk/actions/owl-composite.h index 6d7c6f0c47c8..ca055599b2fc 100644 --- a/drivers/clk/actions/owl-composite.h +++ b/drivers/clk/actions/owl-composite.h @@ -119,6 +119,5 @@ extern const struct clk_ops owl_comp_div_ops; extern const struct clk_ops owl_comp_fact_ops; extern const struct clk_ops owl_comp_fix_fact_ops; extern const struct clk_ops owl_comp_pass_ops; -extern const struct clk_ops clk_fixed_factor_ops; #endif /* _OWL_COMPOSITE_H_ */ diff --git a/drivers/clk/actions/owl-fixed-factor.h b/drivers/clk/actions/owl-fixed-factor.h index 3dfd7fd7d292..bbac5afadd67 100644 --- a/drivers/clk/actions/owl-fixed-factor.h +++ b/drivers/clk/actions/owl-fixed-factor.h @@ -23,6 +23,4 @@ _flags), \ } -extern const struct clk_ops clk_fixed_factor_ops; - #endif /* _OWL_FIXED_FACTOR_H_ */ diff --git a/drivers/clk/actions/owl-pll.c b/drivers/clk/actions/owl-pll.c index 869690b79cc1..5e30ce35f2f5 100644 --- a/drivers/clk/actions/owl-pll.c +++ b/drivers/clk/actions/owl-pll.c @@ -186,7 +186,7 @@ static int owl_pll_set_rate(struct clk_hw *hw, unsigned long rate, regmap_write(common->regmap, pll_hw->reg, reg); - udelay(pll_hw->delay); + udelay((unsigned long)pll_hw->delay); return 0; } diff --git a/drivers/clk/anlogic/Kconfig b/drivers/clk/anlogic/Kconfig new file mode 100644 index 000000000000..b3b17540176d --- /dev/null +++ b/drivers/clk/anlogic/Kconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config ANLOGIC_DR1_CRU + tristate "Clock support for Anlogic DR1 series SoCs" + depends on ARCH_ANLOGIC || COMPILE_TEST + select AUXILIARY_BUS + default ARCH_ANLOGIC + help + Say Y to enable clock controller unit support for Anlogic DR1 series + SoCs. + +if ANLOGIC_DR1_CRU + +config ANLOGIC_DR1V90_CRU + tristate "Anlogic DR1V90 clock support" + depends on ARCH_ANLOGIC || COMPILE_TEST + default ARCH_ANLOGIC + help + Support for the Clock and Reset Unit in Anlogic DR1V90 SoCs. + +endif diff --git a/drivers/clk/anlogic/Makefile b/drivers/clk/anlogic/Makefile new file mode 100644 index 000000000000..fab7f29bb097 --- /dev/null +++ b/drivers/clk/anlogic/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_ANLOGIC_DR1_CRU) += anlogic-dr1-cru.o +anlogic-dr1-cru-y += cru_dr1.o + +obj-$(CONFIG_ANLOGIC_DR1V90_CRU) += anlogic-dr1v90-cru.o +anlogic-dr1v90-cru-y += cru-dr1v90.o diff --git a/drivers/clk/anlogic/cru-dr1v90.c b/drivers/clk/anlogic/cru-dr1v90.c new file mode 100644 index 000000000000..b513dfba3dbd --- /dev/null +++ b/drivers/clk/anlogic/cru-dr1v90.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024-2025 Anlogic, Inc. + * Copyright (C) 2026 Junhui Liu + */ + +#include +#include +#include +#include +#include + +#include "cru_dr1.h" + +#include + +static const struct clk_div_table cru_div_table_24[] = { + { 0xFFFFFF, 1 }, { 0x555555, 2 }, { 0x249249, 3 }, { 0x111111, 4 }, + { 0x084210, 5 }, { 0x041041, 6 }, { 0x020408, 7 }, { 0x010101, 8 }, + { 0x008040, 9 }, { 0x004010, 10 }, { 0x002004, 11 }, { 0x001001, 12 }, + { 0x000800, 13 }, { 0x000400, 14 }, { 0x000200, 15 }, { 0x000100, 16 }, + { 0x000080, 17 }, { 0x000040, 18 }, { 0x000020, 19 }, { 0x000010, 20 }, + { 0x000008, 21 }, { 0x000004, 22 }, { 0x000002, 23 }, { 0x000001, 24 }, + { /* sentinel */ } +}; + +static const struct clk_div_table cru_div_table_32[] = { + { 0xFFFFFFFF, 1 }, { 0x55555555, 2 }, { 0x24924924, 3 }, + { 0x11111111, 4 }, { 0x08421084, 5 }, { 0x04104104, 6 }, + { 0x02040810, 7 }, { 0x01010101, 8 }, { 0x00804020, 9 }, + { 0x00401004, 10 }, { 0x00200400, 11 }, { 0x00100100, 12 }, + { 0x00080040, 13 }, { 0x00040010, 14 }, { 0x00020004, 15 }, + { 0x00010001, 16 }, { 0x00008000, 17 }, { 0x00004000, 18 }, + { 0x00002000, 19 }, { 0x00001000, 20 }, { 0x00000800, 21 }, + { 0x00000400, 22 }, { 0x00000200, 23 }, { 0x00000100, 24 }, + { 0x00000080, 25 }, { 0x00000040, 26 }, { 0x00000020, 27 }, + { 0x00000010, 28 }, { 0x00000008, 29 }, { 0x00000004, 30 }, + { 0x00000002, 31 }, { 0x00000001, 32 }, { /* sentinel */ } +}; + +CLK_FIXED_FACTOR_FW_NAME(osc_div2, "osc_div2", "osc", 2, 1, 0); + +CRU_PLL_NM_DEFINE(cpu_pll, CRU_PARENT_NAME(osc), 0x120); +CRU_PLL_C_DEFINE(cpu_pll_4x, CRU_PARENT_HW(cpu_pll), 0x14c); + +CRU_DIV_DEFINE(cpu_4x_div1, CRU_PARENT_HW(cpu_pll_4x), 0x010, 0, 24, + cru_div_table_24, CLK_DIVIDER_READ_ONLY); +CRU_DIV_DEFINE(cpu_4x_div2, CRU_PARENT_HW(cpu_pll_4x), 0x014, 0, 24, + cru_div_table_24, CLK_DIVIDER_READ_ONLY); +CRU_DIV_DEFINE(cpu_4x_div4, CRU_PARENT_HW(cpu_pll_4x), 0x018, 0, 24, + cru_div_table_24, CLK_DIVIDER_READ_ONLY); + +CRU_PLL_NM_DEFINE(io_pll, CRU_PARENT_NAME(osc), 0x220); +CRU_PLL_C_DEFINE(io_1000m, CRU_PARENT_HW(io_pll), 0x248); +CRU_PLL_C_DEFINE(io_400m, CRU_PARENT_HW(io_pll), 0x24c); +CRU_PLL_C_DEFINE(io_25m, CRU_PARENT_HW(io_pll), 0x250); +CRU_PLL_C_DEFINE(io_80m, CRU_PARENT_HW(io_pll), 0x254); + +CRU_DIV_DEFINE(io_400m_div2, CRU_PARENT_HW(io_400m), 0x020, 0, 32, + cru_div_table_32, CLK_DIVIDER_READ_ONLY); +CRU_DIV_DEFINE(io_400m_div4, CRU_PARENT_HW(io_400m), 0x024, 0, 32, + cru_div_table_32, CLK_DIVIDER_READ_ONLY); +CRU_DIV_DEFINE(io_400m_div8, CRU_PARENT_HW(io_400m), 0x028, 0, 32, + cru_div_table_32, CLK_DIVIDER_READ_ONLY); +CRU_DIV_DEFINE(io_400m_div16, CRU_PARENT_HW(io_400m), 0x02c, 0, 32, + cru_div_table_32, CLK_DIVIDER_READ_ONLY); + +CRU_DIV_GATE_DEFINE(qspi, CRU_PARENT_HW(io_1000m), 0x030, 0, 6, NULL, 0, 2); +CRU_DIV_GATE_DEFINE(spi, CRU_PARENT_HW(io_1000m), 0x030, 8, 6, NULL, 0, 4); +CRU_DIV_GATE_DEFINE(smc, CRU_PARENT_HW(io_1000m), 0x030, 16, 6, NULL, 0, 4); +CRU_DIV_DEFINE(sdio, CRU_PARENT_HW(io_400m), 0x030, 24, 6, NULL, 0); + +CRU_DIV_GATE_DEFINE(gpio_db, CRU_PARENT_HW(io_25m), 0x034, 0, 6, NULL, 0, 1); +CRU_DIV_GATE_DEFINE(efuse, CRU_PARENT_HW(io_25m), 0x034, 8, 6, NULL, 0, 1); +CRU_DIV_GATE_DEFINE(tvs, CRU_PARENT_HW(io_25m), 0x034, 16, 6, NULL, 0, 1); +CRU_DIV_GATE_DEFINE(trng, CRU_PARENT_HW(io_25m), 0x034, 24, 7, NULL, 0, 1); + +CRU_DIV_GATE_DEFINE(osc_div, CRU_PARENT_NAME(osc), 0x038, 0, 6, NULL, 0, 1); +CRU_DIV_GATE_DEFINE(pwm, CRU_PARENT_NAME(osc), 0x038, 8, 12, NULL, 0, 1); + +CRU_DIV_GATE_DEFINE(fclk0, CRU_PARENT_HW(io_400m), 0x03c, 0, 6, NULL, 0, 1); +CRU_DIV_GATE_DEFINE(fclk1, CRU_PARENT_HW(io_400m), 0x03c, 8, 6, NULL, 0, 1); +CRU_DIV_GATE_DEFINE(fclk2, CRU_PARENT_HW(io_400m), 0x03c, 16, 6, NULL, 0, 1); +CRU_DIV_GATE_DEFINE(fclk3, CRU_PARENT_HW(io_400m), 0x03c, 24, 6, NULL, 0, 1); + +static const struct clk_parent_data wdt_parents[] = { + CRU_PARENT_HW(osc_div2), + CRU_PARENT_NAME(wdt_ext) +}; +CRU_MUX_DEFINE(wdt_sel, wdt_parents, 0x040, 1, 1); + +static const struct clk_parent_data efuse_parents[] = { + CRU_PARENT_NAME(osc), + CRU_PARENT_DIV_HW(efuse) +}; +CRU_MUX_DEFINE(efuse_sel, efuse_parents, 0x040, 2, 1); + +static const struct clk_parent_data can_parents[] = { + CRU_PARENT_HW(io_80m), + CRU_PARENT_NAME(can_ext) +}; +CRU_MUX_DEFINE(can_sel, can_parents, 0x040, 3, 1); + +static const struct clk_parent_data cpu_parents[] = { + CRU_PARENT_HW(cpu_4x_div1), + CRU_PARENT_HW(cpu_4x_div2) +}; +CRU_MUX_DEFINE(cpu_sel, cpu_parents, 0x040, 5, 1); + +CRU_GATE_DEFINE(can0, CRU_PARENT_HW(can_sel), 0x08c, 20, CLK_GATE_SET_TO_DISABLE); +CRU_GATE_DEFINE(can1, CRU_PARENT_HW(can_sel), 0x08c, 21, CLK_GATE_SET_TO_DISABLE); + +static const struct cru_clk dr1v90_cru_clks[] = { + [CLK_OSC_DIV2] = { &osc_div2.hw, NULL }, + [CLK_CPU_PLL] = { &cpu_pll.hw, &cpu_pll.reg }, + [CLK_CPU_PLL_4X] = { &cpu_pll_4x.hw, &cpu_pll_4x.reg }, + [CLK_CPU_4X] = { &cpu_4x_div1.hw, &cpu_4x_div1.reg }, + [CLK_CPU_2X] = { &cpu_4x_div2.hw, &cpu_4x_div2.reg }, + [CLK_CPU_1X] = { &cpu_4x_div4.hw, &cpu_4x_div4.reg }, + [CLK_IO_PLL] = { &io_pll.hw, &io_pll.reg }, + [CLK_IO_1000M] = { &io_1000m.hw, &io_1000m.reg }, + [CLK_IO_400M] = { &io_400m.hw, &io_400m.reg }, + [CLK_IO_25M] = { &io_25m.hw, &io_25m.reg }, + [CLK_IO_80M] = { &io_80m.hw, &io_80m.reg }, + [CLK_IO_400M_DIV2] = { &io_400m_div2.hw, &io_400m_div2.reg }, + [CLK_IO_400M_DIV4] = { &io_400m_div4.hw, &io_400m_div4.reg }, + [CLK_IO_400M_DIV8] = { &io_400m_div8.hw, &io_400m_div8.reg }, + [CLK_IO_400M_DIV16] = { &io_400m_div16.hw, &io_400m_div16.reg }, + [CLK_QSPI] = { &qspi.divider.hw, &qspi.divider.reg }, + [CLK_SPI] = { &spi.divider.hw, &spi.divider.reg }, + [CLK_SMC] = { &smc.divider.hw, &smc.divider.reg }, + [CLK_SDIO] = { &sdio.hw, &sdio.reg }, + [CLK_GPIO_DB] = { &gpio_db.divider.hw, &gpio_db.divider.reg }, + [CLK_EFUSE] = { &efuse.divider.hw, &efuse.divider.reg }, + [CLK_TVS] = { &tvs.divider.hw, &tvs.divider.reg }, + [CLK_TRNG] = { &trng.divider.hw, &trng.divider.reg }, + [CLK_OSC_DIV] = { &osc_div.divider.hw, &osc_div.divider.reg }, + [CLK_PWM] = { &pwm.divider.hw, &pwm.divider.reg }, + [CLK_FCLK0] = { &fclk0.divider.hw, &fclk0.divider.reg }, + [CLK_FCLK1] = { &fclk1.divider.hw, &fclk1.divider.reg }, + [CLK_FCLK2] = { &fclk2.divider.hw, &fclk2.divider.reg }, + [CLK_FCLK3] = { &fclk3.divider.hw, &fclk3.divider.reg }, + [CLK_WDT_SEL] = { &wdt_sel.hw, &wdt_sel.reg }, + [CLK_EFUSE_SEL] = { &efuse_sel.hw, &efuse_sel.reg }, + [CLK_CAN_SEL] = { &can_sel.hw, &can_sel.reg }, + [CLK_CPU_SEL] = { &cpu_sel.hw, &cpu_sel.reg }, + [CLK_CAN0] = { &can0.hw, &can0.reg }, + [CLK_CAN1] = { &can1.hw, &can1.reg } +}; + +static int dr1v90_cru_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + void __iomem *base; + int ret; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + ret = dr1_cru_clk_register(dev, base, dr1v90_cru_clks, + ARRAY_SIZE(dr1v90_cru_clks)); + if (ret) + return dev_err_probe(dev, ret, "failed to register clocks\n"); + + ret = dr1_cru_reset_register(dev, base); + if (ret) + return dev_err_probe(dev, ret, "failed to register resets\n"); + + return 0; +} + +static const struct of_device_id dr1v90_cru_ids[] = { + { .compatible = "anlogic,dr1v90-cru" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, dr1v90_cru_ids); + +static struct platform_driver dr1v90_cru_driver = { + .driver = { + .name = "dr1v90-cru", + .of_match_table = dr1v90_cru_ids, + }, + .probe = dr1v90_cru_probe, +}; +module_platform_driver(dr1v90_cru_driver); + +MODULE_AUTHOR("Fushan Zeng "); +MODULE_AUTHOR("Junhui Liu "); +MODULE_DESCRIPTION("Anlogic DR1V90 CRU driver"); +MODULE_IMPORT_NS("CLK_ANLOGIC"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/anlogic/cru_dr1.c b/drivers/clk/anlogic/cru_dr1.c new file mode 100644 index 000000000000..10f8751a8838 --- /dev/null +++ b/drivers/clk/anlogic/cru_dr1.c @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024-2025 Anlogic, Inc. + * Copyright (C) 2026 Junhui Liu + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cru_dr1.h" + +static unsigned long cru_pll_nm_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct cru_pll *pll = hw_to_cru_pll(hw); + u32 mult, div; + + div = FIELD_GET(GENMASK(6, 0), readl(pll->reg)) + 1; + mult = FIELD_GET(GENMASK(6, 0), readl(pll->reg + 4)) + 1; + + return parent_rate * mult / div; +} + +const struct clk_ops dr1_cru_pll_nm_ops = { + .recalc_rate = cru_pll_nm_recalc_rate, +}; +EXPORT_SYMBOL_NS_GPL(dr1_cru_pll_nm_ops, "CLK_ANLOGIC"); + +static unsigned long cru_pll_c_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct cru_pll *pll = hw_to_cru_pll(hw); + u32 div; + + div = FIELD_GET(GENMASK(30, 24), readl(pll->reg)) + 1; + + return parent_rate / div; +} + +const struct clk_ops dr1_cru_pll_c_ops = { + .recalc_rate = cru_pll_c_recalc_rate, +}; +EXPORT_SYMBOL_NS_GPL(dr1_cru_pll_c_ops, "CLK_ANLOGIC"); + +static void cru_div_gate_endisable(struct clk_hw *hw, int enable) +{ + struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw); + struct clk_divider *divider = &div_gate->divider; + u32 reg; + + reg = readl(divider->reg); + reg &= ~(clk_div_mask(divider->width) << divider->shift); + + if (enable) + reg |= div_gate->val << divider->shift; + + writel(reg, divider->reg); +} + +static int cru_div_gate_enable(struct clk_hw *hw) +{ + cru_div_gate_endisable(hw, 1); + + return 0; +} + +static void cru_div_gate_disable(struct clk_hw *hw) +{ + cru_div_gate_endisable(hw, 0); +} + +static int cru_div_gate_is_enabled(struct clk_hw *hw) +{ + struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw); + struct clk_divider *divider = &div_gate->divider; + u32 val; + + val = readl(divider->reg) >> divider->shift; + val &= clk_div_mask(divider->width); + + return !!val; +} + +static unsigned long cru_div_gate_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw); + struct clk_divider *divider = &div_gate->divider; + unsigned int val; + + val = readl(divider->reg) >> divider->shift; + val &= clk_div_mask(divider->width); + + if (val < div_gate->min) + return 0; + + return divider_recalc_rate(hw, parent_rate, val, divider->table, + divider->flags, divider->width); +} + +static int cru_div_gate_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw); + struct clk_divider *divider = &div_gate->divider; + unsigned long maxdiv, mindiv; + int div = 0; + + maxdiv = clk_div_mask(divider->width) + 1; + mindiv = div_gate->min + 1; + + div = DIV_ROUND_UP_ULL(req->best_parent_rate, req->rate); + div = div > maxdiv ? maxdiv : div; + div = div < mindiv ? mindiv : div; + + req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, div); + + return 0; +} + +static int cru_div_gate_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw); + struct clk_divider *divider = &div_gate->divider; + int value; + u32 reg; + + if (!__clk_is_enabled(hw->clk)) + return 0; + + value = divider_get_val(rate, parent_rate, divider->table, + divider->width, divider->flags); + if (value < 0) + return value; + + if (value < div_gate->min) + value = div_gate->min; + + reg = readl(divider->reg); + reg &= ~(clk_div_mask(divider->width) << divider->shift); + reg |= (u32)value << divider->shift; + writel(reg, divider->reg); + + div_gate->val = value; + + return 0; +} + +static int cru_div_gate_init(struct clk_hw *hw) +{ + struct cru_div_gate *div_gate = hw_to_cru_div_gate(hw); + struct clk_divider *divider = &div_gate->divider; + u32 val; + + val = readl(divider->reg) >> divider->shift; + val &= clk_div_mask(divider->width); + div_gate->val = val; + + return 0; +} + +const struct clk_ops dr1_cru_div_gate_ops = { + .enable = cru_div_gate_enable, + .disable = cru_div_gate_disable, + .is_enabled = cru_div_gate_is_enabled, + .recalc_rate = cru_div_gate_recalc_rate, + .determine_rate = cru_div_gate_determine_rate, + .set_rate = cru_div_gate_set_rate, + .init = cru_div_gate_init, +}; +EXPORT_SYMBOL_NS_GPL(dr1_cru_div_gate_ops, "CLK_ANLOGIC"); + +int dr1_cru_clk_register(struct device *dev, void __iomem *base, + const struct cru_clk *clks, int nr_clks) +{ + struct clk_hw_onecell_data *priv; + int i, ret; + + priv = devm_kzalloc(dev, struct_size(priv, hws, nr_clks), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + for (i = 0; i < nr_clks; i++) { + const struct cru_clk *clk = &clks[i]; + + if (clk->reg) + *(clk->reg) += (uintptr_t)base; + + ret = devm_clk_hw_register(dev, clk->hw); + if (ret) + return ret; + + priv->hws[i] = clk->hw; + } + + priv->num = nr_clks; + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, priv); + if (ret) + dev_err(dev, "failed to add clock hardware provider\n"); + + return ret; +} +EXPORT_SYMBOL_NS_GPL(dr1_cru_clk_register, "CLK_ANLOGIC"); + +int dr1_cru_reset_register(struct device *dev, void __iomem *base) +{ + struct auxiliary_device *adev; + + adev = devm_auxiliary_device_create(dev, "reset", base); + if (!adev) + return -ENODEV; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(dr1_cru_reset_register, "CLK_ANLOGIC"); + +MODULE_DESCRIPTION("Anlogic DR1 CRU driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/anlogic/cru_dr1.h b/drivers/clk/anlogic/cru_dr1.h new file mode 100644 index 000000000000..5386aed9e9f3 --- /dev/null +++ b/drivers/clk/anlogic/cru_dr1.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024-2025 Anlogic, Inc. + * Copyright (C) 2026 Junhui Liu + */ + +#ifndef _CRU_DR1_H_ +#define _CRU_DR1_H_ + +#include + +struct cru_pll { + struct clk_hw hw; + void __iomem *reg; +}; + +struct cru_div_gate { + struct clk_divider divider; + u32 val; /* Cached divider value for restoring on enable */ + u8 min; /* Minimum divider value to avoid timing issues */ +}; + +struct cru_clk { + struct clk_hw *hw; + void **reg; +}; + +#define CRU_PARENT_NAME(_name) { .fw_name = #_name } +#define CRU_PARENT_HW(_parent) { .hw = &_parent.hw } +#define CRU_PARENT_DIV_HW(_parent) { .hw = &_parent.divider.hw } + +#define CRU_INITHW(_name, _parent, _ops) \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .parent_data = (const struct clk_parent_data[]) \ + { _parent }, \ + .num_parents = 1, \ + .ops = &_ops, \ + } + +#define CRU_INITHW_PARENTS(_name, _parents, _ops) \ + .hw.init = CLK_HW_INIT_PARENTS_DATA(#_name, _parents, &_ops, 0) + +#define CRU_PLL_NM_DEFINE(_name, _parent, _reg) \ +static struct cru_pll _name = { \ + .reg = (void __iomem *)(_reg), \ + CRU_INITHW(_name, _parent, dr1_cru_pll_nm_ops), \ +} + +#define CRU_PLL_C_DEFINE(_name, _parent, _reg) \ +static struct cru_pll _name = { \ + .reg = (void __iomem *)(_reg), \ + CRU_INITHW(_name, _parent, dr1_cru_pll_c_ops), \ +} + +#define CRU_DIV_DEFINE(_name, _parent, _reg, _shift, _width, _table, \ + _flags) \ +static struct clk_divider _name = { \ + .shift = _shift, \ + .width = _width, \ + .flags = _flags, \ + .table = _table, \ + .reg = (void __iomem *)(_reg), \ + CRU_INITHW(_name, _parent, clk_divider_ops), \ +} + +#define CRU_DIV_GATE_DEFINE(_name, _parent, _reg, _shift, _width, \ + _table, _flags, _min) \ +static struct cru_div_gate _name = { \ + .min = _min, \ + .divider = { \ + .shift = _shift, \ + .width = _width, \ + .flags = _flags, \ + .table = _table, \ + .reg = (void __iomem *)(_reg), \ + CRU_INITHW(_name, _parent, dr1_cru_div_gate_ops), \ + } \ +} + +#define CRU_MUX_DEFINE(_name, _parents, _reg, _shift, _width) \ +static struct clk_mux _name = { \ + .shift = _shift, \ + .mask = GENMASK(_width - 1, 0), \ + .reg = (void __iomem *)(_reg), \ + CRU_INITHW_PARENTS(_name, _parents, clk_mux_ops) \ +} + +#define CRU_GATE_DEFINE(_name, _parent, _reg, _bit_idx, _flags) \ +static struct clk_gate _name = { \ + .bit_idx = _bit_idx, \ + .flags = _flags, \ + .reg = (void __iomem *)(_reg), \ + CRU_INITHW(_name, _parent, clk_gate_ops) \ +} + +static inline struct cru_pll *hw_to_cru_pll(struct clk_hw *hw) +{ + return container_of(hw, struct cru_pll, hw); +} + +static inline struct cru_div_gate *hw_to_cru_div_gate(struct clk_hw *hw) +{ + struct clk_divider *divider = to_clk_divider(hw); + + return container_of(divider, struct cru_div_gate, divider); +} + +extern const struct clk_ops dr1_cru_pll_nm_ops; +extern const struct clk_ops dr1_cru_pll_c_ops; +extern const struct clk_ops dr1_cru_div_gate_ops; + +int dr1_cru_clk_register(struct device *dev, void __iomem *base, + const struct cru_clk *clks, int nr_clks); +int dr1_cru_reset_register(struct device *dev, void __iomem *base); + +#endif /* _CRU_DR1_H_ */ diff --git a/drivers/clk/aspeed/Kconfig b/drivers/clk/aspeed/Kconfig index ef50481c31ff..2f505eb3ca95 100644 --- a/drivers/clk/aspeed/Kconfig +++ b/drivers/clk/aspeed/Kconfig @@ -15,6 +15,7 @@ config COMMON_CLK_ASPEED config COMMON_CLK_AST2700 bool "Clock driver for AST2700 SoC" depends on ARCH_ASPEED || COMPILE_TEST + select AUXILIARY_BUS help This driver provides support for clock on AST2700 SoC. The driver is responsible for managing the various clocks required diff --git a/drivers/clk/aspeed/clk-aspeed.c b/drivers/clk/aspeed/clk-aspeed.c index 38a5766a435c..d32a3e9f300a 100644 --- a/drivers/clk/aspeed/clk-aspeed.c +++ b/drivers/clk/aspeed/clk-aspeed.c @@ -349,8 +349,8 @@ static struct clk_hw *aspeed_clk_hw_register_gate(struct device *dev, struct regmap *map, u8 clock_idx, u8 reset_idx, u8 clk_gate_flags, spinlock_t *lock) { + struct clk_init_data init = {}; struct aspeed_clk_gate *gate; - struct clk_init_data init; struct clk_hw *hw; int ret; diff --git a/drivers/clk/aspeed/clk-ast2600.c b/drivers/clk/aspeed/clk-ast2600.c index 70061c961b69..cc3d26602b16 100644 --- a/drivers/clk/aspeed/clk-ast2600.c +++ b/drivers/clk/aspeed/clk-ast2600.c @@ -425,8 +425,8 @@ static struct clk_hw *aspeed_g6_clk_hw_register_gate(struct device *dev, struct regmap *map, u8 clock_idx, u8 reset_idx, u8 clk_gate_flags, spinlock_t *lock) { + struct clk_init_data init = {}; struct aspeed_clk_gate *gate; - struct clk_init_data init; struct clk_hw *hw; int ret; diff --git a/drivers/clk/aspeed/clk-ast2700.c b/drivers/clk/aspeed/clk-ast2700.c index 536600fcd024..495b7fa3395b 100644 --- a/drivers/clk/aspeed/clk-ast2700.c +++ b/drivers/clk/aspeed/clk-ast2700.c @@ -824,7 +824,7 @@ static struct clk_hw *ast2700_clk_hw_register_gate(struct device *dev, const cha void __iomem *reg, u8 clock_idx, unsigned long flags, spinlock_t *lock) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_gate *gate; struct clk_hw *hw; int ret = -EINVAL; diff --git a/drivers/clk/at91/clk-audio-pll.c b/drivers/clk/at91/clk-audio-pll.c index 732037bfbda8..26875ad0cce7 100644 --- a/drivers/clk/at91/clk-audio-pll.c +++ b/drivers/clk/at91/clk-audio-pll.c @@ -486,8 +486,8 @@ struct clk_hw * __init at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name, const char *parent_name) { + struct clk_init_data init = {}; struct clk_audio_pad *apad_ck; - struct clk_init_data init; int ret; apad_ck = kzalloc_obj(*apad_ck); @@ -517,8 +517,8 @@ struct clk_hw * __init at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name, const char *parent_name) { + struct clk_init_data init = {}; struct clk_audio_pmc *apmc_ck; - struct clk_init_data init; int ret; apmc_ck = kzalloc_obj(*apmc_ck); diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c index 12bd112d3c50..8d5488223e49 100644 --- a/drivers/clk/at91/clk-h32mx.c +++ b/drivers/clk/at91/clk-h32mx.c @@ -97,7 +97,7 @@ at91_clk_register_h32mx(struct regmap *regmap, const char *name, const char *parent_name) { struct clk_sama5d4_h32mx *h32mxclk; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; h32mxclk = kzalloc_obj(*h32mxclk); diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index ab515239adcf..77f905e57e1a 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -170,7 +170,7 @@ at91_clk_register_main_osc(struct regmap *regmap, init.name = name; init.ops = &main_osc_ops; if (parent_data) - init.parent_data = (const struct clk_parent_data *)parent_data; + init.parent_data = parent_data; else init.parent_names = &parent_name; init.num_parents = 1; @@ -298,8 +298,8 @@ at91_clk_register_main_rc_osc(struct regmap *regmap, const char *name, u32 frequency, u32 accuracy) { + struct clk_init_data init = {}; struct clk_main_rc_osc *osc; - struct clk_init_data init; struct clk_hw *hw; int ret; diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c index b89f60cf0241..1b9a37a9e070 100644 --- a/drivers/clk/at91/clk-pll.c +++ b/drivers/clk/at91/clk-pll.c @@ -318,7 +318,7 @@ at91_clk_register_pll(struct regmap *regmap, const char *name, { struct clk_pll *pll; struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; int offset = PLL_REG(id); unsigned int pllr; int ret; diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c index 5f93aead03fa..135ca0abeb18 100644 --- a/drivers/clk/at91/clk-plldiv.c +++ b/drivers/clk/at91/clk-plldiv.c @@ -86,9 +86,9 @@ struct clk_hw * __init at91_clk_register_plldiv(struct regmap *regmap, const char *name, const char *parent_name) { + struct clk_init_data init = {}; struct clk_plldiv *plldiv; struct clk_hw *hw; - struct clk_init_data init; int ret; plldiv = kzalloc_obj(*plldiv); diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index f0cad50e490b..dc0009ca2cef 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c @@ -42,8 +42,8 @@ at91_clk_register_sam9260_slow(struct regmap *regmap, int num_parents) { struct clk_sam9260_slow *slowck; + struct clk_init_data init = {}; struct clk_hw *hw; - struct clk_init_data init; int ret; if (!name) diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c index 77f2b8fe6cab..4eff52a9798b 100644 --- a/drivers/clk/at91/clk-smd.c +++ b/drivers/clk/at91/clk-smd.c @@ -113,9 +113,9 @@ struct clk_hw * __init at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name, const char **parent_names, u8 num_parents) { + struct clk_init_data init = {}; struct at91sam9x5_clk_smd *smd; struct clk_hw *hw; - struct clk_init_data init; int ret; smd = kzalloc_obj(*smd); diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index b4dc86193e09..0e4c0367c1af 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c @@ -224,9 +224,9 @@ _at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, const char **parent_names, u8 num_parents, u32 usbs_mask) { + struct clk_init_data init = {}; struct at91sam9x5_clk_usb *usb; struct clk_hw *hw; - struct clk_init_data init; int ret; usb = kzalloc_obj(*usb); @@ -275,9 +275,9 @@ struct clk_hw * __init at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, const char *parent_name) { + struct clk_init_data init = {}; struct at91sam9x5_clk_usb *usb; struct clk_hw *hw; - struct clk_init_data init; int ret; usb = kzalloc_obj(*usb); @@ -394,9 +394,9 @@ struct clk_hw * __init at91rm9200_clk_register_usb(struct regmap *regmap, const char *name, const char *parent_name, const u32 *divisors) { + struct clk_init_data init = {}; struct at91rm9200_clk_usb *usb; struct clk_hw *hw; - struct clk_init_data init; int ret; usb = kzalloc_obj(*usb); diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c index 776118f14867..fc5ca22d181a 100644 --- a/drivers/clk/at91/sckc.c +++ b/drivers/clk/at91/sckc.c @@ -231,9 +231,9 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr, unsigned long startup, const struct clk_slow_bits *bits) { + struct clk_init_data init = {}; struct clk_slow_rc_osc *osc; struct clk_hw *hw; - struct clk_init_data init; int ret; if (!sckcr || !name) diff --git a/drivers/clk/bcm/clk-iproc-armpll.c b/drivers/clk/bcm/clk-iproc-armpll.c index 8485428fe49c..aca53e2bda01 100644 --- a/drivers/clk/bcm/clk-iproc-armpll.c +++ b/drivers/clk/bcm/clk-iproc-armpll.c @@ -235,7 +235,7 @@ void __init iproc_armpll_setup(struct device_node *node) { int ret; struct iproc_arm_pll *pll; - struct clk_init_data init; + struct clk_init_data init = {}; const char *parent_name; pll = kzalloc_obj(*pll); diff --git a/drivers/clk/bcm/clk-iproc-asiu.c b/drivers/clk/bcm/clk-iproc-asiu.c index 56a813227981..86c0100934f8 100644 --- a/drivers/clk/bcm/clk-iproc-asiu.c +++ b/drivers/clk/bcm/clk-iproc-asiu.c @@ -206,7 +206,7 @@ void __init iproc_asiu_setup(struct device_node *node, goto err_iomap_gate; for (i = 0; i < num_clks; i++) { - struct clk_init_data init; + struct clk_init_data init = {}; const char *parent_name; struct iproc_asiu_clk *asiu_clk; const char *clk_name; diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c index d708f770971c..4354aac2d270 100644 --- a/drivers/clk/bcm/clk-iproc-pll.c +++ b/drivers/clk/bcm/clk-iproc-pll.c @@ -722,7 +722,7 @@ void iproc_pll_clk_setup(struct device_node *node, int i, ret; struct iproc_pll *pll; struct iproc_clk *iclk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *parent_name; struct iproc_clk *iclk_array; struct clk_hw_onecell_data *clk_data; diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index f1a99de6de4f..9882f243d681 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -553,6 +553,8 @@ static int raspberrypi_clk_probe(struct platform_device *pdev) rpi->cpufreq = platform_device_register_data(dev, "raspberrypi-cpufreq", -1, NULL, 0); + if (IS_ERR(rpi->cpufreq)) + return PTR_ERR(rpi->cpufreq); return 0; } diff --git a/drivers/clk/berlin/berlin2-avpll.c b/drivers/clk/berlin/berlin2-avpll.c index c801d42397bf..33a3cc16b0cc 100644 --- a/drivers/clk/berlin/berlin2-avpll.c +++ b/drivers/clk/berlin/berlin2-avpll.c @@ -181,8 +181,8 @@ int __init berlin2_avpll_vco_register(void __iomem *base, const char *name, const char *parent_name, u8 vco_flags, unsigned long flags) { + struct clk_init_data init = {}; struct berlin2_avpll_vco *vco; - struct clk_init_data init; vco = kzalloc_obj(*vco); if (!vco) @@ -358,7 +358,7 @@ int __init berlin2_avpll_channel_register(void __iomem *base, u8 ch_flags, unsigned long flags) { struct berlin2_avpll_channel *ch; - struct clk_init_data init; + struct clk_init_data init = {}; ch = kzalloc_obj(*ch); if (!ch) diff --git a/drivers/clk/berlin/berlin2-pll.c b/drivers/clk/berlin/berlin2-pll.c index d0ec3d0bcf3e..1c4203736ecf 100644 --- a/drivers/clk/berlin/berlin2-pll.c +++ b/drivers/clk/berlin/berlin2-pll.c @@ -78,7 +78,7 @@ berlin2_pll_register(const struct berlin2_pll_map *map, void __iomem *base, const char *name, const char *parent_name, unsigned long flags) { - struct clk_init_data init; + struct clk_init_data init = {}; struct berlin2_pll *pll; pll = kzalloc_obj(*pll); diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 6fcee41447e4..e53256c56dfa 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -568,7 +568,7 @@ static int axi_clkgen_probe(struct platform_device *pdev) const struct axi_clkgen_limits *dflt_limits; struct axi_clkgen *axi_clkgen; unsigned int pcore_version; - struct clk_init_data init; + struct clk_init_data init = {}; const char *parent_names[2]; const char *clk_name; struct clk *axi_clk; diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c index 30d0493c7718..56b69d4fe4c2 100644 --- a/drivers/clk/clk-cdce925.c +++ b/drivers/clk/clk-cdce925.c @@ -620,12 +620,17 @@ static int cdce925_probe(struct i2c_client *client) struct device_node *node = client->dev.of_node; const char *parent_name; const char *pll_clk_name[MAX_NUMBER_OF_PLLS] = {NULL,}; - struct clk_init_data init; + struct clk_init_data init = {}; u32 value; int i; int err; struct device_node *np_output; - char child_name[6]; + /* + * The PLL number isn't a compile time constant so GCC can't infer + * the number. Make the stack buffer large enough to hold any int + * so Wformat-truncation does not complain. + */ + char child_name[15]; struct regmap_config config = { .name = "configuration0", .reg_bits = 8, @@ -697,7 +702,7 @@ static int cdce925_probe(struct i2c_client *client) dev_err(&client->dev, "Failed register PLL %d\n", i); goto error; } - sprintf(child_name, "PLL%d", i+1); + snprintf(child_name, sizeof(child_name), "PLL%d", i + 1); np_output = of_get_child_by_name(node, child_name); if (!np_output) continue; diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c index 550b8ae375a2..da66b9ae3de5 100644 --- a/drivers/clk/clk-conf.c +++ b/drivers/clk/clk-conf.c @@ -25,8 +25,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) node); for (index = 0; index < num_parents; index++) { - rc = of_parse_phandle_with_args(node, "assigned-clock-parents", - "#clock-cells", index, &clkspec); + rc = of_parse_phandle_with_args_map(node, "assigned-clock-parents", + "clock", index, &clkspec); if (rc < 0) { /* skip empty (null) phandles */ if (rc == -ENOENT) @@ -47,8 +47,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) return PTR_ERR(pclk); } - rc = of_parse_phandle_with_args(node, "assigned-clocks", - "#clock-cells", index, &clkspec); + rc = of_parse_phandle_with_args_map(node, "assigned-clocks", + "clock", index, &clkspec); if (rc < 0) goto err; if (clkspec.np == node && !clk_supplier) { @@ -121,8 +121,8 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier) rate = rates[index]; if (rate) { - rc = of_parse_phandle_with_args(node, "assigned-clocks", - "#clock-cells", index, &clkspec); + rc = of_parse_phandle_with_args_map(node, "assigned-clocks", + "clock", index, &clkspec); if (rc < 0) { /* skip empty (null) phandles */ if (rc == -ENOENT) diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c index e415bdff4d97..aa1823b3100e 100644 --- a/drivers/clk/clk-cs2000-cp.c +++ b/drivers/clk/clk-cs2000-cp.c @@ -461,7 +461,7 @@ static int cs2000_clk_register(struct cs2000_priv *priv) { struct device *dev = priv_to_dev(priv); struct device_node *np = dev->of_node; - struct clk_init_data init; + struct clk_init_data init = {}; const char *name = np->name; static const char *parent_names[CLK_MAX]; u32 aux_out = 0; diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index 5c45aacb6409..24fdec2e6198 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -6,14 +6,18 @@ #include #include #include +#include +#include #include #include #include +#include #include #include #include #include #include +#include #define RST_NR_PER_BANK 32 @@ -40,9 +44,22 @@ #define REG_HIR_MASK GENMASK(31, 16) /* EN7581 */ #define REG_NP_SCU_PCIC 0x88 +#define REG_NP_SCU_SSR3 0x94 +#define REG_SSUSB_HSGMII_SEL_MASK BIT(29) +#define REG_SSUSB_HSGMII_SEL_HSGMII FIELD_PREP_CONST(REG_SSUSB_HSGMII_SEL_MASK, 0x0) +#define REG_SSUSB_HSGMII_SEL_USB FIELD_PREP_CONST(REG_SSUSB_HSGMII_SEL_MASK, 0x1) #define REG_NP_SCU_SSTR 0x9c #define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13) +#define REG_PCIE_XSI0_SEL_PCIE FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, 0x0) +#define REG_PCIE_XSI0_SEL_XFI FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, 0x1) +#define REG_PCIE_XSI0_SEL_HSGMII FIELD_PREP_CONST(REG_PCIE_XSI0_SEL_MASK, 0x2) #define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11) +#define REG_PCIE_XSI1_SEL_PCIE FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, 0x0) +#define REG_PCIE_XSI1_SEL_XFI FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, 0x1) +#define REG_PCIE_XSI1_SEL_HSGMII FIELD_PREP_CONST(REG_PCIE_XSI1_SEL_MASK, 0x2) +#define REG_USB_PCIE_SEL_MASK BIT(3) +#define REG_USB_PCIE_SEL_PCIE FIELD_PREP_CONST(REG_USB_PCIE_SEL_MASK, 0x0) +#define REG_USB_PCIE_SEL_USB FIELD_PREP_CONST(REG_USB_PCIE_SEL_MASK, 0x1) #define REG_CRYPTO_CLKSRC2 0x20c /* EN751221 */ #define EN751221_REG_SPI_DIV 0x0cc @@ -82,6 +99,8 @@ enum en_hir { HIR_MAX = 14, }; +#define EN_SERDES_PHY_NUM 4 + struct en_clk_desc { int id; const char *name; @@ -114,6 +133,18 @@ struct en_rst_data { struct reset_controller_dev rcdev; }; +struct en_serdes_phy_instance { + struct phy *phy; + unsigned int serdes_port; +}; + +struct en_clk_priv { + void __iomem *base; + /* protect SCU register */ + spinlock_t lock; + struct en_serdes_phy_instance *serdes_phys[EN_SERDES_PHY_NUM]; +}; + struct en_clk_soc_data { u32 num_clocks; const struct clk_ops pcie_ops; @@ -847,12 +878,179 @@ static int en7581_reset_register(struct device *dev, void __iomem *base, return devm_reset_controller_register(dev, &rst_data->rcdev); } +static int en7581_serdes_phy_set_mode(struct phy *phy, enum phy_mode mode, + int submode) +{ + struct en_serdes_phy_instance *instance = phy_get_drvdata(phy); + struct en_clk_priv *priv = dev_get_drvdata(phy->dev.parent); + u32 reg, mask, sel, val; + unsigned long flags; + + switch (instance->serdes_port) { + case AIROHA_SCU_SERDES_PCIE1: + reg = REG_NP_SCU_SSTR; + mask = REG_PCIE_XSI0_SEL_MASK; + + if (mode != PHY_MODE_ETHERNET && mode != PHY_MODE_PCIE) + return -EINVAL; + + if (mode == PHY_MODE_ETHERNET) { + switch (submode) { + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + sel = REG_PCIE_XSI0_SEL_XFI; + break; + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: + sel = REG_PCIE_XSI0_SEL_HSGMII; + break; + default: + return -EINVAL; + } + } else { + sel = REG_PCIE_XSI0_SEL_PCIE; + } + + break; + case AIROHA_SCU_SERDES_PCIE2: + reg = REG_NP_SCU_SSTR; + mask = REG_PCIE_XSI1_SEL_MASK; + + if (mode != PHY_MODE_ETHERNET && mode != PHY_MODE_PCIE) + return -EINVAL; + + if (mode == PHY_MODE_ETHERNET) { + switch (submode) { + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + sel = REG_PCIE_XSI1_SEL_XFI; + break; + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: + sel = REG_PCIE_XSI1_SEL_HSGMII; + break; + default: + return -EINVAL; + } + } else { + sel = REG_PCIE_XSI1_SEL_PCIE; + } + + break; + case AIROHA_SCU_SERDES_USB1: + reg = REG_NP_SCU_SSR3; + mask = REG_SSUSB_HSGMII_SEL_MASK; + + if (mode != PHY_MODE_ETHERNET && mode != PHY_MODE_USB_DEVICE && + mode != PHY_MODE_USB_DEVICE_SS) + return -EINVAL; + + if (mode == PHY_MODE_ETHERNET) + sel = REG_SSUSB_HSGMII_SEL_HSGMII; + else + sel = REG_SSUSB_HSGMII_SEL_USB; + + break; + case AIROHA_SCU_SERDES_USB2: + reg = REG_NP_SCU_SSTR; + mask = REG_USB_PCIE_SEL_MASK; + + if (mode != PHY_MODE_PCIE && mode != PHY_MODE_USB_DEVICE && + mode != PHY_MODE_USB_DEVICE_SS) + return -EINVAL; + + if (mode == PHY_MODE_PCIE) + sel = REG_USB_PCIE_SEL_PCIE; + else + sel = REG_USB_PCIE_SEL_USB; + + break; + default: + return -EINVAL; + } + + spin_lock_irqsave(&priv->lock, flags); + val = readl(priv->base + reg); + val &= ~mask; + val |= sel; + writel(val, priv->base + reg); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static const struct phy_ops en7581_serdes_phy_ops = { + .set_mode = en7581_serdes_phy_set_mode, + .owner = THIS_MODULE, +}; + +static struct phy *en7581_serdes_phy_xlate(struct device *dev, + const struct of_phandle_args *args) +{ + struct en_clk_priv *priv = dev_get_drvdata(dev); + struct en_serdes_phy_instance *instance; + unsigned int serdes_port; + + if (args->args_count != 1) { + dev_err(dev, "invalid number of cells in 'phy' property\n"); + return ERR_PTR(-EINVAL); + } + + serdes_port = args->args[0]; + if (serdes_port >= EN_SERDES_PHY_NUM) { + dev_err(dev, "invalid serdes port: %d\n", serdes_port); + return ERR_PTR(-EINVAL); + } + + instance = priv->serdes_phys[serdes_port]; + if (!instance) { + dev_err(dev, "failed to find appropriate serdes phy\n"); + return ERR_PTR(-EINVAL); + } + + return instance->phy; +} + +static int en7581_serdes_phy_register(struct device *dev) +{ + struct en_clk_priv *priv = dev_get_drvdata(dev); + struct phy_provider *phy_provider; + int i; + + for (i = 0; i < EN_SERDES_PHY_NUM; i++) { + struct en_serdes_phy_instance *instance; + + instance = devm_kzalloc(dev, sizeof(*instance), + GFP_KERNEL); + if (!instance) + return -ENOMEM; + + instance->phy = devm_phy_create(dev, NULL, + &en7581_serdes_phy_ops); + if (IS_ERR(instance->phy)) + return dev_err_probe(dev, PTR_ERR(instance->phy), "failed to create phy\n"); + + instance->serdes_port = i; + priv->serdes_phys[i] = instance; + + phy_set_drvdata(instance->phy, instance); + } + + phy_provider = devm_of_phy_provider_register(dev, en7581_serdes_phy_xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + static int en7581_clk_hw_init(struct platform_device *pdev, struct clk_hw_onecell_data *clk_data) { + struct en_clk_priv *priv = platform_get_drvdata(pdev); struct regmap *map; void __iomem *base; u32 val; + int ret; map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); if (IS_ERR(map)) @@ -862,6 +1060,8 @@ static int en7581_clk_hw_init(struct platform_device *pdev, if (IS_ERR(base)) return PTR_ERR(base); + priv->base = base; + en7581_register_clocks(&pdev->dev, clk_data, map, base); val = readl(base + REG_NP_SCU_SSTR); @@ -876,9 +1076,12 @@ static int en7581_clk_hw_init(struct platform_device *pdev, 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); + ret = en7581_reset_register(&pdev->dev, base, en7581_rst_map, + ARRAY_SIZE(en7581_rst_map), en7581_rst_ofs); + if (ret) + return ret; + + return en7581_serdes_phy_register(&pdev->dev); } static enum en_hir get_hw_id(void __iomem *np_base) @@ -985,16 +1188,25 @@ static int en7523_clk_probe(struct platform_device *pdev) struct device_node *node = pdev->dev.of_node; const struct en_clk_soc_data *soc_data; struct clk_hw_onecell_data *clk_data; + struct en_clk_priv *priv; int r; soc_data = device_get_match_data(&pdev->dev); + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + spin_lock_init(&priv->lock); + clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws, soc_data->num_clocks), GFP_KERNEL); if (!clk_data) return -ENOMEM; + platform_set_drvdata(pdev, priv); + clk_data->num = soc_data->num_clocks; r = soc_data->hw_init(pdev, clk_data); if (r) diff --git a/drivers/clk/clk-eyeq.c b/drivers/clk/clk-eyeq.c index cf37feccc734..ae0faee31689 100644 --- a/drivers/clk/clk-eyeq.c +++ b/drivers/clk/clk-eyeq.c @@ -513,21 +513,16 @@ static int eqc_probe(struct platform_device *pdev) const struct eqc_match_data *data; struct clk_hw_onecell_data *cells; unsigned int i, clk_count; - struct resource *res; void __iomem *base; int ret; + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + data = device_get_match_data(dev); if (!data) - return 0; /* No clocks nor auxdevs, we are done. */ - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - base = ioremap(res->start, resource_size(res)); - if (!base) - return -ENOMEM; + return 0; /* No clocks nor auxdevs, stop here but keep resource reserved */ /* Init optional auxiliary devices. */ eqc_auxdev_create_optional(dev, base, data->reset_auxdev_name); @@ -559,7 +554,20 @@ static int eqc_probe(struct platform_device *pdev) 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); + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, cells); + if (ret) { + for (i = 0; i < data->clk_count; i++) { + const struct eqc_clock *clk = &data->clks[i]; + struct clk_hw *hw = cells->hws[clk->index]; + + if (!IS_ERR_OR_NULL(hw) && clk->unregister) + clk->unregister(hw); + } + + kfree(cells); + } + + return ret; } #define DIV(_index, _parent_idx, _name, _parent_name, \ @@ -1175,6 +1183,7 @@ 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 }, { .compatible = "mobileye,eyeq6lplus-olb", .data = &eqc_eyeq6lplus_match_data }, + { .compatible = "mobileye,eyeq6h-central-olb" /* no data, early only */ }, { .compatible = "mobileye,eyeq6h-west-olb", .data = &eqc_eyeq6h_west_match_data }, { .compatible = "mobileye,eyeq6h-east-olb", .data = &eqc_eyeq6h_east_match_data }, { .compatible = "mobileye,eyeq6h-south-olb", .data = &eqc_eyeq6h_south_match_data }, diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index 1c5fdcb68a50..c8e00d75cd14 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c @@ -271,7 +271,7 @@ struct clk_hw *clk_hw_register_fractional_divider(struct device *dev, u8 clk_divider_flags, spinlock_t *lock) { struct clk_fractional_divider *fd; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_hw *hw; int ret; diff --git a/drivers/clk/clk-gemini.c b/drivers/clk/clk-gemini.c index 9c0e6e7a7cac..4e874392e3b0 100644 --- a/drivers/clk/clk-gemini.c +++ b/drivers/clk/clk-gemini.c @@ -193,8 +193,8 @@ static struct clk_hw *gemini_pci_clk_setup(const char *name, const char *parent_name, struct regmap *map) { + struct clk_init_data init = {}; struct clk_gemini_pci *pciclk; - struct clk_init_data init; int ret; pciclk = kzalloc_obj(*pciclk); diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 9099c57e2715..918b2c6444ee 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -214,7 +214,7 @@ static int gpio_clk_driver_probe(struct platform_device *pdev) gpiod = devm_gpiod_get(dev, gpio_name, GPIOD_OUT_LOW); if (IS_ERR(gpiod)) return dev_err_probe(dev, PTR_ERR(gpiod), - "Can't get '%s' named GPIO property\n", gpio_name); + "Can't get '%s' GPIO\n", gpio_name); if (is_mux) hw = clk_hw_register_gpio_mux(dev, gpiod); diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c index e9b177811dfc..61c231997635 100644 --- a/drivers/clk/clk-highbank.c +++ b/drivers/clk/clk-highbank.c @@ -269,7 +269,7 @@ static void __init hb_clk_init(struct device_node *node, const struct clk_ops *o struct hb_clk *hb_clk; const char *clk_name = node->name; const char *parent_name; - struct clk_init_data init; + struct clk_init_data init = {}; struct device_node *srnp; int rc; diff --git a/drivers/clk/clk-lmk04832.c b/drivers/clk/clk-lmk04832.c index f9a0684d2628..755f9837c53a 100644 --- a/drivers/clk/clk-lmk04832.c +++ b/drivers/clk/clk-lmk04832.c @@ -587,8 +587,8 @@ static const struct clk_ops lmk04832_vco_ops = { */ static int lmk04832_register_vco(struct lmk04832 *lmk) { + struct clk_init_data init = {}; const char *parent_names[1]; - struct clk_init_data init; int ret; init.name = "lmk-vco"; @@ -947,8 +947,8 @@ static const struct clk_ops lmk04832_sclk_ops = { static int lmk04832_register_sclk(struct lmk04832 *lmk) { + struct clk_init_data init = {}; const char *parent_names[1]; - struct clk_init_data init; int ret; init.name = "lmk-sclk"; @@ -1292,8 +1292,8 @@ static int lmk04832_register_clkout(struct lmk04832 *lmk, const int num) { char name[] = "lmk-clkoutXX"; char dclk_name[] = "lmk-dclkXX_YY"; + struct clk_init_data init = {}; const char *parent_names[2]; - struct clk_init_data init; int dclk_num = num / 2; int ret; @@ -1410,6 +1410,9 @@ static int lmk04832_probe(struct spi_device *spi) lmk->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(lmk->reset_gpio)) + return dev_err_probe(lmk->dev, PTR_ERR(lmk->reset_gpio), + "failed to get reset GPIO\n"); lmk->dclk = devm_kcalloc(lmk->dev, info->num_channels >> 1, sizeof(struct lmk_dclk), GFP_KERNEL); diff --git a/drivers/clk/clk-milbeaut.c b/drivers/clk/clk-milbeaut.c index 4265bc442dfd..29c1e5f68c7a 100644 --- a/drivers/clk/clk-milbeaut.c +++ b/drivers/clk/clk-milbeaut.c @@ -328,9 +328,9 @@ static struct clk_hw *m10v_clk_hw_register_mux(struct device *dev, u8 shift, u32 mask, u8 clk_mux_flags, u32 *table, spinlock_t *lock) { + struct clk_init_data init = {}; struct clk_mux *mux; struct clk_hw *hw; - struct clk_init_data init; int ret; mux = kzalloc_obj(*mux); @@ -410,8 +410,8 @@ static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct m10v_clk_divider *divider = to_m10v_div(hw); - int value; unsigned long flags = 0; + int value, ret = 0; u32 val; u32 write_en = BIT(divider->width - 1); @@ -433,8 +433,10 @@ static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, if (divider->write_valid_reg) { writel(M10V_DCHREQ, divider->write_valid_reg); - if (readl_poll_timeout(divider->write_valid_reg, val, - !val, M10V_UPOLL_RATE, M10V_UTIMEOUT)) + ret = readl_poll_timeout_atomic(divider->write_valid_reg, val, + !val, M10V_UPOLL_RATE, + M10V_UTIMEOUT); + if (ret) pr_err("%s:%s couldn't stabilize\n", __func__, clk_hw_get_name(hw)); } @@ -444,7 +446,7 @@ static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, else __release(divider->lock); - return 0; + return ret; } static const struct clk_ops m10v_clk_divider_ops = { @@ -459,9 +461,9 @@ static struct clk_hw *m10v_clk_hw_register_divider(struct device *dev, u8 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock, void __iomem *write_valid_reg) { + struct clk_init_data init = {}; struct m10v_clk_divider *div; struct clk_hw *hw; - struct clk_init_data init; int ret; div = kzalloc_obj(*div); diff --git a/drivers/clk/clk-nomadik.c b/drivers/clk/clk-nomadik.c index da6b89759a14..890084b3912b 100644 --- a/drivers/clk/clk-nomadik.c +++ b/drivers/clk/clk-nomadik.c @@ -263,7 +263,7 @@ pll_clk_register(struct device *dev, const char *name, { int ret; struct clk_pll *pll; - struct clk_init_data init; + struct clk_init_data init = {}; if (id != 1 && id != 2) { pr_err("%s: the Nomadik has only PLL 1 & 2\n", __func__); @@ -355,7 +355,7 @@ src_clk_register(struct device *dev, const char *name, { int ret; struct clk_src *sclk; - struct clk_init_data init; + struct clk_init_data init = {}; sclk = kzalloc_obj(*sclk); if (!sclk) diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c index 79eca6ee3120..562d2d406d7a 100644 --- a/drivers/clk/clk-npcm7xx.c +++ b/drivers/clk/clk-npcm7xx.c @@ -69,8 +69,8 @@ static struct clk_hw * npcm7xx_clk_register_pll(void __iomem *pllcon, const char *name, const char *parent_name, unsigned long flags) { + struct clk_init_data init = {}; struct npcm7xx_clk_pll *pll; - struct clk_init_data init; struct clk_hw *hw; int ret; diff --git a/drivers/clk/clk-pwm.c b/drivers/clk/clk-pwm.c index 4709f0338e37..2001c7c9367c 100644 --- a/drivers/clk/clk-pwm.c +++ b/drivers/clk/clk-pwm.c @@ -95,7 +95,7 @@ static const struct clk_ops clk_pwm_ops = { static int clk_pwm_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_pwm *clk_pwm; struct pwm_device *pwm; struct pwm_args pargs; diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c index 564550c80389..864bf89cecd0 100644 --- a/drivers/clk/clk-renesas-pcie.c +++ b/drivers/clk/clk-renesas-pcie.c @@ -63,10 +63,11 @@ struct rs9_driver_data { struct i2c_client *client; struct regmap *regmap; const struct rs9_chip_info *chip_info; - struct clk_hw *clk_dif[8]; u8 pll_amplitude; u8 pll_ssc; u8 clk_dif_sr; + /* must be last */ + struct clk_hw_onecell_data onecell; }; /* @@ -270,32 +271,28 @@ static void rs9_update_config(struct rs9_driver_data *rs9) } } -static struct clk_hw * -rs9_of_clk_get(struct of_phandle_args *clkspec, void *data) -{ - struct rs9_driver_data *rs9 = data; - unsigned int idx = clkspec->args[0]; - - return rs9->clk_dif[idx]; -} - static int rs9_probe(struct i2c_client *client) { + const struct rs9_chip_info *chip_info; unsigned char name[5] = "DIF0"; struct rs9_driver_data *rs9; unsigned int vid, did; struct clk_hw *hw; int i, ret; - rs9 = devm_kzalloc(&client->dev, sizeof(*rs9), GFP_KERNEL); + chip_info = i2c_get_match_data(client); + if (!chip_info) + return -EINVAL; + + rs9 = devm_kzalloc(&client->dev, struct_size(rs9, onecell.hws, + chip_info->num_clks), GFP_KERNEL); if (!rs9) return -ENOMEM; i2c_set_clientdata(client, rs9); rs9->client = client; - rs9->chip_info = i2c_get_match_data(client); - if (!rs9->chip_info) - return -EINVAL; + rs9->chip_info = chip_info; + rs9->onecell.num = chip_info->num_clks; /* Fetch common configuration from DT (if specified) */ ret = rs9_get_common_config(rs9); @@ -303,7 +300,7 @@ static int rs9_probe(struct i2c_client *client) return ret; /* Fetch DIFx output configuration from DT (if specified) */ - for (i = 0; i < rs9->chip_info->num_clks; i++) { + for (i = 0; i < rs9->onecell.num; i++) { ret = rs9_get_output_config(rs9, i); if (ret) return ret; @@ -329,24 +326,24 @@ static int rs9_probe(struct i2c_client *client) return ret; vid &= RS9_REG_VID_MASK; - if (vid != RS9_REG_VID_IDT || did != rs9->chip_info->did) + if (vid != RS9_REG_VID_IDT || did != chip_info->did) return dev_err_probe(&client->dev, -ENODEV, "Incorrect VID/DID: %#02x, %#02x. Expected %#02x, %#02x\n", - vid, did, RS9_REG_VID_IDT, - rs9->chip_info->did); + vid, did, RS9_REG_VID_IDT, chip_info->did); /* Register clock */ - for (i = 0; i < rs9->chip_info->num_clks; i++) { + for (i = 0; i < rs9->onecell.num; i++) { snprintf(name, 5, "DIF%d", i); hw = devm_clk_hw_register_fixed_factor_index(&client->dev, name, 0, 0, 4, 1); if (IS_ERR(hw)) return PTR_ERR(hw); - rs9->clk_dif[i] = hw; + rs9->onecell.hws[i] = hw; } - ret = devm_of_clk_add_hw_provider(&client->dev, rs9_of_clk_get, rs9); + ret = devm_of_clk_add_hw_provider(&client->dev, of_clk_hw_onecell_get, + &rs9->onecell); if (!ret) rs9_update_config(rs9); @@ -370,8 +367,10 @@ static int rs9_resume(struct device *dev) regcache_cache_only(rs9->regmap, false); ret = regcache_sync(rs9->regmap); - if (ret) + if (ret) { + regcache_cache_only(rs9->regmap, true); dev_err(dev, "Failed to restore register map: %d\n", ret); + } return ret; } diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index fa5ac8f673f6..94969d97d6e9 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -192,8 +192,10 @@ static int s2mps11_clk_probe(struct platform_device *pdev) clk_data->hws[i] = &s2mps11_clks[i].hw; } - of_clk_add_hw_provider(s2mps11_clks->clk_np, of_clk_hw_onecell_get, - clk_data); + ret = of_clk_add_hw_provider(s2mps11_clks->clk_np, + of_clk_hw_onecell_get, clk_data); + if (ret) + goto err_reg; platform_set_drvdata(pdev, s2mps11_clks); @@ -201,8 +203,10 @@ static int s2mps11_clk_probe(struct platform_device *pdev) err_reg: of_node_put(s2mps11_clks[0].clk_np); - while (--i >= 0) - clkdev_drop(s2mps11_clks[i].lookup); + while (--i >= 0) { + if (s2mps11_clks[i].lookup) + clkdev_drop(s2mps11_clks[i].lookup); + } return ret; } diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index b2d412ca1d22..e2eec7be5c19 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -128,7 +128,7 @@ static int scpi_clk_ops_init(struct device *dev, const struct of_device_id *match, struct scpi_clk *sclk, const char *name) { - struct clk_init_data init; + struct clk_init_data init = {}; unsigned long min = 0, max = 0; int ret; diff --git a/drivers/clk/clk-si514.c b/drivers/clk/clk-si514.c index c0b433ad9372..07091b91420d 100644 --- a/drivers/clk/clk-si514.c +++ b/drivers/clk/clk-si514.c @@ -337,8 +337,8 @@ static const struct regmap_config si514_regmap_config = { static int si514_probe(struct i2c_client *client) { + struct clk_init_data init = {}; struct clk_si514 *data; - struct clk_init_data init; int err; data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); diff --git a/drivers/clk/clk-si521xx.c b/drivers/clk/clk-si521xx.c index e3fb8df712ef..84dc3621df93 100644 --- a/drivers/clk/clk-si521xx.c +++ b/drivers/clk/clk-si521xx.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -255,18 +256,24 @@ static void si521xx_diff_idx_to_reg_bit(const u16 chip_info, const int idx, struct si_clk *clk) { unsigned long mask; - int oe, b, ctr = 0; + unsigned int bit; + int oe = 1; - for (oe = 1; oe <= 2; oe++) { - mask = bitrev8(SI521XX_OE_MAP_GET_OE(oe, chip_info)); - for_each_set_bit(b, &mask, 8) { - if (ctr++ != idx) - continue; - clk->reg = SI521XX_REG_OE(oe); - clk->bit = 7 - b; - return; - } - } + mask = bitrev8(SI521XX_OE_MAP_GET_OE(1, chip_info)); + bit = fns(mask, idx); + if (bit < 8) + goto out; + + oe = 2; + bit = idx - hweight8(mask); + mask = bitrev8(SI521XX_OE_MAP_GET_OE(2, chip_info)); + bit = fns(mask, bit); + if (bit >= 8) + return; + +out: + clk->reg = SI521XX_REG_OE(oe); + clk->bit = 7 - bit; } static struct clk_hw * @@ -341,7 +348,7 @@ static int si521xx_probe(struct i2c_client *client) return ret; } -static int __maybe_unused si521xx_suspend(struct device *dev) +static int si521xx_suspend(struct device *dev) { struct si521xx *si = dev_get_drvdata(dev); @@ -351,15 +358,17 @@ static int __maybe_unused si521xx_suspend(struct device *dev) return 0; } -static int __maybe_unused si521xx_resume(struct device *dev) +static int si521xx_resume(struct device *dev) { struct si521xx *si = dev_get_drvdata(dev); int ret; regcache_cache_only(si->regmap, false); ret = regcache_sync(si->regmap); - if (ret) + if (ret) { + regcache_cache_only(si->regmap, true); dev_err(dev, "Failed to restore register map: %d\n", ret); + } return ret; } @@ -374,17 +383,17 @@ MODULE_DEVICE_TABLE(i2c, si521xx_id); static const struct of_device_id clk_si521xx_of_match[] = { { .compatible = "skyworks,si52144", .data = (void *)SI521XX_OE_MAP(0x5, 0xc0) }, { .compatible = "skyworks,si52146", .data = (void *)SI521XX_OE_MAP(0x15, 0xe0) }, - { .compatible = "skyworks,si52147", .data = (void *)SI521XX_OE_MAP(0x15, 0xf8) }, + { .compatible = "skyworks,si52147", .data = (void *)SI521XX_OE_MAP(0x17, 0xf8) }, { } }; MODULE_DEVICE_TABLE(of, clk_si521xx_of_match); -static SIMPLE_DEV_PM_OPS(si521xx_pm_ops, si521xx_suspend, si521xx_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(si521xx_pm_ops, si521xx_suspend, si521xx_resume); static struct i2c_driver si521xx_driver = { .driver = { .name = "clk-si521xx", - .pm = &si521xx_pm_ops, + .pm = pm_sleep_ptr(&si521xx_pm_ops), .of_match_table = clk_si521xx_of_match, }, .probe = si521xx_probe, diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 5311c23532b4..88522333525b 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -1556,8 +1556,8 @@ static const struct attribute *si5341_attributes[] = { static int si5341_probe(struct i2c_client *client) { + struct clk_init_data init = {}; struct clk_si5341 *data; - struct clk_init_data init; struct clk *input; const char *root_clock_name; const char *synth_clock_names[SI5341_NUM_SYNTH] = { NULL }; diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 20b0c3c48b86..70daba62305c 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -907,7 +907,7 @@ static int _si5351_clkout_set_disable_state( return 0; } -static void _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num) +static int _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num) { u8 val = si5351_reg_read(drvdata, SI5351_CLK0_CTRL + num); u8 mask = val & SI5351_CLK_PLL_SELECT ? SI5351_PLL_RESET_B : @@ -918,7 +918,7 @@ static void _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num switch (val & SI5351_CLK_INPUT_MASK) { case SI5351_CLK_INPUT_XTAL: case SI5351_CLK_INPUT_CLKIN: - return; /* pll not used, no need to reset */ + return 0; /* pll not used, no need to reset */ } si5351_reg_write(drvdata, SI5351_PLL_RESET, mask); @@ -931,6 +931,8 @@ static void _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num dev_dbg(&drvdata->client->dev, "%s - %s: pll = %d\n", __func__, clk_hw_get_name(&drvdata->clkout[num].hw), (val & SI5351_CLK_PLL_SELECT) ? 1 : 0); + + return err; } static int si5351_clkout_prepare(struct clk_hw *hw) @@ -947,8 +949,18 @@ static int si5351_clkout_prepare(struct clk_hw *hw) * Do a pll soft reset on the parent pll -- needed to get a * deterministic phase relationship between the output clocks. */ - if (pdata->clkout[hwdata->num].pll_reset) - _si5351_clkout_reset_pll(hwdata->drvdata, hwdata->num); + if (pdata->clkout[hwdata->num].pll_reset) { + int ret; + + ret = _si5351_clkout_reset_pll(hwdata->drvdata, hwdata->num); + if (ret) { + si5351_set_bits(hwdata->drvdata, + SI5351_CLK0_CTRL + hwdata->num, + SI5351_CLK_POWERDOWN, + SI5351_CLK_POWERDOWN); + return ret; + } + } si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL, (1 << hwdata->num), 0); diff --git a/drivers/clk/clk-si544.c b/drivers/clk/clk-si544.c index 9c520128e0a2..3924ec3e2163 100644 --- a/drivers/clk/clk-si544.c +++ b/drivers/clk/clk-si544.c @@ -445,8 +445,8 @@ static const struct regmap_config si544_regmap_config = { static int si544_probe(struct i2c_client *client) { + struct clk_init_data init = {}; struct clk_si544 *data; - struct clk_init_data init; int err; data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); diff --git a/drivers/clk/clk-si570.c b/drivers/clk/clk-si570.c index 3063e38c66da..ac9013e7379c 100644 --- a/drivers/clk/clk-si570.c +++ b/drivers/clk/clk-si570.c @@ -412,7 +412,7 @@ static const struct regmap_config si570_regmap_config = { static int si570_probe(struct i2c_client *client) { struct clk_si570 *data; - struct clk_init_data init; + struct clk_init_data init = {}; u32 initial_fout, factory_fout, stability; bool skip_recall; int err; diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 565b4d99bebb..6603d4815514 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -485,8 +485,8 @@ static struct clk *clk_register_apb_mul(struct device *dev, const char *name, const char *parent_name, unsigned long flags, u8 bit_idx) { + struct clk_init_data init = {}; struct clk_apb_mul *am; - struct clk_init_data init; struct clk *clk; am = kzalloc_obj(*am); @@ -810,8 +810,8 @@ static struct clk_hw *clk_register_pll_div(const char *name, struct clk_hw *pll_hw, spinlock_t *lock) { struct stm32f4_pll_div *pll_div; + struct clk_init_data init = {}; struct clk_hw *hw; - struct clk_init_data init; int ret; /* allocate the divider */ diff --git a/drivers/clk/clk-stm32h7.c b/drivers/clk/clk-stm32h7.c index 82e0789cf189..c6afa9b20235 100644 --- a/drivers/clk/clk-stm32h7.c +++ b/drivers/clk/clk-stm32h7.c @@ -462,8 +462,8 @@ static struct clk_hw *clk_register_stm32_timer_ker(struct device *dev, u8 dppre_shift, spinlock_t *lock) { + struct clk_init_data init = {}; struct timer_ker *element; - struct clk_init_data init; struct clk_hw *hw; int err; diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index b51148920216..d91749be785c 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -1223,7 +1223,7 @@ static void vc5_remove(struct i2c_client *client) clk_unregister_fixed_rate(vc5->pin_xin); } -static int __maybe_unused vc5_suspend(struct device *dev) +static int vc5_suspend(struct device *dev) { struct vc5_driver_data *vc5 = dev_get_drvdata(dev); @@ -1233,15 +1233,17 @@ static int __maybe_unused vc5_suspend(struct device *dev) return 0; } -static int __maybe_unused vc5_resume(struct device *dev) +static int vc5_resume(struct device *dev) { struct vc5_driver_data *vc5 = dev_get_drvdata(dev); int ret; regcache_cache_only(vc5->regmap, false); ret = regcache_sync(vc5->regmap); - if (ret) + if (ret) { + regcache_cache_only(vc5->regmap, true); dev_err(dev, "Failed to restore register map: %d\n", ret); + } return ret; } @@ -1335,12 +1337,12 @@ static const struct of_device_id clk_vc5_of_match[] = { }; MODULE_DEVICE_TABLE(of, clk_vc5_of_match); -static SIMPLE_DEV_PM_OPS(vc5_pm_ops, vc5_suspend, vc5_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(vc5_pm_ops, vc5_suspend, vc5_resume); static struct i2c_driver vc5_driver = { .driver = { .name = "vc5", - .pm = &vc5_pm_ops, + .pm = pm_sleep_ptr(&vc5_pm_ops), .of_match_table = clk_vc5_of_match, }, .probe = vc5_probe, diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index 3e62cb853d5e..581ac00c31bc 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -227,8 +227,8 @@ static __init void vtwm_device_clk_init(struct device_node *node) struct clk_hw *hw; struct clk_device *dev_clk; const char *clk_name = node->name; + struct clk_init_data init = {}; const char *parent_name; - struct clk_init_data init; int rc; int clk_init_flags = 0; @@ -687,8 +687,8 @@ static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type) struct clk_hw *hw; struct clk_pll *pll_clk; const char *clk_name = node->name; + struct clk_init_data init = {}; const char *parent_name; - struct clk_init_data init; int rc; if (!pmc_base) diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c index abb6c8fcdc91..2029962ae5aa 100644 --- a/drivers/clk/clk-xgene.c +++ b/drivers/clk/clk-xgene.c @@ -126,9 +126,9 @@ static struct clk *xgene_register_clk_pll(struct device *dev, unsigned long flags, void __iomem *reg, u32 pll_offset, u32 type, spinlock_t *lock, int version) { + struct clk_init_data init = {}; struct xgene_clk_pll *apmclk; struct clk *clk; - struct clk_init_data init; /* allocate the APM clock structure */ apmclk = kzalloc_obj(*apmclk); @@ -350,8 +350,8 @@ xgene_register_clk_pmd(struct device *dev, unsigned long flags, void __iomem *reg, u8 shift, u8 width, u64 denom, u32 clk_flags, spinlock_t *lock) { + struct clk_init_data init = {}; struct xgene_clk_pmd *fd; - struct clk_init_data init; struct clk *clk; fd = kzalloc_obj(*fd); @@ -634,9 +634,9 @@ static struct clk *xgene_register_clk(struct device *dev, const char *name, const char *parent_name, struct xgene_dev_parameters *parameters, spinlock_t *lock) { + struct clk_init_data init = {}; struct xgene_clk *apmclk; struct clk *clk; - struct clk_init_data init; int rc; /* allocate the APM clock structure */ diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index fef87167a60b..4d2cc86bfbeb 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "clk.h" @@ -166,6 +167,7 @@ struct clk { unsigned long max_rate; unsigned int exclusive_count; struct hlist_node clks_node; + bool pinning; }; /*** runtime pm ***/ @@ -2851,6 +2853,20 @@ int clk_hw_set_spread_spectrum(struct clk_hw *hw, const struct clk_spread_spectr if (!hw) return 0; + switch (ss_conf->method) { + case CLK_SPREAD_NO: + break; + case CLK_SPREAD_CENTER: + case CLK_SPREAD_UP: + case CLK_SPREAD_DOWN: + if (!ss_conf->modfreq_hz || !ss_conf->spread_bp || + ss_conf->spread_bp > 10000) + return -EINVAL; + break; + default: + return -EINVAL; + } + core = hw->core; clk_prepare_lock(); @@ -4237,13 +4253,15 @@ static void free_clk(struct clk *clk) * @hw: clk_hw associated with the clk being consumed * @dev_id: string describing device name * @con_id: connection ID string on device + * @owner: reference to the module creating the clock * * This is the main function used to create a clk pointer for use by clk * consumers. It connects a consumer to the clk_core and clk_hw structures * used by the framework and clk provider respectively. */ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, - const char *dev_id, const char *con_id) + const char *dev_id, const char *con_id, + struct module *owner) { struct clk *clk; struct clk_core *core; @@ -4258,7 +4276,13 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, return clk; clk->dev = dev; - if (!try_module_get(core->owner)) { + /* + * Pin the provider module only when the consumer lives in a different + * module. A provider getting a clk from its own clk_hw would otherwise + * pin itself and could never be unloaded. + */ + clk->pinning = owner != core->owner; + if (clk->pinning && !try_module_get(core->owner)) { free_clk(clk); return ERR_PTR(-ENOENT); } @@ -4269,24 +4293,19 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, return clk; } -/** - * clk_hw_get_clk - get clk consumer given an clk_hw - * @hw: clk_hw associated with the clk being consumed - * @con_id: connection ID string on device - * - * Returns: new clk consumer - * This is the function to be used by providers which need - * to get a consumer clk and act on the clock element - * Calls to this function must be balanced with calls clk_put() +/* + * Internal helper backing the clk_hw_get_clk() macro, which passes the caller's + * module via THIS_MODULE. */ -struct clk *clk_hw_get_clk(struct clk_hw *hw, const char *con_id) +struct clk *__clk_hw_get_clk(struct clk_hw *hw, const char *con_id, + struct module *owner) { struct device *dev = hw->core->dev; const char *name = dev ? dev_name(dev) : NULL; - return clk_hw_create_clk(dev, hw, name, con_id); + return clk_hw_create_clk(dev, hw, name, con_id, owner); } -EXPORT_SYMBOL(clk_hw_get_clk); +EXPORT_SYMBOL(__clk_hw_get_clk); static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist) { @@ -4450,8 +4469,9 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) INIT_HLIST_HEAD(&core->clks); /* - * Don't call clk_hw_create_clk() here because that would pin the - * provider module to itself and prevent it from ever being removed. + * Don't call clk_hw_create_clk() here because it would systematically + * add a consumer to the hw clock and all clocks would appear to have + * consumer in the clock summary. */ hw->clk = alloc_clk(core, NULL, NULL); if (IS_ERR(hw->clk)) { @@ -4808,7 +4828,7 @@ struct clk *devm_clk_hw_get_clk(struct device *dev, struct clk_hw *hw, if (!clkp) return ERR_PTR(-ENOMEM); - clk = clk_hw_get_clk(hw, con_id); + clk = __clk_hw_get_clk(hw, con_id, dev->driver->owner); if (!IS_ERR(clk)) { *clkp = clk; devres_add(dev, clkp); @@ -4855,7 +4875,8 @@ void __clk_put(struct clk *clk) owner = clk->core->owner; kref_put(&clk->core->ref, __clk_release); - module_put(owner); + if (clk->pinning) + module_put(owner); free_clk(clk); } @@ -5297,13 +5318,13 @@ static int of_parse_clkspec(const struct device_node *np, int index, /* * For named clocks, first look up the name in the * "clock-names" property. If it cannot be found, then index - * will be an error code and of_parse_phandle_with_args() will + * will be an error code and the OF phandle parser will * return -EINVAL. */ if (name) index = of_property_match_string(np, "clock-names", name); - ret = of_parse_phandle_with_args(np, "clocks", "#clock-cells", - index, out_args); + ret = of_parse_phandle_with_args_map(np, "clocks", "clock", + index, out_args); if (!ret) break; if (name && index >= 0) @@ -5314,6 +5335,8 @@ static int of_parse_clkspec(const struct device_node *np, int index, * has a "clock-ranges" property, then we can try one of its * clocks. */ + if (of_property_present(np, "clocks")) + break; np = np->parent; if (np && !of_property_present(np, "clock-ranges")) break; @@ -5370,13 +5393,13 @@ of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec) * * This function looks up a struct clk from the registered list of clock * providers, an input is a clock specifier data structure as returned - * from the of_parse_phandle_with_args() function call. + * from the OF phandle parser. */ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) { struct clk_hw *hw = of_clk_get_hw_from_clkspec(clkspec); - return clk_hw_create_clk(NULL, hw, NULL, __func__); + return clk_hw_create_clk(NULL, hw, NULL, __func__, NULL); } EXPORT_SYMBOL_GPL(of_clk_get_from_provider); @@ -5396,6 +5419,7 @@ struct clk_hw *of_clk_get_hw(struct device_node *np, int index, return hw; } +EXPORT_SYMBOL_IF_KUNIT(of_clk_get_hw); static struct clk *__of_clk_get(struct device_node *np, int index, const char *dev_id, @@ -5403,7 +5427,7 @@ static struct clk *__of_clk_get(struct device_node *np, { struct clk_hw *hw = of_clk_get_hw(np, index, con_id); - return clk_hw_create_clk(NULL, hw, dev_id, con_id); + return clk_hw_create_clk(NULL, hw, dev_id, con_id, NULL); } struct clk *of_clk_get(struct device_node *np, int index) @@ -5458,8 +5482,7 @@ const char *of_clk_get_parent_name(const struct device_node *np, int index) int count; struct clk *clk; - rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index, - &clkspec); + rc = of_parse_clkspec(np, index, NULL, &clkspec); if (rc) return NULL; diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 2d801900cad5..5009380863a9 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -23,13 +23,14 @@ struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id); #ifdef CONFIG_COMMON_CLK struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, - const char *dev_id, const char *con_id); + const char *dev_id, const char *con_id, + struct module *owner); void __clk_put(struct clk *clk); #else /* All these casts to avoid ifdefs in clkdev... */ static inline struct clk * clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id, - const char *con_id) + const char *con_id, struct module *owner) { return (struct clk *)hw; } diff --git a/drivers/clk/clk_kunit_helpers.c b/drivers/clk/clk_kunit_helpers.c index 68a28e70bb61..ab6b2cffcad6 100644 --- a/drivers/clk/clk_kunit_helpers.c +++ b/drivers/clk/clk_kunit_helpers.c @@ -233,5 +233,36 @@ int of_clk_add_hw_provider_kunit(struct kunit *test, struct device_node *np, } EXPORT_SYMBOL_GPL(of_clk_add_hw_provider_kunit); +KUNIT_DEFINE_ACTION_WRAPPER(of_node_put_wrapper, of_node_put, struct device_node *); + +/** + * clk_of_find_node_by_name_kunit() - Test managed of_find_node_by_name() + * @test: The test context + * @from: Parent device node to start searching from, or NULL to search from root + * @name: The name string to match against + * + * Just like of_find_node_by_name(), except the device_node is managed by + * the test case and is automatically put after the test case concludes. + * + * Return: the device_node on success, NULL if not found, or an error pointer on failure. + */ +struct device_node *clk_of_find_node_by_name_kunit(struct kunit *test, struct device_node *from, + const char *name) +{ + struct device_node *np; + int ret; + + np = of_find_node_by_name(from, name); + if (!np) + return NULL; + + ret = kunit_add_action_or_reset(test, of_node_put_wrapper, np); + if (ret) + return ERR_PTR(ret); + + return np; +} +EXPORT_SYMBOL_GPL(clk_of_find_node_by_name_kunit); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("KUnit helpers for clk providers and consumers"); diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c index 1c5c8b7c1f3c..0505ed357b20 100644 --- a/drivers/clk/clk_test.c +++ b/drivers/clk/clk_test.c @@ -3526,7 +3526,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p */ .desc = "provider missing assigned-clocks", TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_without), - .sscs = {50000, 60000, 3}, + .sscs = {50000, 600, 3}, }, { /* @@ -3535,7 +3535,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p */ .desc = "consumer missing assigned-clocks", TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_without_consumer), - .sscs = {50000, 60000, 3}, + .sscs = {50000, 600, 3}, .consumer_test = true, }, { @@ -3545,7 +3545,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p */ .desc = "provider assigned-clock-sscs of zero", TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_zero), - .sscs = {50000, 60000, 3}, + .sscs = {50000, 600, 3}, }, { /* @@ -3554,7 +3554,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p */ .desc = "consumer assigned-clock-sscs of zero", TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_zero_consumer), - .sscs = {50000, 60000, 3}, + .sscs = {50000, 600, 3}, .consumer_test = true, }, { @@ -3564,7 +3564,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p */ .desc = "provider assigned-clocks null phandle", TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_null), - .sscs = {50000, 60000, 3}, + .sscs = {50000, 600, 3}, }, { /* @@ -3573,7 +3573,7 @@ static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_p */ .desc = "consumer assigned-clocks null phandle", TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_null_consumer), - .sscs = {50000, 60000, 3}, + .sscs = {50000, 600, 3}, .consumer_test = true, }, }; @@ -3738,11 +3738,149 @@ static struct kunit_suite clk_hw_get_dev_of_node_test_suite = { .test_cases = clk_hw_get_dev_of_node_test_cases, }; +static const struct clk_init_data clk_parse_clkspec_1_init_data = { + .name = "clk_parse_clkspec_1", + .ops = &empty_clk_ops, +}; + +static const struct clk_init_data clk_parse_clkspec_2_init_data = { + .name = "clk_parse_clkspec_2", + .ops = &empty_clk_ops, +}; + +struct clk_parse_clkspec_ctx { + struct device_node *cons_np; +}; + +static int clk_parse_clkspec_init(struct kunit *test) +{ + struct device_node *prov1_np, *prov2_np; + struct clk_parse_clkspec_ctx *ctx; + struct clk_hw *hw1, *hw2; + + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + test->priv = ctx; + + KUNIT_ASSERT_EQ(test, 0, of_overlay_apply_kunit(test, kunit_clk_parse_clkspec)); + + /* Register provider 1 */ + hw1 = kunit_kzalloc(test, sizeof(*hw1), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw1); + hw1->init = &clk_parse_clkspec_1_init_data; + + prov1_np = of_find_compatible_node(NULL, NULL, "test,clock-provider1"); + KUNIT_ASSERT_NOT_NULL(test, prov1_np); + of_node_put_kunit(test, prov1_np); + + KUNIT_ASSERT_EQ(test, 0, of_clk_hw_register_kunit(test, prov1_np, hw1)); + KUNIT_ASSERT_EQ(test, 0, of_clk_add_hw_provider_kunit(test, prov1_np, of_clk_hw_simple_get, hw1)); + + /* Register provider 2 */ + hw2 = kunit_kzalloc(test, sizeof(*hw2), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw2); + hw2->init = &clk_parse_clkspec_2_init_data; + + prov2_np = of_find_compatible_node(NULL, NULL, "test,clock-provider2"); + KUNIT_ASSERT_NOT_NULL(test, prov2_np); + of_node_put_kunit(test, prov2_np); + + KUNIT_ASSERT_EQ(test, 0, of_clk_hw_register_kunit(test, prov2_np, hw2)); + KUNIT_ASSERT_EQ(test, 0, of_clk_add_hw_provider_kunit(test, prov2_np, of_clk_hw_simple_get, hw2)); + + ctx->cons_np = of_find_compatible_node(NULL, NULL, "test,clock-consumer"); + KUNIT_ASSERT_NOT_NULL(test, ctx->cons_np); + of_node_put_kunit(test, ctx->cons_np); + + return 0; +} + +/* Test DT phandle lookups using correct index or name succeed */ +static void clk_parse_clkspec_with_correct_index_and_name(struct kunit *test) +{ + struct clk_parse_clkspec_ctx *ctx = test->priv; + struct clk_hw *hw1, *hw2, *hw3, *hw4; + + /* Get clocks by index */ + hw1 = of_clk_get_hw(ctx->cons_np, 0, NULL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, hw1); + + hw2 = of_clk_get_hw(ctx->cons_np, 1, NULL); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, hw2); + KUNIT_EXPECT_PTR_NE(test, hw1, hw2); + + /* Get clocks by name */ + hw3 = of_clk_get_hw(ctx->cons_np, 0, "first_clock"); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, hw3); + KUNIT_EXPECT_PTR_EQ(test, hw1, hw3); + + hw4 = of_clk_get_hw(ctx->cons_np, 0, "second_clock"); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, hw4); + KUNIT_EXPECT_PTR_EQ(test, hw2, hw4); +} + +/* Test DT phandle lookups using wrong index or name fail */ +static void clk_parse_clkspec_with_incorrect_index_and_name(struct kunit *test) +{ + struct clk_parse_clkspec_ctx *ctx = test->priv; + struct clk_hw *hw; + + /* Get clock by index */ + hw = of_clk_get_hw(ctx->cons_np, 2, NULL); + KUNIT_EXPECT_TRUE(test, IS_ERR(hw)); + + /* Get clock by name */ + hw = of_clk_get_hw(ctx->cons_np, 0, "third_clock"); + KUNIT_EXPECT_TRUE(test, IS_ERR(hw)); +} + +/* + * Verify that of_clk_get_parent_name() returns the correct clock name when + * looking up by index through the consumer's clocks property. + */ +static void of_clk_get_parent_name_gets_parent_name(struct kunit *test) +{ + struct clk_parse_clkspec_ctx *ctx = test->priv; + const char *expected_name = "clk_parse_clkspec_1"; + + KUNIT_EXPECT_STREQ(test, expected_name, + of_clk_get_parent_name(ctx->cons_np, 0)); +} + +static void of_clk_get_hw_maps_thru_nexus(struct kunit *test) +{ + struct clk_parse_clkspec_ctx *ctx = test->priv; + struct clk_hw *expected; + struct device_node *np; + + np = clk_of_find_node_by_name_kunit(test, NULL, "kunit-clock-nexus-child"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np); + expected = of_clk_get_hw(ctx->cons_np, 1, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected); + + KUNIT_EXPECT_PTR_EQ(test, expected, of_clk_get_hw(np, 0, NULL)); +} + +static struct kunit_case clk_parse_clkspec_test_cases[] = { + KUNIT_CASE(clk_parse_clkspec_with_correct_index_and_name), + KUNIT_CASE(clk_parse_clkspec_with_incorrect_index_and_name), + KUNIT_CASE(of_clk_get_parent_name_gets_parent_name), + KUNIT_CASE(of_clk_get_hw_maps_thru_nexus), + {} +}; + +/* Test suite to verify clk_parse_clkspec() */ +static struct kunit_suite clk_parse_clkspec_test_suite = { + .name = "clk_parse_clkspec", + .init = clk_parse_clkspec_init, + .test_cases = clk_parse_clkspec_test_cases, +}; kunit_test_suites( &clk_assigned_rates_suite, &clk_assigned_sscs_suite, &clk_hw_get_dev_of_node_test_suite, + &clk_parse_clkspec_test_suite, &clk_leaf_mux_set_rate_parent_test_suite, &clk_test_suite, &clk_multiple_parents_mux_test_suite, @@ -3760,4 +3898,5 @@ kunit_test_suites( &clk_uncached_test_suite, ); MODULE_DESCRIPTION("Kunit tests for clk framework"); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index abaa0f9e0083..919fc680ae4d 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -88,7 +88,7 @@ static struct clk *__clk_get_sys(struct device *dev, const char *dev_id, { struct clk_hw *hw = clk_find_hw(dev_id, con_id); - return clk_hw_create_clk(dev, hw, dev_id, con_id); + return clk_hw_create_clk(dev, hw, dev_id, con_id, NULL); } struct clk *clk_get_sys(const char *dev_id, const char *con_id) @@ -105,7 +105,7 @@ struct clk *clk_get(struct device *dev, const char *con_id) if (dev && dev->of_node) { hw = of_clk_get_hw(dev->of_node, 0, con_id); if (!IS_ERR(hw) || PTR_ERR(hw) == -EPROBE_DEFER) - return clk_hw_create_clk(dev, hw, dev_id, con_id); + return clk_hw_create_clk(dev, hw, dev_id, con_id, NULL); } return __clk_get_sys(dev, dev_id, con_id); diff --git a/drivers/clk/davinci/Kconfig b/drivers/clk/davinci/Kconfig new file mode 100644 index 000000000000..7b8c518ef6b4 --- /dev/null +++ b/drivers/clk/davinci/Kconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0-only +config COMMON_CLK_DAVINCI + bool "Clock drivers for TI DaVinci SoCs" + depends on ARCH_DAVINCI || COMPILE_TEST + depends on HAS_IOMEM + select REGMAP_MMIO + select RESET_CONTROLLER + default ARCH_DAVINCI + help + Support for the clock controllers found on TI DaVinci SoCs. diff --git a/drivers/clk/davinci/Makefile b/drivers/clk/davinci/Makefile index f9d5c9a392e4..7cb030b5e046 100644 --- a/drivers/clk/davinci/Makefile +++ b/drivers/clk/davinci/Makefile @@ -1,11 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 -ifeq ($(CONFIG_COMMON_CLK), y) -obj-$(CONFIG_ARCH_DAVINCI_DA8XX) += da8xx-cfgchip.o +obj-y += da8xx-cfgchip.o obj-y += pll.o -obj-$(CONFIG_ARCH_DAVINCI_DA850) += pll-da850.o +obj-y += pll-da850.o obj-y += psc.o -obj-$(CONFIG_ARCH_DAVINCI_DA850) += psc-da850.o -endif +obj-y += psc-da850.o diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c index a5109fe8b16e..9d7fced898ae 100644 --- a/drivers/clk/davinci/da8xx-cfgchip.c +++ b/drivers/clk/davinci/da8xx-cfgchip.c @@ -91,7 +91,7 @@ da8xx_cfgchip_gate_clk_register(struct device *dev, struct clk *parent; const char *parent_name; struct da8xx_cfgchip_gate_clk *gate; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; parent = devm_clk_get(dev, NULL); @@ -241,7 +241,7 @@ da8xx_cfgchip_mux_clk_register(struct device *dev, { const char * const parent_names[] = { info->parent0, info->parent1 }; struct da8xx_cfgchip_mux_clk *mux; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c index f73b0ac5d8a0..0e58b02d7aca 100644 --- a/drivers/clk/davinci/pll.c +++ b/drivers/clk/davinci/pll.c @@ -371,7 +371,7 @@ struct clk *davinci_pll_clk_register(struct device *dev, char pllout_name[MAX_NAME_SIZE]; char postdiv_name[MAX_NAME_SIZE]; char pllen_name[MAX_NAME_SIZE]; - struct clk_init_data init; + struct clk_init_data init = {}; struct davinci_pll_clk *pllout; struct davinci_pllen_clk *pllen; struct clk *oscin_clk = NULL; diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c index ff603520d56f..73dce7ce2be6 100644 --- a/drivers/clk/davinci/psc.c +++ b/drivers/clk/davinci/psc.c @@ -234,7 +234,7 @@ davinci_lpsc_clk_register(struct device *dev, const char *name, const char *parent_name, struct regmap *regmap, u32 md, u32 pd, u32 flags) { - struct clk_init_data init; + struct clk_init_data init = {}; struct davinci_lpsc_clk *lpsc; int ret; bool is_on; diff --git a/drivers/clk/hisilicon/clk-hi3559a.c b/drivers/clk/hisilicon/clk-hi3559a.c index f297fb25c512..fea6fb9e98f5 100644 --- a/drivers/clk/hisilicon/clk-hi3559a.c +++ b/drivers/clk/hisilicon/clk-hi3559a.c @@ -456,8 +456,8 @@ static void hisi_clk_register_pll(struct hi3559av100_pll_clock *clks, { void __iomem *base = data->base; struct hi3559av100_clk_pll *p_clk = NULL; + struct clk_init_data init = {}; struct clk *clk = NULL; - struct clk_init_data init; int i; p_clk = devm_kcalloc(dev, nums, sizeof(*p_clk), GFP_KERNEL); diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index 8dcad74e679a..a2c4637eaa98 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -410,9 +410,9 @@ static const struct clk_ops clk_mmc_ops = { static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk, void __iomem *base, struct device_node *np) { + struct clk_init_data init = {}; struct clk_mmc *mclk; struct clk *clk; - struct clk_init_data init; mclk = kzalloc_obj(*mclk); if (!mclk) diff --git a/drivers/clk/hisilicon/clk-hi6220-stub.c b/drivers/clk/hisilicon/clk-hi6220-stub.c index bf99cfafafa0..a70544d2bdb9 100644 --- a/drivers/clk/hisilicon/clk-hi6220-stub.c +++ b/drivers/clk/hisilicon/clk-hi6220-stub.c @@ -195,7 +195,7 @@ static const struct clk_ops hi6220_stub_clk_ops = { static int hi6220_stub_clk_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct clk_init_data init; + struct clk_init_data init = {}; struct hi6220_stub_clk *stub_clk; struct clk *clk; struct device_node *np = pdev->dev.of_node; diff --git a/drivers/clk/hisilicon/clk-hisi-phase.c b/drivers/clk/hisilicon/clk-hisi-phase.c index ba6afad66a2b..d8e555d9728d 100644 --- a/drivers/clk/hisilicon/clk-hisi-phase.c +++ b/drivers/clk/hisilicon/clk-hisi-phase.c @@ -94,8 +94,8 @@ struct clk *clk_register_hisi_phase(struct device *dev, const struct hisi_phase_clock *clks, void __iomem *base, spinlock_t *lock) { + struct clk_init_data init = {}; struct clk_hisi_phase *phase; - struct clk_init_data init; phase = devm_kzalloc(dev, sizeof(struct clk_hisi_phase), GFP_KERNEL); if (!phase) diff --git a/drivers/clk/hisilicon/clk-hix5hd2.c b/drivers/clk/hisilicon/clk-hix5hd2.c index 57db6fab43aa..4b7ebebfac4b 100644 --- a/drivers/clk/hisilicon/clk-hix5hd2.c +++ b/drivers/clk/hisilicon/clk-hix5hd2.c @@ -258,8 +258,8 @@ hix5hd2_clk_register_complex(struct hix5hd2_complex_clock *clks, int nums, for (i = 0; i < nums; i++) { struct hix5hd2_clk_complex *p_clk; + struct clk_init_data init = {}; struct clk *clk; - struct clk_init_data init; p_clk = kzalloc_obj(*p_clk); if (!p_clk) diff --git a/drivers/clk/hisilicon/clkdivider-hi6220.c b/drivers/clk/hisilicon/clkdivider-hi6220.c index 20a337383a1e..cc53d0a33e3c 100644 --- a/drivers/clk/hisilicon/clkdivider-hi6220.c +++ b/drivers/clk/hisilicon/clkdivider-hi6220.c @@ -103,7 +103,7 @@ struct clk *hi6220_register_clkdiv(struct device *dev, const char *name, { struct hi6220_clk_divider *div; struct clk *clk; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_div_table *table; u32 max_div, min_div; int i; diff --git a/drivers/clk/hisilicon/clkgate-separated.c b/drivers/clk/hisilicon/clkgate-separated.c index 199303157ebd..e02d6bb5ada7 100644 --- a/drivers/clk/hisilicon/clkgate-separated.c +++ b/drivers/clk/hisilicon/clkgate-separated.c @@ -87,8 +87,8 @@ struct clk *hisi_register_clkgate_sep(struct device *dev, const char *name, u8 clk_gate_flags, spinlock_t *lock) { struct clkgate_separated *sclk; + struct clk_init_data init = {}; struct clk *clk; - struct clk_init_data init; sclk = kzalloc_obj(*sclk); if (!sclk) diff --git a/drivers/clk/imx/clk-busy.c b/drivers/clk/imx/clk-busy.c index b8b6e7c7e1fe..75a2bf29e42f 100644 --- a/drivers/clk/imx/clk-busy.c +++ b/drivers/clk/imx/clk-busy.c @@ -78,8 +78,8 @@ struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name void __iomem *busy_reg, u8 busy_shift) { struct clk_busy_divider *busy; + struct clk_init_data init = {}; struct clk_hw *hw; - struct clk_init_data init; int ret; busy = kzalloc_obj(*busy); @@ -157,9 +157,9 @@ struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift u8 width, void __iomem *busy_reg, u8 busy_shift, const char * const *parent_names, int num_parents) { + struct clk_init_data init = {}; struct clk_busy_mux *busy; struct clk_hw *hw; - struct clk_init_data init; int ret; busy = kzalloc_obj(*busy); diff --git a/drivers/clk/imx/clk-composite-93.c b/drivers/clk/imx/clk-composite-93.c index ef20ceb2d255..953f67d13978 100644 --- a/drivers/clk/imx/clk-composite-93.c +++ b/drivers/clk/imx/clk-composite-93.c @@ -43,11 +43,12 @@ static int imx93_clk_composite_wait_ready(struct clk_hw *hw, void __iomem *reg) return ret; } -static void imx93_clk_composite_gate_endisable(struct clk_hw *hw, int enable) +static int imx93_clk_composite_gate_endisable(struct clk_hw *hw, int enable) { struct clk_gate *gate = to_clk_gate(hw); unsigned long flags; u32 reg; + int ret; if (gate->lock) spin_lock_irqsave(gate->lock, flags); @@ -61,17 +62,17 @@ static void imx93_clk_composite_gate_endisable(struct clk_hw *hw, int enable) writel(reg, gate->reg); - imx93_clk_composite_wait_ready(hw, gate->reg); + ret = imx93_clk_composite_wait_ready(hw, gate->reg); if (gate->lock) spin_unlock_irqrestore(gate->lock, flags); + + return ret; } static int imx93_clk_composite_gate_enable(struct clk_hw *hw) { - imx93_clk_composite_gate_endisable(hw, 1); - - return 0; + return imx93_clk_composite_gate_endisable(hw, 1); } static void imx93_clk_composite_gate_disable(struct clk_hw *hw) diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c index f53dbaacddcc..b4d9722eb17e 100644 --- a/drivers/clk/imx/clk-cpu.c +++ b/drivers/clk/imx/clk-cpu.c @@ -76,9 +76,9 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, struct clk *div, struct clk *mux, struct clk *pll, struct clk *step) { + struct clk_init_data init = {}; struct clk_cpu *cpu; struct clk_hw *hw; - struct clk_init_data init; int ret; cpu = kzalloc_obj(*cpu); diff --git a/drivers/clk/imx/clk-divider-gate.c b/drivers/clk/imx/clk-divider-gate.c index 957d132c4607..a1b7c109069c 100644 --- a/drivers/clk/imx/clk-divider-gate.c +++ b/drivers/clk/imx/clk-divider-gate.c @@ -179,8 +179,8 @@ struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name const struct clk_div_table *table, spinlock_t *lock) { - struct clk_init_data init; struct clk_divider_gate *div_gate; + struct clk_init_data init = {}; struct clk_hw *hw; u32 val; int ret; diff --git a/drivers/clk/imx/clk-fixup-div.c b/drivers/clk/imx/clk-fixup-div.c index 3866319af54e..a6f68317cd2e 100644 --- a/drivers/clk/imx/clk-fixup-div.c +++ b/drivers/clk/imx/clk-fixup-div.c @@ -90,8 +90,8 @@ struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent, void (*fixup)(u32 *val)) { struct clk_fixup_div *fixup_div; + struct clk_init_data init = {}; struct clk_hw *hw; - struct clk_init_data init; int ret; if (!fixup) diff --git a/drivers/clk/imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c index 7188cdad79d3..f43648f7fb45 100644 --- a/drivers/clk/imx/clk-fixup-mux.c +++ b/drivers/clk/imx/clk-fixup-mux.c @@ -70,8 +70,8 @@ struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg, int num_parents, void (*fixup)(u32 *val)) { struct clk_fixup_mux *fixup_mux; + struct clk_init_data init = {}; struct clk_hw *hw; - struct clk_init_data init; int ret; if (!fixup) diff --git a/drivers/clk/imx/clk-frac-pll.c b/drivers/clk/imx/clk-frac-pll.c index cd4e26bac19c..d6c59634c0c0 100644 --- a/drivers/clk/imx/clk-frac-pll.c +++ b/drivers/clk/imx/clk-frac-pll.c @@ -208,7 +208,7 @@ struct clk_hw *imx_clk_hw_frac_pll(const char *name, const char *parent_name, void __iomem *base) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_frac_pll *pll; struct clk_hw *hw; int ret; diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index 4048c16c0578..376ba435a747 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -89,6 +89,7 @@ static const struct imx_fracn_gppll_rate_table fracn_tbl[] = { PLL_FRACN_GP(445333333U, 167, 0, 1, 0, 9), PLL_FRACN_GP(400000000U, 200, 0, 1, 0, 12), PLL_FRACN_GP(393216000U, 163, 84, 100, 0, 10), + PLL_FRACN_GP(350000000U, 175, 0, 1, 0, 12), PLL_FRACN_GP(333333333U, 125, 0, 1, 1, 9), PLL_FRACN_GP(332600000U, 138, 584, 1000, 0, 10), PLL_FRACN_GP(300000000U, 150, 0, 1, 0, 12), @@ -363,9 +364,9 @@ static struct clk_hw *_imx_clk_fracn_gppll(const char *name, const char *parent_ const struct imx_fracn_gppll_clk *pll_clk, u32 pll_flags) { + struct clk_init_data init = {}; struct clk_fracn_gppll *pll; struct clk_hw *hw; - struct clk_init_data init; int ret; pll = kzalloc_obj(*pll); diff --git a/drivers/clk/imx/clk-gate-93.c b/drivers/clk/imx/clk-gate-93.c index 7acbcfec9610..7208138d615d 100644 --- a/drivers/clk/imx/clk-gate-93.c +++ b/drivers/clk/imx/clk-gate-93.c @@ -158,9 +158,9 @@ struct clk_hw *imx93_clk_gate(struct device *dev, const char *name, const char * unsigned long flags, void __iomem *reg, u32 bit_idx, u32 val, u32 mask, u32 domain_id, unsigned int *share_count) { + struct clk_init_data init = {}; struct imx93_clk_gate *gate; struct clk_hw *hw; - struct clk_init_data init; int ret; u32 authen; diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c index 504cfeef28a0..cf873e490362 100644 --- a/drivers/clk/imx/clk-gate-exclusive.c +++ b/drivers/clk/imx/clk-gate-exclusive.c @@ -59,9 +59,9 @@ struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent, void __iomem *reg, u8 shift, u32 exclusive_mask) { struct clk_gate_exclusive *exgate; + struct clk_init_data init = {}; struct clk_gate *gate; struct clk_hw *hw; - struct clk_init_data init; int ret; if (exclusive_mask == 0) diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index f07cf82dd9c9..c8b6323571ee 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c @@ -139,9 +139,9 @@ struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, u8 clk_gate2_flags, spinlock_t *lock, unsigned int *share_count) { + struct clk_init_data init = {}; struct clk_gate2 *gate; struct clk_hw *hw; - struct clk_init_data init; int ret; gate = kzalloc_obj(struct clk_gate2); diff --git a/drivers/clk/imx/clk-lpcg-scu.c b/drivers/clk/imx/clk-lpcg-scu.c index 03bbfbe9bff3..da110a823fd5 100644 --- a/drivers/clk/imx/clk-lpcg-scu.c +++ b/drivers/clk/imx/clk-lpcg-scu.c @@ -114,8 +114,8 @@ struct clk_hw *__imx_clk_lpcg_scu(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 bit_idx, bool hw_gate) { + struct clk_init_data init = {}; struct clk_lpcg_scu *clk; - struct clk_init_data init; struct clk_hw *hw; int ret; diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c index e7a5d80c5008..e56bb27e57cc 100644 --- a/drivers/clk/imx/clk-pfd.c +++ b/drivers/clk/imx/clk-pfd.c @@ -127,9 +127,9 @@ static const struct clk_ops clk_pfd_ops = { struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name, void __iomem *reg, u8 idx) { + struct clk_init_data init = {}; struct clk_pfd *pfd; struct clk_hw *hw; - struct clk_init_data init; int ret; pfd = kzalloc_obj(*pfd); diff --git a/drivers/clk/imx/clk-pfdv2.c b/drivers/clk/imx/clk-pfdv2.c index 0f92b92e2229..43ba79e47eac 100644 --- a/drivers/clk/imx/clk-pfdv2.c +++ b/drivers/clk/imx/clk-pfdv2.c @@ -203,7 +203,7 @@ static const struct clk_ops clk_pfdv2_ops = { struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name, const char *parent_name, void __iomem *reg, u8 idx) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_pfdv2 *pfd; struct clk_hw *hw; int ret; diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index b6f1cc9f5700..c6438144e507 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,8 @@ #define GNRL_CTL 0x0 #define DIV_CTL0 0x4 #define DIV_CTL1 0x8 +#define SSCG_CTRL 0xc + #define LOCK_STATUS BIT(31) #define LOCK_SEL_MASK BIT(29) #define CLKE_MASK BIT(11) @@ -33,6 +36,13 @@ #define KDIV_MASK GENMASK(15, 0) #define KDIV_MIN SHRT_MIN #define KDIV_MAX SHRT_MAX +#define SSCG_ENABLE BIT(31) +#define MFREQ_CTL_MASK GENMASK(19, 12) +#define MRAT_CTL_MASK GENMASK(9, 4) +#define SEL_PF_DOWN_SPREAD 0 +#define SEL_PF_UP_SPREAD 1 +#define SEL_PF_CENTER_SPREAD 2 +#define SEL_PF_MASK GENMASK(1, 0) #define LOCK_TIMEOUT_US 10000 @@ -44,6 +54,7 @@ struct clk_pll14xx { int rate_count; s16 delta_k; spinlock_t lock; + struct clk_spread_spectrum ss_conf; }; #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw) @@ -366,6 +377,62 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate, return 0; } +static void __clk_pll1443x_set_spread_spectrum(struct clk_hw *hw, + unsigned long parent_rate, + unsigned int pdiv, + unsigned int mdiv) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(hw); + struct clk_spread_spectrum *conf = &pll->ss_conf; + u32 sscg_ctrl, mfr, mrr, sel_pf; + + sscg_ctrl = readl_relaxed(pll->base + SSCG_CTRL); + sscg_ctrl &= ~(SSCG_ENABLE | MFREQ_CTL_MASK | MRAT_CTL_MASK | SEL_PF_MASK); + + switch (conf->method) { + case CLK_SPREAD_CENTER: + sel_pf = SEL_PF_CENTER_SPREAD; + break; + case CLK_SPREAD_UP: + sel_pf = SEL_PF_UP_SPREAD; + break; + case CLK_SPREAD_DOWN: + sel_pf = SEL_PF_DOWN_SPREAD; + break; + default: + /* No spread: disable modulation and clear any stale state */ + goto out; + } + + if (!conf->modfreq_hz || !parent_rate || !pdiv) + goto out; + + mfr = div64_u64(parent_rate, (u64)conf->modfreq_hz * pdiv * BIT(5)); + if (!mfr || mfr > FIELD_MAX(MFREQ_CTL_MASK)) { + pr_warn_ratelimited("%s: SSC disabled, modulation frequency (%u Hz) out of range\n", + clk_hw_get_name(hw), conf->modfreq_hz); + goto out; + } + + /* + * No overflow: the core limits spread_bp to 10000 and mdiv is a 10-bit + * field, so the product is at most 10000 * 1023 * 64 < 2^32. + */ + mrr = (conf->spread_bp * mdiv * BIT(6)) / (10000 * mfr); + if (!mrr || mrr > FIELD_MAX(MRAT_CTL_MASK)) { + pr_warn_ratelimited("%s: SSC disabled, spread (%u permyriad) out of range\n", + clk_hw_get_name(hw), conf->spread_bp); + goto out; + } + + sscg_ctrl |= SSCG_ENABLE | FIELD_PREP(MFREQ_CTL_MASK, mfr) | + FIELD_PREP(MRAT_CTL_MASK, mrr) | + FIELD_PREP(SEL_PF_MASK, sel_pf); + +out: + writel_relaxed(sscg_ctrl, pll->base + SSCG_CTRL); +} + static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, unsigned long prate) { @@ -390,6 +457,9 @@ 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); + __clk_pll1443x_set_spread_spectrum(hw, prate, rate.pdiv, + rate.mdiv); + spin_unlock_irqrestore(&pll->lock, flags); return 0; @@ -411,6 +481,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); + __clk_pll1443x_set_spread_spectrum(hw, prate, rate.pdiv, rate.mdiv); + spin_unlock_irqrestore(&pll->lock, flags); /* @@ -437,6 +509,36 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, return 0; } +static int clk_pll1443x_set_spread_spectrum(struct clk_hw *hw, + const struct clk_spread_spectrum *ss_conf) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(hw); + struct clk_hw *parent = clk_hw_get_parent(hw); + unsigned long parent_rate = parent ? clk_hw_get_rate(parent) : 0; + unsigned long flags; + u32 div_ctl0; + + spin_lock_irqsave(&pll->lock, flags); + + pll->ss_conf = *ss_conf; + + /* + * Apply the configuration to the hardware right away, using the + * current PLL dividers: the clock framework does not call set_rate() + * if the requested rate is unchanged, so relying on it would leave + * the SSC settings unapplied when the PLL is already at the target + * rate (e.g. configured by the bootloader). + */ + div_ctl0 = readl_relaxed(pll->base + DIV_CTL0); + __clk_pll1443x_set_spread_spectrum(hw, parent_rate, + FIELD_GET(PDIV_MASK, div_ctl0), + FIELD_GET(MDIV_MASK, div_ctl0)); + + spin_unlock_irqrestore(&pll->lock, flags); + + return 0; +} + static int clk_pll14xx_prepare(struct clk_hw *hw) { struct clk_pll14xx *pll = to_clk_pll14xx(hw); @@ -509,15 +611,16 @@ static const struct clk_ops clk_pll1443x_ops = { .recalc_rate = clk_pll14xx_recalc_rate, .determine_rate = clk_pll1443x_determine_rate, .set_rate = clk_pll1443x_set_rate, + .set_spread_spectrum = clk_pll1443x_set_spread_spectrum, }; struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name, const char *parent_name, void __iomem *base, const struct imx_pll14xx_clk *pll_clk) { + struct clk_init_data init = {}; struct clk_pll14xx *pll; struct clk_hw *hw; - struct clk_init_data init; int ret; u32 val; diff --git a/drivers/clk/imx/clk-pllv1.c b/drivers/clk/imx/clk-pllv1.c index da5531e57da2..ee60c7660ef4 100644 --- a/drivers/clk/imx/clk-pllv1.c +++ b/drivers/clk/imx/clk-pllv1.c @@ -114,9 +114,9 @@ static const struct clk_ops clk_pllv1_ops = { struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name, const char *parent, void __iomem *base) { + struct clk_init_data init = {}; struct clk_pllv1 *pll; struct clk_hw *hw; - struct clk_init_data init; int ret; pll = kmalloc_obj(*pll); diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c index 43396388030e..aacc3d84e797 100644 --- a/drivers/clk/imx/clk-pllv2.c +++ b/drivers/clk/imx/clk-pllv2.c @@ -249,9 +249,9 @@ static const struct clk_ops clk_pllv2_ops = { struct clk_hw *imx_clk_hw_pllv2(const char *name, const char *parent, void __iomem *base) { + struct clk_init_data init = {}; struct clk_pllv2 *pll; struct clk_hw *hw; - struct clk_init_data init; int ret; pll = kzalloc_obj(*pll); diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c index a0ad6f4aae8f..714d9c723e16 100644 --- a/drivers/clk/imx/clk-pllv3.c +++ b/drivers/clk/imx/clk-pllv3.c @@ -422,8 +422,8 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name, { struct clk_pllv3 *pll; const struct clk_ops *ops; + struct clk_init_data init = {}; struct clk_hw *hw; - struct clk_init_data init; int ret; pll = kzalloc_obj(*pll); diff --git a/drivers/clk/imx/clk-pllv4.c b/drivers/clk/imx/clk-pllv4.c index 8fa2f7111ce9..6dc9640d2f19 100644 --- a/drivers/clk/imx/clk-pllv4.c +++ b/drivers/clk/imx/clk-pllv4.c @@ -246,9 +246,9 @@ static const struct clk_ops clk_pllv4_ops = { struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name, const char *parent_name, void __iomem *base) { + struct clk_init_data init = {}; struct clk_pllv4 *pll; struct clk_hw *hw; - struct clk_init_data init; int ret; pll = kzalloc_obj(*pll); diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index 44220e9c5c2a..0d034e206c6b 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -445,7 +445,7 @@ struct clk_hw *__imx_clk_scu(struct device *dev, const char *name, const char * const *parents, int num_parents, u32 rsrc_id, u8 clk_type) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_scu *clk; struct clk_hw *hw; int ret; @@ -839,9 +839,9 @@ struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_na bool invert) { struct imx_scu_clk_node *clk_node; + struct clk_init_data init = {}; struct clk_gpr_scu *clk; struct clk_hw *hw; - struct clk_init_data init; int ret; if (rsrc_id >= IMX_SC_R_LAST || gpr_id >= IMX_SC_C_LAST) diff --git a/drivers/clk/imx/clk-sscg-pll.c b/drivers/clk/imx/clk-sscg-pll.c index 7f104ecfa80f..f6286ec11e0c 100644 --- a/drivers/clk/imx/clk-sscg-pll.c +++ b/drivers/clk/imx/clk-sscg-pll.c @@ -504,8 +504,8 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char *name, void __iomem *base, unsigned long flags) { + struct clk_init_data init = {}; struct clk_sscg_pll *pll; - struct clk_init_data init; struct clk_hw *hw; int ret; diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index f38506830ccf..49e51e949f71 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -95,11 +95,16 @@ struct clk_hw *imx_obtain_fixed_clock_hw( const char *name, unsigned long rate) { struct clk *clk; + struct clk_hw *hw; clk = imx_obtain_fixed_clock_from_dt(name); if (IS_ERR(clk)) - clk = imx_clk_fixed(name, rate); - return __clk_get_hw(clk); + return __clk_get_hw(imx_clk_fixed(name, rate)); + + hw = __clk_get_hw(clk); + clk_put(clk); + + return hw; } struct clk_hw *imx_obtain_fixed_of_clock(struct device_node *np, @@ -119,12 +124,16 @@ struct clk_hw *imx_obtain_fixed_of_clock(struct device_node *np, struct clk_hw *imx_get_clk_hw_by_name(struct device_node *np, const char *name) { struct clk *clk; + struct clk_hw *hw; clk = of_clk_get_by_name(np, name); if (IS_ERR(clk)) return ERR_PTR(-ENOENT); - return __clk_get_hw(clk); + hw = __clk_get_hw(clk); + clk_put(clk); + + return hw; } EXPORT_SYMBOL_GPL(imx_get_clk_hw_by_name); diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index 41e4c69131bd..ad223aa20e8d 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -644,8 +644,8 @@ static const struct clk_ops ingenic_clk_ops = { static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx) { const struct ingenic_cgu_clk_info *clk_info = &cgu->clock_info[idx]; - struct clk_init_data clk_init; struct ingenic_clk *ingenic_clk = NULL; + struct clk_init_data clk_init = {}; struct clk *clk, *parent; const char *parent_names[4]; unsigned caps, i, num_possible; diff --git a/drivers/clk/keystone/gate.c b/drivers/clk/keystone/gate.c index 03e854f10fd9..e83e3d4c7d67 100644 --- a/drivers/clk/keystone/gate.c +++ b/drivers/clk/keystone/gate.c @@ -164,7 +164,7 @@ static struct clk *clk_register_psc(struct device *dev, struct clk_psc_data *psc_data, spinlock_t *lock) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_psc *psc; struct clk *clk; diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c index ed197ee0cc88..020d5f4e9ed6 100644 --- a/drivers/clk/keystone/pll.c +++ b/drivers/clk/keystone/pll.c @@ -122,7 +122,7 @@ static struct clk *clk_register_pll(struct device *dev, const char *parent_name, struct clk_pll_data *pll_data) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_pll *pll; struct clk *clk; diff --git a/drivers/clk/keystone/syscon-clk.c b/drivers/clk/keystone/syscon-clk.c index ecf180a7949c..338174be4121 100644 --- a/drivers/clk/keystone/syscon-clk.c +++ b/drivers/clk/keystone/syscon-clk.c @@ -67,7 +67,7 @@ static struct clk_hw const struct ti_syscon_gate_clk_data *data) { struct ti_syscon_gate_clk_priv *priv; - struct clk_init_data init; + struct clk_init_data init = {}; char *name = NULL; int ret; diff --git a/drivers/clk/kunit_clk_assigned_rates.h b/drivers/clk/kunit_clk_assigned_rates.h index d7ae5ec2d25b..c5d9f004ee81 100644 --- a/drivers/clk/kunit_clk_assigned_rates.h +++ b/drivers/clk/kunit_clk_assigned_rates.h @@ -9,10 +9,10 @@ #define ASSIGNED_RATES_1_RATE 9700000 #define ASSIGNED_SSCS_0_MODFREQ 10000 -#define ASSIGNED_SSCS_0_SPREAD 30000 +#define ASSIGNED_SSCS_0_SPREAD 300 #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_SPREAD 400 #define ASSIGNED_SSCS_1_METHOD CLK_SSC_UP_SPREAD #endif diff --git a/drivers/clk/kunit_clk_parse_clkspec.dtso b/drivers/clk/kunit_clk_parse_clkspec.dtso new file mode 100644 index 000000000000..a4115216d2aa --- /dev/null +++ b/drivers/clk/kunit_clk_parse_clkspec.dtso @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&{/} { + kunit_clock_provider1: kunit-clock-provider1 { + compatible = "test,clock-provider1"; + #clock-cells = <1>; + }; + + kunit_clock_provider2: kunit-clock-provider2 { + compatible = "test,clock-provider2"; + #clock-cells = <1>; + }; + + kunit-clock-consumer { + compatible = "test,clock-consumer"; + clocks = <&kunit_clock_provider1 0>, <&kunit_clock_provider2 0>; + clock-names = "first_clock", "second_clock"; + }; + + kunit_clock_nexus: kunit-clock-nexus { + clocks = <&kunit_clock_provider2 0>; + clock-map = <&kunit_clock_provider2 0>; + #clock-cells = <0>; + + kunit-clock-nexus-child { + clocks = <&kunit_clock_nexus>; + }; + }; +}; diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index b059d44577f1..ba1ca9c90dbf 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -541,6 +541,7 @@ config COMMON_CLK_MT8173_MFGTOP tristate "Clock and power driver for MediaTek MT8173 mfgtop" depends on COMMON_CLK_MT8173 depends on PM + depends on OF default COMMON_CLK_MT8173 select PM_GENERIC_DOMAINS select PM_GENERIC_DOMAINS_OF diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c index 412558b95127..9799bc156dcc 100644 --- a/drivers/clk/mediatek/clk-cpumux.c +++ b/drivers/clk/mediatek/clk-cpumux.c @@ -62,9 +62,9 @@ static struct clk_hw * mtk_clk_register_cpumux(struct device *dev, const struct mtk_composite *mux, struct regmap *regmap) { + struct clk_init_data init = {}; struct mtk_clk_cpumux *cpumux; int ret; - struct clk_init_data init; cpumux = kzalloc_obj(*cpumux); if (!cpumux) diff --git a/drivers/clk/mediatek/reset.h b/drivers/clk/mediatek/reset.h index 562ffd290a22..b09cdcab0c4b 100644 --- a/drivers/clk/mediatek/reset.h +++ b/drivers/clk/mediatek/reset.h @@ -60,11 +60,11 @@ struct mtk_clk_rst_data { }; /** - * mtk_register_reset_controller - Register mediatek clock reset controller with device - * @np: Pointer to device. + * mtk_register_reset_controller_with_dev - Register a MediaTek reset controller + * @dev: Device used to manage the reset controller resources. * @desc: Constant pointer to description of clock reset. * - * Return: 0 on success and errorno otherwise. + * Return: 0 on success, negative errno otherwise. */ int mtk_register_reset_controller_with_dev(struct device *dev, const struct mtk_clk_rst_desc *desc); diff --git a/drivers/clk/meson/t7-peripherals.c b/drivers/clk/meson/t7-peripherals.c index 214db7850d86..2f429ea86796 100644 --- a/drivers/clk/meson/t7-peripherals.c +++ b/drivers/clk/meson/t7-peripherals.c @@ -947,9 +947,14 @@ static T7_SYS_PCLK(sys_gdc, SYS_CLK_EN0_REG0, 17, 0); static T7_SYS_PCLK(sys_deswarp, SYS_CLK_EN0_REG0, 18, 0); static T7_SYS_PCLK(sys_ampipe_nand, SYS_CLK_EN0_REG0, 19, 0); static T7_SYS_PCLK(sys_ampipe_eth, SYS_CLK_EN0_REG0, 20, 0); -static T7_SYS_PCLK(sys_am2axi0, SYS_CLK_EN0_REG0, 21, 0); -static T7_SYS_PCLK(sys_am2axi1, SYS_CLK_EN0_REG0, 22, 0); -static T7_SYS_PCLK(sys_am2axi2, SYS_CLK_EN0_REG0, 23, 0); +/* + * NOTE: sys_am2axi0..2 provide the clock to the AXI bus used for DMA between + * the peripherals and the DRAM. After the clocks are disabled, a device that + * starts a transfer cannot complete it. + */ +static T7_SYS_PCLK(sys_am2axi0, SYS_CLK_EN0_REG0, 21, CLK_IS_CRITICAL); +static T7_SYS_PCLK(sys_am2axi1, SYS_CLK_EN0_REG0, 22, CLK_IS_CRITICAL); +static T7_SYS_PCLK(sys_am2axi2, SYS_CLK_EN0_REG0, 23, CLK_IS_CRITICAL); static T7_SYS_PCLK(sys_sd_emmc_a, SYS_CLK_EN0_REG0, 24, 0); static T7_SYS_PCLK(sys_sd_emmc_b, SYS_CLK_EN0_REG0, 25, 0); static T7_SYS_PCLK(sys_sd_emmc_c, SYS_CLK_EN0_REG0, 26, 0); diff --git a/drivers/clk/mmp/Kconfig b/drivers/clk/mmp/Kconfig index b0d2fea3cda5..35a069034b28 100644 --- a/drivers/clk/mmp/Kconfig +++ b/drivers/clk/mmp/Kconfig @@ -1,10 +1,15 @@ # SPDX-License-Identifier: GPL-2.0-only +config COMMON_CLK_MMP + bool + default ARCH_MMP + config COMMON_CLK_PXA1908 bool "Clock driver for Marvell PXA1908" depends on ARCH_MMP || COMPILE_TEST depends on OF default y if ARCH_MMP && ARM64 + select COMMON_CLK_MMP select AUXILIARY_BUS help This driver supports the Marvell PXA1908 SoC clocks. diff --git a/drivers/clk/mmp/clk-apbc.c b/drivers/clk/mmp/clk-apbc.c index 84532ce8fd09..338ccd8fe99c 100644 --- a/drivers/clk/mmp/clk-apbc.c +++ b/drivers/clk/mmp/clk-apbc.c @@ -120,9 +120,9 @@ struct clk *mmp_clk_register_apbc(const char *name, const char *parent_name, void __iomem *base, unsigned int delay, unsigned int apbc_flags, spinlock_t *lock) { + struct clk_init_data init = {}; struct clk_apbc *apbc; struct clk *clk; - struct clk_init_data init; apbc = kzalloc_obj(*apbc); if (!apbc) diff --git a/drivers/clk/mmp/clk-apmu.c b/drivers/clk/mmp/clk-apmu.c index 30bbac1deca1..887854d8f5b1 100644 --- a/drivers/clk/mmp/clk-apmu.c +++ b/drivers/clk/mmp/clk-apmu.c @@ -65,9 +65,9 @@ static const struct clk_ops clk_apmu_ops = { struct clk *mmp_clk_register_apmu(const char *name, const char *parent_name, void __iomem *base, u32 enable_mask, spinlock_t *lock) { + struct clk_init_data init = {}; struct clk_apmu *apmu; struct clk *clk; - struct clk_init_data init; apmu = kzalloc_obj(*apmu); if (!apmu) diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c index 13bfc4c99f3a..5774354563aa 100644 --- a/drivers/clk/mmp/clk-frac.c +++ b/drivers/clk/mmp/clk-frac.c @@ -171,8 +171,8 @@ struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, struct mmp_clk_factor_masks *masks, struct u32_fract *ftbl, unsigned int ftbl_cnt, spinlock_t *lock) { + struct clk_init_data init = {}; struct mmp_clk_factor *factor; - struct clk_init_data init; struct clk *clk; if (!masks) { diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c index cc2f841ae9d9..e8dad4ed0125 100644 --- a/drivers/clk/mmp/clk-gate.c +++ b/drivers/clk/mmp/clk-gate.c @@ -94,9 +94,9 @@ struct clk *mmp_clk_register_gate(struct device *dev, const char *name, void __iomem *reg, u32 mask, u32 val_enable, u32 val_disable, unsigned int gate_flags, spinlock_t *lock) { + struct clk_init_data init = {}; struct mmp_clk_gate *gate; struct clk *clk; - struct clk_init_data init; /* allocate the gate */ gate = kzalloc_obj(*gate); diff --git a/drivers/clk/mmp/clk-mix.c b/drivers/clk/mmp/clk-mix.c index b1c9899c71af..2f3d1cb6f836 100644 --- a/drivers/clk/mmp/clk-mix.c +++ b/drivers/clk/mmp/clk-mix.c @@ -444,9 +444,9 @@ struct clk *mmp_clk_register_mix(struct device *dev, struct mmp_clk_mix_config *config, spinlock_t *lock) { + struct clk_init_data init = {}; struct mmp_clk_mix *mix; struct clk *clk; - struct clk_init_data init; mix = kzalloc_obj(*mix); if (!mix) diff --git a/drivers/clk/mmp/clk-pll.c b/drivers/clk/mmp/clk-pll.c index 430f5e3c8540..e0ea29b5bb66 100644 --- a/drivers/clk/mmp/clk-pll.c +++ b/drivers/clk/mmp/clk-pll.c @@ -104,9 +104,9 @@ static struct clk *mmp_clk_register_pll(char *name, unsigned long input_rate, void __iomem *postdiv_reg, u8 postdiv_shift) { + struct clk_init_data init = {}; struct mmp_clk_pll *pll; struct clk *clk; - struct clk_init_data init; pll = kzalloc_obj(*pll); if (!pll) diff --git a/drivers/clk/mstar/clk-msc313-mpll.c b/drivers/clk/mstar/clk-msc313-mpll.c index 61beb4e87525..bd45aa0aec01 100644 --- a/drivers/clk/mstar/clk-msc313-mpll.c +++ b/drivers/clk/mstar/clk-msc313-mpll.c @@ -105,7 +105,7 @@ static int msc313_mpll_probe(struct platform_device *pdev) return PTR_ERR(mpll->loop_div_second); mpll->clk_data = devm_kzalloc(dev, struct_size(mpll->clk_data, hws, - ARRAY_SIZE(output_dividers)), GFP_KERNEL); + NUMOUTPUTS), GFP_KERNEL); if (!mpll->clk_data) return -ENOMEM; diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c index 1e44ace7d951..b1c6fceb91b2 100644 --- a/drivers/clk/mvebu/ap-cpu-clk.c +++ b/drivers/clk/mvebu/ap-cpu-clk.c @@ -284,9 +284,11 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) if (!ap_cpu_data) return -ENOMEM; + ap_cpu_data->num = nclusters; + for_each_of_cpu_node(dn) { char *clk_name = "cpu-cluster-0"; - struct clk_init_data init; + struct clk_init_data init = {}; const char *parent_name; struct clk *parent; u64 cpu; @@ -333,8 +335,6 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) ap_cpu_data->hws[cluster_index] = &ap_cpu_clk[cluster_index].hw; } - ap_cpu_data->num = cluster_index + 1; - ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, ap_cpu_data); if (ret) dev_err(dev, "failed to register OF clock provider\n"); diff --git a/drivers/clk/mvebu/clk-corediv.c b/drivers/clk/mvebu/clk-corediv.c index ae48293b0c41..e26ada3c29ae 100644 --- a/drivers/clk/mvebu/clk-corediv.c +++ b/drivers/clk/mvebu/clk-corediv.c @@ -253,7 +253,7 @@ static void __init mvebu_corediv_clk_init(struct device_node *node, const struct clk_corediv_soc_desc *soc_desc) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_corediv *corediv; struct clk **clks; void __iomem *base; diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index 24196e288fe2..a7646a25726b 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c @@ -192,7 +192,7 @@ static void __init of_cpu_clk_setup(struct device_node *node) goto clks_out; for_each_possible_cpu(cpu) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk *clk; char *clk_name = kzalloc(5, GFP_KERNEL); diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c index fe7224162b3c..d4ee785c6511 100644 --- a/drivers/clk/mxs/clk-div.c +++ b/drivers/clk/mxs/clk-div.c @@ -70,9 +70,9 @@ static const struct clk_ops clk_div_ops = { struct clk *mxs_clk_div(const char *name, const char *parent_name, void __iomem *reg, u8 shift, u8 width, u8 busy) { + struct clk_init_data init = {}; struct clk_div *div; struct clk *clk; - struct clk_init_data init; div = kzalloc_obj(*div); if (!div) diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c index 52eb82fde322..e317710ab503 100644 --- a/drivers/clk/mxs/clk-frac.c +++ b/drivers/clk/mxs/clk-frac.c @@ -112,9 +112,9 @@ static const struct clk_ops clk_frac_ops = { struct clk *mxs_clk_frac(const char *name, const char *parent_name, void __iomem *reg, u8 shift, u8 width, u8 busy) { + struct clk_init_data init = {}; struct clk_frac *frac; struct clk *clk; - struct clk_init_data init; frac = kzalloc_obj(*frac); if (!frac) diff --git a/drivers/clk/mxs/clk-pll.c b/drivers/clk/mxs/clk-pll.c index 581868e0693c..5acf48cddbb2 100644 --- a/drivers/clk/mxs/clk-pll.c +++ b/drivers/clk/mxs/clk-pll.c @@ -82,9 +82,9 @@ static const struct clk_ops clk_pll_ops = { struct clk *mxs_clk_pll(const char *name, const char *parent_name, void __iomem *base, u8 power, unsigned long rate) { + struct clk_init_data init = {}; struct clk_pll *pll; struct clk *clk; - struct clk_init_data init; pll = kzalloc_obj(*pll); if (!pll) diff --git a/drivers/clk/mxs/clk-ref.c b/drivers/clk/mxs/clk-ref.c index 9667d4d3c2a8..66ea1c229014 100644 --- a/drivers/clk/mxs/clk-ref.c +++ b/drivers/clk/mxs/clk-ref.c @@ -113,9 +113,9 @@ static const struct clk_ops clk_ref_ops = { struct clk *mxs_clk_ref(const char *name, const char *parent_name, void __iomem *reg, u8 idx) { + struct clk_init_data init = {}; struct clk_ref *ref; struct clk *clk; - struct clk_init_data init; ref = kzalloc_obj(*ref); if (!ref) diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c index 9f65d0623517..c914079cee2d 100644 --- a/drivers/clk/nuvoton/clk-ma35d1.c +++ b/drivers/clk/nuvoton/clk-ma35d1.c @@ -17,6 +17,7 @@ static DEFINE_SPINLOCK(ma35d1_lock); #define PLL_MAX_NUM 5 +#define MA35D1_CLK_COUNT 238 /* Clock Control Registers Offset */ #define REG_CLK_PWRCTL 0x00 @@ -467,12 +468,12 @@ static int ma35d1_clocks_probe(struct platform_device *pdev) int ret; ma35d1_hw_data = devm_kzalloc(dev, - struct_size(ma35d1_hw_data, hws, CLK_MAX_IDX), + struct_size(ma35d1_hw_data, hws, MA35D1_CLK_COUNT), GFP_KERNEL); if (!ma35d1_hw_data) return -ENOMEM; - ma35d1_hw_data->num = CLK_MAX_IDX; + ma35d1_hw_data->num = MA35D1_CLK_COUNT; hws = ma35d1_hw_data->hws; clk_base = devm_platform_ioremap_resource(pdev, 0); @@ -543,6 +544,8 @@ static int ma35d1_clocks_probe(struct platform_device *pdev) hws[HCLK3] = ma35d1_clk_fixed_factor(dev, "hclk3", "sysclk1_mux", 1, 2); hws[PCLK3] = ma35d1_clk_fixed_factor(dev, "pclk3", "sysclk1_mux", 1, 2); hws[PCLK4] = ma35d1_clk_fixed_factor(dev, "pclk4", "sysclk1_mux", 1, 2); + hws[PCLK3_DIV4096] = ma35d1_clk_fixed_factor(dev, "pclk3_div4096", "pclk3", 1, 4096); + hws[PCLK4_DIV4096] = ma35d1_clk_fixed_factor(dev, "pclk4_div4096", "pclk4", 1, 4096); hws[USBPHY0] = ma35d1_clk_fixed("usbphy0", 480000000); hws[USBPHY1] = ma35d1_clk_fixed("usbphy1", 480000000); diff --git a/drivers/clk/nxp/clk-lpc18xx-creg.c b/drivers/clk/nxp/clk-lpc18xx-creg.c index 3d3982e9c661..de3c214a80fc 100644 --- a/drivers/clk/nxp/clk-lpc18xx-creg.c +++ b/drivers/clk/nxp/clk-lpc18xx-creg.c @@ -138,7 +138,7 @@ static struct clk *clk_register_creg_clk(struct device *dev, const char **parent_name, struct regmap *syscon) { - struct clk_init_data init; + struct clk_init_data init = {}; init.ops = creg_clk->ops; init.name = creg_clk->name; diff --git a/drivers/clk/pistachio/clk-pll.c b/drivers/clk/pistachio/clk-pll.c index 5b268a985a9c..ad997a777632 100644 --- a/drivers/clk/pistachio/clk-pll.c +++ b/drivers/clk/pistachio/clk-pll.c @@ -453,8 +453,8 @@ static struct clk *pll_register(const char *name, const char *parent_name, struct pistachio_pll_rate_table *rates, unsigned int nr_rates) { + struct clk_init_data init = {}; struct pistachio_clk_pll *pll; - struct clk_init_data init; struct clk *clk; pll = kzalloc_obj(*pll); diff --git a/drivers/clk/pistachio/clk.c b/drivers/clk/pistachio/clk.c index 80c722c77a1b..03e28779011f 100644 --- a/drivers/clk/pistachio/clk.c +++ b/drivers/clk/pistachio/clk.c @@ -17,28 +17,21 @@ pistachio_clk_alloc_provider(struct device_node *node, unsigned int num_clks) { struct pistachio_clk_provider *p; - p = kzalloc_obj(*p); + p = kzalloc_flex(*p, clks, num_clks); if (!p) return p; - p->clk_data.clks = kzalloc_objs(struct clk *, num_clks); - if (!p->clk_data.clks) - goto free_provider; + p->clk_data.clks = p->clks; p->clk_data.clk_num = num_clks; p->node = node; p->base = of_iomap(node, 0); if (!p->base) { pr_err("Failed to map clock provider registers\n"); - goto free_clks; + kfree(p); + return NULL; } return p; - -free_clks: - kfree(p->clk_data.clks); -free_provider: - kfree(p); - return NULL; } void pistachio_clk_register_provider(struct pistachio_clk_provider *p) diff --git a/drivers/clk/pistachio/clk.h b/drivers/clk/pistachio/clk.h index 2f4ffbd98282..1b9b311b9656 100644 --- a/drivers/clk/pistachio/clk.h +++ b/drivers/clk/pistachio/clk.h @@ -142,6 +142,7 @@ struct pistachio_clk_provider { struct device_node *node; void __iomem *base; struct clk_onecell_data clk_data; + struct clk *clks[]; }; extern struct pistachio_clk_provider * diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index d1fc9bf87126..27d0ab24d50a 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -19,6 +19,17 @@ menuconfig COMMON_CLK_QCOM if COMMON_CLK_QCOM +config CLK_ELIZA_CAMCC + tristate "Eliza Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_ELIZA_GCC + default m if ARCH_QCOM + help + Support for the camera clock controller on Qualcomm Technologies, Inc + Eliza devices. + Say Y if you want to support camera devices and functionality such as + capturing pictures. + config CLK_ELIZA_DISPCC tristate "Eliza Display Clock Controller" depends on ARM64 || COMPILE_TEST @@ -39,6 +50,16 @@ config CLK_ELIZA_GCC Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDCC, etc. +config CLK_ELIZA_GPUCC + tristate "Eliza Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_ELIZA_GCC + default m if ARCH_QCOM + help + Support for the graphics clock controller on Eliza devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config CLK_ELIZA_TCSRCC tristate "Eliza TCSR Clock Controller" depends on ARM64 || COMPILE_TEST @@ -59,6 +80,16 @@ config CLK_GLYMUR_CAMCC Say Y if you want to support camera devices and functionality such as capturing pictures. +config CLK_ELIZA_VIDEOCC + tristate "Eliza Video Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_ELIZA_GCC + default m if ARCH_QCOM + help + Support for the video clock controller on Eliza devices. + Say Y if you want to support video devices and functionality such as + video encode and decode. + config CLK_GLYMUR_DISPCC tristate "Glymur Display Clock Controller" depends on ARM64 || COMPILE_TEST @@ -73,7 +104,6 @@ config CLK_GLYMUR_DISPCC 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 @@ -96,6 +126,7 @@ config CLK_GLYMUR_GPUCC tristate "Glymur Graphics Clock Controller" depends on ARM64 || COMPILE_TEST select CLK_GLYMUR_GCC + default m if ARCH_QCOM help Support for the graphics clock controller on Glymur devices. Say Y if you want to support graphics controller devices and @@ -181,6 +212,27 @@ config CLK_KAANAPALI_VIDEOCC Say Y if you want to support video devices and functionality such as video encode/decode. +config CLK_KUNO_GCC + tristate "Kuno Global Clock Controller" + depends on ARM || COMPILE_TEST + select QCOM_GDSC + default ARCH_QCOM + help + Support for the global clock controller (GCC) on Kuno devices. + Say Y if you want to use peripheral devices such as UART, SPI, + I2C, USB, SD, PCIe and Ethernet on the Kuno SoC. This clock + controller supplies the clocks and resets to those peripherals. + +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_DISPCC tristate "Nord Display Clock Controller" depends on ARM64 || COMPILE_TEST @@ -192,15 +244,16 @@ config CLK_NORD_DISPCC Say Y if you want to support display devices and functionality such as splash screen. -config CLK_MAILI_VIDEOCC - tristate "Maili Video Clock Controller" +config CLK_NORD_CAMCC + tristate "Nord Camera Clock Controller" depends on ARM64 || COMPILE_TEST - select CLK_HAWI_GCC + select CLK_NORD_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. + Support for the camera clock controller on Qualcomm Technologies, Inc + Nord devices. + Say Y if you want to support camera devices and functionality such as + capturing pictures. config CLK_NORD_GCC tristate "Nord Global Clock Controller" @@ -213,26 +266,6 @@ config CLK_NORD_GCC 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 @@ -244,6 +277,45 @@ config CLK_NORD_GPUCC Say Y if you want to support graphics controller devices and functionality such as 3D graphics. +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. + +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_NORD_VIDEOCC + tristate "Nord VIDEO Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_NORD_GCC + default m if ARCH_QCOM + help + Support for the video clock controller on Qualcomm Technologies, Inc. + Nord devices. + Say Y if you want to support video devices and functionality such as + video encode/decode. + +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_X1E80100_CAMCC tristate "X1E80100 Camera Clock Controller" depends on ARM64 || COMPILE_TEST @@ -423,6 +495,17 @@ config QCOM_CLK_RPMH Say Y if you want to support the clocks exposed by RPMh on platforms such as SDM845. +config CLK_HAWI_CAMCC + tristate "Hawi Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_HAWI_GCC + default m if ARCH_QCOM + help + Support for the camera clock controller on Qualcomm Technologies, Inc + Hawi devices. + Say Y if you want to support camera devices and functionality such as + capturing pictures. + config CLK_HAWI_GCC tristate "Hawi Global Clock Controller" depends on ARM64 || COMPILE_TEST @@ -433,6 +516,18 @@ config CLK_HAWI_GCC Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SD/eMMC, PCIe, etc. +config CLK_HAWI_GPUCC + tristate "Hawi Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_HAWI_GCC + default m if ARCH_QCOM + help + Support for the graphics clock controller on Hawi devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. It also provides GX clock + domain control required for GPU power management on Hawi-based + devices. + config CLK_HAWI_TCSRCC tristate "Hawi TCSR Clock Controller" depends on ARM64 || COMPILE_TEST @@ -694,6 +789,16 @@ config MSM_GCC_8939 Say Y if you want to use devices such as UART, SPI i2c, USB, SD/eMMC, display, graphics, camera etc. +config MSM_GCC_8952 + tristate "MSM8952 Global Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + default ARCH_QCOM + help + Support for the global clock controller on MSM8952 devices. + Say Y if you want to use devices such as UART, SPI i2c, USB, + SD/eMMC, display, graphics, camera etc. + config MSM_GCC_8960 tristate "APQ8064/MSM8960 Global Clock Controller" depends on ARM || COMPILE_TEST @@ -895,14 +1000,6 @@ config QCS_GCC_404 Say Y if you want to use multimedia devices or peripheral devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc. -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. - config SA_CAMCC_8775P tristate "SA8775P Camera Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index daf25d583be2..6affb5073f26 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -21,9 +21,12 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o # Keep alphabetically sorted by config obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o +obj-$(CONFIG_CLK_ELIZA_CAMCC) += cambistmclkcc-eliza.o camcc-eliza.o obj-$(CONFIG_CLK_ELIZA_DISPCC) += dispcc-eliza.o obj-$(CONFIG_CLK_ELIZA_GCC) += gcc-eliza.o +obj-$(CONFIG_CLK_ELIZA_GPUCC) += gpucc-eliza.o obj-$(CONFIG_CLK_ELIZA_TCSRCC) += tcsrcc-eliza.o +obj-$(CONFIG_CLK_ELIZA_VIDEOCC) += videocc-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 @@ -32,7 +35,9 @@ 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_CAMCC) += cambistmclkcc-kaanapali.o camcc-hawi.o obj-$(CONFIG_CLK_HAWI_GCC) += gcc-hawi.o +obj-$(CONFIG_CLK_HAWI_GPUCC) += gpucc-hawi.o gxclkctl-kaanapali.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 @@ -41,11 +46,14 @@ 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_KUNO_GCC) += gcc-kuno.o obj-$(CONFIG_CLK_MAILI_VIDEOCC) += videocc-maili.o +obj-$(CONFIG_CLK_NORD_CAMCC) += camcc-nord.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_NORD_VIDEOCC) += videocc-glymur.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 @@ -82,6 +90,7 @@ obj-$(CONFIG_MSM_GCC_8909) += gcc-msm8909.o obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o obj-$(CONFIG_MSM_GCC_8917) += gcc-msm8917.o obj-$(CONFIG_MSM_GCC_8939) += gcc-msm8939.o +obj-$(CONFIG_MSM_GCC_8952) += gcc-msm8952.o obj-$(CONFIG_MSM_GCC_8953) += gcc-msm8953.o obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o diff --git a/drivers/clk/qcom/cambistmclkcc-eliza.c b/drivers/clk/qcom/cambistmclkcc-eliza.c new file mode 100644 index 000000000000..5cb68b81095e --- /dev/null +++ b/drivers/clk/qcom/cambistmclkcc-eliza.c @@ -0,0 +1,464 @@ +// 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_AHB_CLK, +}; + +enum { + P_BI_TCXO, + P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, + P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, + P_SLEEP_CLK, +}; + +static const struct pll_vco rivian_ole_vco[] = { + { 777000000, 1285000000, 0 }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_bist_mclk_cc_pll0_config = { + .l = 0x32, + .cal_l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x10000030, + .config_ctl_hi_val = 0x80890263, + .config_ctl_hi1_val = 0x00000217, + .user_ctl_val = 0x00000001, + .user_ctl_hi_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_bist_mclk_cc_pll0 = { + .offset = 0x0, + .config = &cam_bist_mclk_cc_pll0_config, + .vco_table = rivian_ole_vco, + .num_vco = ARRAY_SIZE(rivian_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_EVO], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_rivian_evo_ops, + }, + }, +}; + +static const struct parent_map cam_bist_mclk_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 3 }, + { P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data cam_bist_mclk_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, + { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, +}; + +static const struct parent_map cam_bist_mclk_cc_parent_map_1[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data cam_bist_mclk_cc_parent_data_1[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_cam_bist_mclk_cc_mclk0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 4), + F(68571429, P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 14, 0, 0), + { } +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk0_clk_src = { + .cmd_rcgr = 0x4000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk0_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk1_clk_src = { + .cmd_rcgr = 0x401c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk1_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk2_clk_src = { + .cmd_rcgr = 0x4038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk2_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk3_clk_src = { + .cmd_rcgr = 0x4054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk3_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk4_clk_src = { + .cmd_rcgr = 0x4070, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk4_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk5_clk_src = { + .cmd_rcgr = 0x408c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk5_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk6_clk_src = { + .cmd_rcgr = 0x40a8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk6_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk7_clk_src = { + .cmd_rcgr = 0x40c4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk7_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_bist_mclk_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_bist_mclk_cc_sleep_clk_src = { + .cmd_rcgr = 0x40e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_1, + .freq_tbl = ftbl_cam_bist_mclk_cc_sleep_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_sleep_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk0_clk = { + .halt_reg = 0x4018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk1_clk = { + .halt_reg = 0x4034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk2_clk = { + .halt_reg = 0x4050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk3_clk = { + .halt_reg = 0x406c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x406c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk4_clk = { + .halt_reg = 0x4088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk5_clk = { + .halt_reg = 0x40a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk6_clk = { + .halt_reg = 0x40c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk6_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk7_clk = { + .halt_reg = 0x40dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk7_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *cam_bist_mclk_cc_eliza_clocks[] = { + [CAM_BIST_MCLK_CC_MCLK0_CLK] = &cam_bist_mclk_cc_mclk0_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK0_CLK_SRC] = &cam_bist_mclk_cc_mclk0_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK1_CLK] = &cam_bist_mclk_cc_mclk1_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK1_CLK_SRC] = &cam_bist_mclk_cc_mclk1_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK2_CLK] = &cam_bist_mclk_cc_mclk2_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK2_CLK_SRC] = &cam_bist_mclk_cc_mclk2_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK3_CLK] = &cam_bist_mclk_cc_mclk3_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK3_CLK_SRC] = &cam_bist_mclk_cc_mclk3_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK4_CLK] = &cam_bist_mclk_cc_mclk4_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK4_CLK_SRC] = &cam_bist_mclk_cc_mclk4_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK5_CLK] = &cam_bist_mclk_cc_mclk5_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK5_CLK_SRC] = &cam_bist_mclk_cc_mclk5_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK6_CLK] = &cam_bist_mclk_cc_mclk6_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK6_CLK_SRC] = &cam_bist_mclk_cc_mclk6_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK7_CLK] = &cam_bist_mclk_cc_mclk7_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK7_CLK_SRC] = &cam_bist_mclk_cc_mclk7_clk_src.clkr, + [CAM_BIST_MCLK_CC_PLL0] = &cam_bist_mclk_cc_pll0.clkr, + [CAM_BIST_MCLK_CC_SLEEP_CLK_SRC] = &cam_bist_mclk_cc_sleep_clk_src.clkr, +}; + +static struct clk_alpha_pll *cam_bist_mclk_cc_eliza_plls[] = { + &cam_bist_mclk_cc_pll0, +}; + +static const u32 cam_bist_mclk_cc_eliza_critical_cbcrs[] = { + 0x40f8, /* CAM_BIST_MCLK_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_bist_mclk_cc_eliza_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x5010, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data cam_bist_mclk_cc_eliza_driver_data = { + .alpha_plls = cam_bist_mclk_cc_eliza_plls, + .num_alpha_plls = ARRAY_SIZE(cam_bist_mclk_cc_eliza_plls), + .clk_cbcrs = cam_bist_mclk_cc_eliza_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_bist_mclk_cc_eliza_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_bist_mclk_cc_eliza_desc = { + .config = &cam_bist_mclk_cc_eliza_regmap_config, + .clks = cam_bist_mclk_cc_eliza_clocks, + .num_clks = ARRAY_SIZE(cam_bist_mclk_cc_eliza_clocks), + .use_rpm = true, + .driver_data = &cam_bist_mclk_cc_eliza_driver_data, +}; + +static const struct of_device_id cam_bist_mclk_cc_eliza_match_table[] = { + { .compatible = "qcom,eliza-cambistmclkcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_bist_mclk_cc_eliza_match_table); + +static int cam_bist_mclk_cc_eliza_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_bist_mclk_cc_eliza_desc); +} + +static struct platform_driver cam_bist_mclk_cc_eliza_driver = { + .probe = cam_bist_mclk_cc_eliza_probe, + .driver = { + .name = "cambistmclkcc-eliza", + .of_match_table = cam_bist_mclk_cc_eliza_match_table, + }, +}; + +module_platform_driver(cam_bist_mclk_cc_eliza_driver); + +MODULE_DESCRIPTION("QTI CAMBISTMCLKCC Eliza Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/cambistmclkcc-kaanapali.c b/drivers/clk/qcom/cambistmclkcc-kaanapali.c index c96e9196d908..b5bafc1e7d42 100644 --- a/drivers/clk/qcom/cambistmclkcc-kaanapali.c +++ b/drivers/clk/qcom/cambistmclkcc-kaanapali.c @@ -394,11 +394,18 @@ static const struct regmap_config cam_bist_mclk_cc_kaanapali_regmap_config = { .fast_io = true, }; +static void cam_bist_mclk_cc_kaanapali_regs_configure(struct device *dev, struct regmap *regmap) +{ + regmap_write(regmap, 0x18, 0); /* CAM_BIST_MCLK_CC_PLL0_USER_CTL_U */ + regmap_write(regmap, 0x28, 0); /* CAM_BIST_MCLK_CC_PLL0_CONFIG_CTL_U2 */ +} + static const struct qcom_cc_driver_data cam_bist_mclk_cc_kaanapali_driver_data = { .alpha_plls = cam_bist_mclk_cc_kaanapali_plls, .num_alpha_plls = ARRAY_SIZE(cam_bist_mclk_cc_kaanapali_plls), .clk_cbcrs = cam_bist_mclk_cc_kaanapali_critical_cbcrs, .num_clk_cbcrs = ARRAY_SIZE(cam_bist_mclk_cc_kaanapali_critical_cbcrs), + .clk_regs_configure = cam_bist_mclk_cc_kaanapali_regs_configure, }; static const struct qcom_cc_desc cam_bist_mclk_cc_kaanapali_desc = { diff --git a/drivers/clk/qcom/cambistmclkcc-sm8750.c b/drivers/clk/qcom/cambistmclkcc-sm8750.c index 69abb756c04f..45788ddb9dcc 100644 --- a/drivers/clk/qcom/cambistmclkcc-sm8750.c +++ b/drivers/clk/qcom/cambistmclkcc-sm8750.c @@ -413,11 +413,18 @@ static const struct regmap_config cam_bist_mclk_cc_sm8750_regmap_config = { .fast_io = true, }; +static void cam_bist_mclk_cc_sm8750_regs_configure(struct device *dev, struct regmap *regmap) +{ + regmap_write(regmap, 0x18, 0); /* CAM_BIST_MCLK_CC_PLL0_USER_CTL_U */ + regmap_write(regmap, 0x28, 0); /* CAM_BIST_MCLK_CC_PLL0_CONFIG_CTL_U2 */ +} + static const struct qcom_cc_driver_data cam_bist_mclk_cc_sm8750_driver_data = { .alpha_plls = cam_bist_mclk_cc_sm8750_plls, .num_alpha_plls = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_plls), .clk_cbcrs = cam_bist_mclk_cc_sm8750_critical_cbcrs, .num_clk_cbcrs = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_critical_cbcrs), + .clk_regs_configure = cam_bist_mclk_cc_sm8750_regs_configure, }; static const struct qcom_cc_desc cam_bist_mclk_cc_sm8750_desc = { diff --git a/drivers/clk/qcom/camcc-eliza.c b/drivers/clk/qcom/camcc-eliza.c new file mode 100644 index 000000000000..7348f4dde65a --- /dev/null +++ b/drivers/clk/qcom/camcc-eliza.c @@ -0,0 +1,2803 @@ +// 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_SLEEP_CLK, + DT_AHB_CLK, +}; + +enum { + P_BI_TCXO, + 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_PLL3_OUT_EVEN, + P_CAM_CC_PLL4_OUT_EVEN, + P_CAM_CC_PLL5_OUT_EVEN, + P_CAM_CC_PLL6_OUT_EVEN, + P_CAM_CC_PLL6_OUT_ODD, + P_SLEEP_CLK, +}; + +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + +/* 1200.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .cal_l = 0x44, + .alpha = 0x8000, + .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 = 0x00008400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .config = &cam_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 = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_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_LUCID_OLE], + .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_lucid_ole_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_LUCID_OLE], + .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_lucid_ole_ops, + }, +}; + +/* 900.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x2e, + .cal_l = 0x44, + .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 = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .config = &cam_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 = "cam_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 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_LUCID_OLE], + .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_lucid_ole_ops, + }, +}; + +/* 872.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x2d, + .cal_l = 0x44, + .alpha = 0x6aaa, + .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 = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .config = &cam_cc_pll2_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 = "cam_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll2_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { + .offset = 0x2000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll2_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll2_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll2_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +/* 890.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x2e, + .cal_l = 0x44, + .alpha = 0x5aaa, + .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 = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .config = &cam_cc_pll3_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 = "cam_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_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_LUCID_OLE], + .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_lucid_ole_ops, + }, +}; + +/* 890.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x2e, + .cal_l = 0x44, + .alpha = 0x5aaa, + .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 = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll4 = { + .offset = 0x4000, + .config = &cam_cc_pll4_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 = "cam_cc_pll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_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_LUCID_OLE], + .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_lucid_ole_ops, + }, +}; + +/* 890.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll5_config = { + .l = 0x2e, + .cal_l = 0x44, + .alpha = 0x5aaa, + .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 = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll5 = { + .offset = 0x5000, + .config = &cam_cc_pll5_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 = "cam_cc_pll5", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_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_LUCID_OLE], + .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_lucid_ole_ops, + }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll6_config = { + .l = 0x32, + .cal_l = 0x44, + .alpha = 0x0, + .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 = 0x00008400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll6 = { + .offset = 0x6000, + .config = &cam_cc_pll6_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 = "cam_cc_pll6", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_even = { + .offset = 0x6000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll6_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_odd = { + .offset = 0x6000, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll6_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_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_PLL6_OUT_ODD, 4 }, + { P_CAM_CC_PLL6_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_pll6_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_1[] = { + { 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_PLL6_OUT_ODD, 4 }, + { P_CAM_CC_PLL6_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .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_pll6_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL1_OUT_EVEN, 4 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll1_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll2_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_4[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_4[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map cam_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL3_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll4_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL5_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll5_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_8[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_8[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_rt_axi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 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_rt_axi_clk_src = { + .cmd_rcgr = 0x112e8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_camnoc_rt_axi_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_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(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .cmd_rcgr = 0x1126c, + .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 = 0x11288, + .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 struct clk_rcg2 cam_cc_cci_2_clk_src = { + .cmd_rcgr = 0x112a4, + .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_2_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(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 = 0x11068, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_cre_clk_src[] = { + 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_PLL6_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cre_clk_src = { + .cmd_rcgr = 0x111ac, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_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(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x10000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_csi1phytimer_clk_src = { + .cmd_rcgr = 0x10024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_csi2phytimer_clk_src = { + .cmd_rcgr = 0x10044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_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_csi3phytimer_clk_src = { + .cmd_rcgr = 0x10064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_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_csi4phytimer_clk_src = { + .cmd_rcgr = 0x10084, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_csi5phytimer_clk_src = { + .cmd_rcgr = 0x100a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_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_csid_clk_src = { + .cmd_rcgr = 0x112c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_fast_ahb_clk_src[] = { + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 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 = 0x100dc, + .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_0_clk_src[] = { + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_0_clk_src = { + .cmd_rcgr = 0x11214, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_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_icp_1_clk_src = { + .cmd_rcgr = 0x1123c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_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 struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .cmd_rcgr = 0x11150, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cphy_rx_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_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_ife_lite_csid_clk_src = { + .cmd_rcgr = 0x1117c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cphy_rx_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_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_ipe_nps_clk_src[] = { + F(450000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(575000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(825000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_nps_clk_src = { + .cmd_rcgr = 0x10190, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .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_2, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0x111d0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cre_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_ofe_clk_src[] = { + F(436000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(570000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(757000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ofe_clk_src = { + .cmd_rcgr = 0x1011c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ofe_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_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_qdss_debug_clk_src[] = { + F(60000000, P_CAM_CC_PLL6_OUT_EVEN, 8, 0, 0), + F(120000000, P_CAM_CC_PLL0_OUT_EVEN, 5, 0, 0), + F(240000000, P_CAM_CC_PLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qdss_debug_clk_src = { + .cmd_rcgr = 0x1132c, + .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 = 0x11380, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_4, + .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_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_slow_ahb_clk_src[] = { + F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { + .cmd_rcgr = 0x10100, + .mnd_width = 0, + .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_tfe_0_clk_src[] = { + F(445000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(567000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(644000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(785000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_0_clk_src = { + .cmd_rcgr = 0x11018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_tfe_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_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_tfe_1_clk_src[] = { + F(445000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(567000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(644000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(785000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_1_clk_src = { + .cmd_rcgr = 0x11098, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_6, + .freq_tbl = ftbl_cam_cc_tfe_1_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_clk_src", + .parent_data = cam_cc_parent_data_6, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_tfe_2_clk_src[] = { + F(445000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(567000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(644000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(785000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_2_clk_src = { + .cmd_rcgr = 0x11100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_7, + .freq_tbl = ftbl_cam_cc_tfe_2_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_clk_src", + .parent_data = cam_cc_parent_data_7, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_7), + .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, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_xo_clk_src = { + .cmd_rcgr = 0x11364, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_8, + .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_8, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch cam_cc_cam_top_ahb_clk = { + .halt_reg = 0x113ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x113ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_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_cam_top_fast_ahb_clk = { + .halt_reg = 0x1139c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1139c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_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_dcd_xo_clk = { + .halt_reg = 0x11320, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11320, + .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_nrt_axi_clk = { + .halt_reg = 0x11310, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x11310, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x11310, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_cre_clk = { + .halt_reg = 0x111c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ipe_nps_clk = { + .halt_reg = 0x101b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_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_camnoc_nrt_ofe_anchor_clk = { + .halt_reg = 0x10158, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10158, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ofe_anchor_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ofe_hdr_clk = { + .halt_reg = 0x1016c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1016c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ofe_hdr_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ofe_main_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_camnoc_nrt_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_axi_clk = { + .halt_reg = 0x11300, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11300, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_ife_lite_clk = { + .halt_reg = 0x11178, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11178, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_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_camnoc_rt_tfe_0_bayer_clk = { + .halt_reg = 0x11054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_0_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_0_main_clk = { + .halt_reg = 0x11040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_1_bayer_clk = { + .halt_reg = 0x110d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_1_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_1_main_clk = { + .halt_reg = 0x110c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_2_bayer_clk = { + .halt_reg = 0x1113c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1113c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_2_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_2_main_clk = { + .halt_reg = 0x11128, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11128, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_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 = 0x11324, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11324, + .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 = 0x11284, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11284, + .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 = 0x112a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x112a0, + .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_cci_2_clk = { + .halt_reg = 0x112bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x112bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_2_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 = 0x11360, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x11360, + .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_cre_ahb_clk = { + .halt_reg = 0x111cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_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_cre_clk = { + .halt_reg = 0x111c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_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 = 0x10018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10018, + .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 = 0x1003c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1003c, + .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_csi2phytimer_clk = { + .halt_reg = 0x1005c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1005c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi2phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi3phytimer_clk = { + .halt_reg = 0x1007c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1007c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi3phytimer_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 = 0x1009c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1009c, + .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_csi5phytimer_clk = { + .halt_reg = 0x100bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi5phytimer_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 = 0x112d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x112d8, + .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 = 0x10020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10020, + .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 = 0x1001c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1001c, + .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 = 0x10040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10040, + .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_csiphy2_clk = { + .halt_reg = 0x10060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy2_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_csiphy3_clk = { + .halt_reg = 0x10080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy3_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 = 0x100a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100a0, + .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_csiphy5_clk = { + .halt_reg = 0x100c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy5_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_drv_ahb_clk = { + .halt_reg = 0x113c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x113c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_drv_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_aon_ops, + }, + }, +}; + +static struct clk_branch cam_cc_drv_xo_clk = { + .halt_reg = 0x113c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x113c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_drv_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_aon_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_0_ahb_clk = { + .halt_reg = 0x11264, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11264, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_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_0_clk = { + .halt_reg = 0x1122c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1122c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_1_ahb_clk = { + .halt_reg = 0x11268, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11268, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_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_1_clk = { + .halt_reg = 0x11254, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11254, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_1_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 = 0x111a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111a8, + .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 = 0x11168, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11168, + .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 = 0x111a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111a4, + .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 = 0x11194, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11194, + .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 = 0x101d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101d4, + .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 = 0x101a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101a8, + .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 = 0x101d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101d8, + .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 = 0x101bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101bc, + .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 = 0x101dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101dc, + .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_0_clk = { + .halt_reg = 0x111e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_0_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_jpeg_1_clk = { + .halt_reg = 0x111f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_1_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_ofe_ahb_clk = { + .halt_reg = 0x10118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_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_ofe_anchor_clk = { + .halt_reg = 0x10148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10148, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_anchor_fast_ahb_clk = { + .halt_reg = 0x100f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_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_ofe_hdr_clk = { + .halt_reg = 0x1015c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1015c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_hdr_fast_ahb_clk = { + .halt_reg = 0x100fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_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_ofe_main_clk = { + .halt_reg = 0x10134, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_main_fast_ahb_clk = { + .halt_reg = 0x100f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_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_qdss_debug_clk = { + .halt_reg = 0x11344, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11344, + .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 = 0x11348, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11348, + .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 clk_branch cam_cc_tfe_0_bayer_clk = { + .halt_reg = 0x11044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_bayer_fast_ahb_clk = { + .halt_reg = 0x11064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_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_tfe_0_main_clk = { + .halt_reg = 0x11030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_main_fast_ahb_clk = { + .halt_reg = 0x11060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_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_tfe_1_bayer_clk = { + .halt_reg = 0x110c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_bayer_fast_ahb_clk = { + .halt_reg = 0x110e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_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_tfe_1_main_clk = { + .halt_reg = 0x110b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_main_fast_ahb_clk = { + .halt_reg = 0x110e0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_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_tfe_2_bayer_clk = { + .halt_reg = 0x1112c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1112c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_bayer_fast_ahb_clk = { + .halt_reg = 0x1114c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1114c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_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_tfe_2_main_clk = { + .halt_reg = 0x11118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_main_fast_ahb_clk = { + .halt_reg = 0x11148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11148, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_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 gdsc cam_cc_titan_top_gdsc = { + .gdscr = 0x1134c, + .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_ipe_0_gdsc = { + .gdscr = 0x1017c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ipe_0_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ofe_gdsc = { + .gdscr = 0x100c8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ofe_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_tfe_0_gdsc = { + .gdscr = 0x11004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_0_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_tfe_1_gdsc = { + .gdscr = 0x11084, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_1_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_tfe_2_gdsc = { + .gdscr = 0x110ec, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_2_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *cam_cc_eliza_clocks[] = { + [CAM_CC_CAM_TOP_AHB_CLK] = &cam_cc_cam_top_ahb_clk.clkr, + [CAM_CC_CAM_TOP_FAST_AHB_CLK] = &cam_cc_cam_top_fast_ahb_clk.clkr, + [CAM_CC_CAMNOC_DCD_XO_CLK] = &cam_cc_camnoc_dcd_xo_clk.clkr, + [CAM_CC_CAMNOC_NRT_AXI_CLK] = &cam_cc_camnoc_nrt_axi_clk.clkr, + [CAM_CC_CAMNOC_NRT_CRE_CLK] = &cam_cc_camnoc_nrt_cre_clk.clkr, + [CAM_CC_CAMNOC_NRT_IPE_NPS_CLK] = &cam_cc_camnoc_nrt_ipe_nps_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_ANCHOR_CLK] = &cam_cc_camnoc_nrt_ofe_anchor_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_HDR_CLK] = &cam_cc_camnoc_nrt_ofe_hdr_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK] = &cam_cc_camnoc_nrt_ofe_main_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK] = &cam_cc_camnoc_rt_axi_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK_SRC] = &cam_cc_camnoc_rt_axi_clk_src.clkr, + [CAM_CC_CAMNOC_RT_IFE_LITE_CLK] = &cam_cc_camnoc_rt_ife_lite_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_0_BAYER_CLK] = &cam_cc_camnoc_rt_tfe_0_bayer_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_0_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_1_BAYER_CLK] = &cam_cc_camnoc_rt_tfe_1_bayer_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_1_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_2_BAYER_CLK] = &cam_cc_camnoc_rt_tfe_2_bayer_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_2_main_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_CCI_2_CLK] = &cam_cc_cci_2_clk.clkr, + [CAM_CC_CCI_2_CLK_SRC] = &cam_cc_cci_2_clk_src.clkr, + [CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CRE_AHB_CLK] = &cam_cc_cre_ahb_clk.clkr, + [CAM_CC_CRE_CLK] = &cam_cc_cre_clk.clkr, + [CAM_CC_CRE_CLK_SRC] = &cam_cc_cre_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_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr, + [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr, + [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr, + [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_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_CSI5PHYTIMER_CLK] = &cam_cc_csi5phytimer_clk.clkr, + [CAM_CC_CSI5PHYTIMER_CLK_SRC] = &cam_cc_csi5phytimer_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_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr, + [CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr, + [CAM_CC_CSIPHY4_CLK] = &cam_cc_csiphy4_clk.clkr, + [CAM_CC_CSIPHY5_CLK] = &cam_cc_csiphy5_clk.clkr, + [CAM_CC_DRV_AHB_CLK] = &cam_cc_drv_ahb_clk.clkr, + [CAM_CC_DRV_XO_CLK] = &cam_cc_drv_xo_clk.clkr, + [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, + [CAM_CC_ICP_0_AHB_CLK] = &cam_cc_icp_0_ahb_clk.clkr, + [CAM_CC_ICP_0_CLK] = &cam_cc_icp_0_clk.clkr, + [CAM_CC_ICP_0_CLK_SRC] = &cam_cc_icp_0_clk_src.clkr, + [CAM_CC_ICP_1_AHB_CLK] = &cam_cc_icp_1_ahb_clk.clkr, + [CAM_CC_ICP_1_CLK] = &cam_cc_icp_1_clk.clkr, + [CAM_CC_ICP_1_CLK_SRC] = &cam_cc_icp_1_clk_src.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_0_CLK] = &cam_cc_jpeg_0_clk.clkr, + [CAM_CC_JPEG_1_CLK] = &cam_cc_jpeg_1_clk.clkr, + [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr, + [CAM_CC_OFE_AHB_CLK] = &cam_cc_ofe_ahb_clk.clkr, + [CAM_CC_OFE_ANCHOR_CLK] = &cam_cc_ofe_anchor_clk.clkr, + [CAM_CC_OFE_ANCHOR_FAST_AHB_CLK] = &cam_cc_ofe_anchor_fast_ahb_clk.clkr, + [CAM_CC_OFE_CLK_SRC] = &cam_cc_ofe_clk_src.clkr, + [CAM_CC_OFE_HDR_CLK] = &cam_cc_ofe_hdr_clk.clkr, + [CAM_CC_OFE_HDR_FAST_AHB_CLK] = &cam_cc_ofe_hdr_fast_ahb_clk.clkr, + [CAM_CC_OFE_MAIN_CLK] = &cam_cc_ofe_main_clk.clkr, + [CAM_CC_OFE_MAIN_FAST_AHB_CLK] = &cam_cc_ofe_main_fast_ahb_clk.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_PLL2_OUT_EVEN] = &cam_cc_pll2_out_even.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_PLL6] = &cam_cc_pll6.clkr, + [CAM_CC_PLL6_OUT_EVEN] = &cam_cc_pll6_out_even.clkr, + [CAM_CC_PLL6_OUT_ODD] = &cam_cc_pll6_out_odd.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_TFE_0_BAYER_CLK] = &cam_cc_tfe_0_bayer_clk.clkr, + [CAM_CC_TFE_0_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_0_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_0_CLK_SRC] = &cam_cc_tfe_0_clk_src.clkr, + [CAM_CC_TFE_0_MAIN_CLK] = &cam_cc_tfe_0_main_clk.clkr, + [CAM_CC_TFE_0_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_0_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_BAYER_CLK] = &cam_cc_tfe_1_bayer_clk.clkr, + [CAM_CC_TFE_1_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_1_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_CLK_SRC] = &cam_cc_tfe_1_clk_src.clkr, + [CAM_CC_TFE_1_MAIN_CLK] = &cam_cc_tfe_1_main_clk.clkr, + [CAM_CC_TFE_1_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_1_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_BAYER_CLK] = &cam_cc_tfe_2_bayer_clk.clkr, + [CAM_CC_TFE_2_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_2_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_CLK_SRC] = &cam_cc_tfe_2_clk_src.clkr, + [CAM_CC_TFE_2_MAIN_CLK] = &cam_cc_tfe_2_main_clk.clkr, + [CAM_CC_TFE_2_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_2_main_fast_ahb_clk.clkr, + [CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr, +}; + +static struct gdsc *cam_cc_eliza_gdscs[] = { + [CAM_CC_IPE_0_GDSC] = &cam_cc_ipe_0_gdsc, + [CAM_CC_OFE_GDSC] = &cam_cc_ofe_gdsc, + [CAM_CC_TFE_0_GDSC] = &cam_cc_tfe_0_gdsc, + [CAM_CC_TFE_1_GDSC] = &cam_cc_tfe_1_gdsc, + [CAM_CC_TFE_2_GDSC] = &cam_cc_tfe_2_gdsc, + [CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc, +}; + +static const struct qcom_reset_map cam_cc_eliza_resets[] = { + [CAM_CC_DRV_BCR] = { 0x113bc }, + [CAM_CC_ICP_BCR] = { 0x11210 }, + [CAM_CC_IPE_0_BCR] = { 0x10178 }, + [CAM_CC_OFE_BCR] = { 0x100c4 }, + [CAM_CC_QDSS_DEBUG_BCR] = { 0x11328 }, + [CAM_CC_TFE_0_BCR] = { 0x11000 }, + [CAM_CC_TFE_1_BCR] = { 0x11080 }, + [CAM_CC_TFE_2_BCR] = { 0x110e8 }, +}; + +static struct clk_alpha_pll *cam_cc_eliza_plls[] = { + &cam_cc_pll0, + &cam_cc_pll1, + &cam_cc_pll2, + &cam_cc_pll3, + &cam_cc_pll4, + &cam_cc_pll5, + &cam_cc_pll6, +}; + +static const u32 cam_cc_eliza_critical_cbcrs[] = { + 0x1137c, /* CAM_CC_GDSC_CLK */ + 0x11398, /* CAM_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_cc_eliza_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1601c, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data cam_cc_eliza_driver_data = { + .alpha_plls = cam_cc_eliza_plls, + .num_alpha_plls = ARRAY_SIZE(cam_cc_eliza_plls), + .clk_cbcrs = cam_cc_eliza_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_eliza_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_cc_eliza_desc = { + .config = &cam_cc_eliza_regmap_config, + .clks = cam_cc_eliza_clocks, + .num_clks = ARRAY_SIZE(cam_cc_eliza_clocks), + .resets = cam_cc_eliza_resets, + .num_resets = ARRAY_SIZE(cam_cc_eliza_resets), + .gdscs = cam_cc_eliza_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_eliza_gdscs), + .use_rpm = true, + .driver_data = &cam_cc_eliza_driver_data, +}; + +static const struct of_device_id cam_cc_eliza_match_table[] = { + { .compatible = "qcom,eliza-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_eliza_match_table); + +static int cam_cc_eliza_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_cc_eliza_desc); +} + +static struct platform_driver cam_cc_eliza_driver = { + .probe = cam_cc_eliza_probe, + .driver = { + .name = "camcc-eliza", + .of_match_table = cam_cc_eliza_match_table, + }, +}; + +module_platform_driver(cam_cc_eliza_driver); + +MODULE_DESCRIPTION("QTI CAMCC Eliza Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-glymur.c b/drivers/clk/qcom/camcc-glymur.c index 81c1e102b110..6d022bbd2ce2 100644 --- a/drivers/clk/qcom/camcc-glymur.c +++ b/drivers/clk/qcom/camcc-glymur.c @@ -2235,11 +2235,18 @@ static const struct regmap_config cam_cc_glymur_regmap_config = { .fast_io = true, }; +static void cam_cc_glymur_regs_configure(struct device *dev, struct regmap *regmap) +{ + regmap_write(regmap, 0x2018, 0); /* CAM_CC_PLL2_PLL_USER_CTL_U */ + regmap_write(regmap, 0x2028, 0); /* CAM_CC_PLL2_PLL_CONFIG_CTL_U2 */ +} + 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), + .clk_regs_configure = cam_cc_glymur_regs_configure, }; static const struct qcom_cc_desc cam_cc_glymur_desc = { diff --git a/drivers/clk/qcom/camcc-hawi.c b/drivers/clk/qcom/camcc-hawi.c new file mode 100644 index 000000000000..9842a9a4bf85 --- /dev/null +++ b/drivers/clk/qcom/camcc-hawi.c @@ -0,0 +1,3152 @@ +// 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_AHB_CLK, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +/* Need to match the order of interconnects in DT binding */ +enum { + DT_ICC_TOP_GDSC, +}; + +enum { + P_BI_TCXO, + 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_PLL3_OUT_EVEN, + P_CAM_CC_PLL4_OUT_EVEN, + P_CAM_CC_PLL5_OUT_EVEN, + P_CAM_CC_PLL6_OUT_EVEN, + P_CAM_CC_PLL6_OUT_MAIN, + P_CAM_CC_PLL6_OUT_ODD, + P_CAM_CC_PLL7_OUT_EVEN, + P_CAM_CC_PLL7_OUT_MAIN, + P_CAM_CC_PLL8_OUT_EVEN, +}; + +static const struct pll_vco taycan_eha_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 = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00008400, + .user_ctl_hi_val = 0x00000002, +}; + +/* 1200.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll0_config_maili = { + .l = 0x3e, + .cal_l = 0x42, + .alpha = 0x8000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a806160, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00008400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .config = &cam_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 = "cam_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_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_EHA_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_eha_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_EHA_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_eha_t_ops, + }, +}; + +/* 493.2 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x19, + .alpha = 0xb000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +/* 493.2 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll1_config_maili = { + .l = 0x19, + .cal_l = 0x42, + .alpha = 0xb000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a806160, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .config = &cam_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 = "cam_cc_pll1", + .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_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_EHA_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_eha_t_ops, + }, +}; + +/* 451.2 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x17, + .alpha = 0x8000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +/* 600.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll2_config_maili = { + .l = 0x1f, + .cal_l = 0x42, + .alpha = 0x4000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a806160, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .config = &cam_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 = "cam_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 clk_div_table post_div_table_cam_cc_pll2_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { + .offset = 0x2000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll2_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll2_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 = "cam_cc_pll2_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eha_t_ops, + }, +}; + +/* 476.4 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x18, + .alpha = 0xd000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +/* 476.4 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll3_config_maili = { + .l = 0x18, + .cal_l = 0x42, + .alpha = 0xd000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a806160, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .config = &cam_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 = "cam_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 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_EHA_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_eha_t_ops, + }, +}; + +/* 476.4 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x18, + .alpha = 0xd000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +/* 476.4 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll4_config_maili = { + .l = 0x18, + .cal_l = 0x42, + .alpha = 0xd000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a806160, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll4 = { + .offset = 0x4000, + .config = &cam_cc_pll4_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 = "cam_cc_pll4", + .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_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_EHA_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_eha_t_ops, + }, +}; + +/* 476.4 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll5_config = { + .l = 0x18, + .alpha = 0xd000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +/* 476.4 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll5_config_maili = { + .l = 0x18, + .cal_l = 0x42, + .alpha = 0xd000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a806160, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll5 = { + .offset = 0x5000, + .config = &cam_cc_pll5_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 = "cam_cc_pll5", + .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_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_EHA_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_eha_t_ops, + }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll6_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00008400, + .user_ctl_hi_val = 0x00000002, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll6_config_maili = { + .l = 0x32, + .cal_l = 0x42, + .alpha = 0x0, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a806160, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00008400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll6 = { + .offset = 0x6000, + .config = &cam_cc_pll6_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 = "cam_cc_pll6", + .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_cam_cc_pll6_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_even = { + .offset = 0x6000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll6_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_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 = "cam_cc_pll6_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eha_t_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_odd = { + .offset = 0x6000, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll6_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EHA_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eha_t_ops, + }, +}; + +/* 345.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll7_config = { + .l = 0x11, + .alpha = 0xf800, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +/* 345.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll7_config_maili = { + .l = 0x11, + .cal_l = 0x42, + .alpha = 0xf800, + .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 cam_cc_pll7 = { + .offset = 0x7000, + .config = &cam_cc_pll7_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 = "cam_cc_pll7", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eha_t_ops, + }, + }, +}; + +/* 493.2 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll8_config = { + .l = 0x19, + .alpha = 0xb000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +/* 493.2 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll8_config_maili = { + .l = 0x19, + .cal_l = 0x42, + .alpha = 0xb000, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a806160, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll8 = { + .offset = 0x8000, + .config = &cam_cc_pll8_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 = "cam_cc_pll8", + .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_cam_cc_pll8_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll8_out_even = { + .offset = 0x8000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll8_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll8_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 = "cam_cc_pll8_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll8.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eha_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_PLL6_OUT_ODD, 4 }, + { P_CAM_CC_PLL6_OUT_EVEN, 5 }, + { P_CAM_CC_PLL6_OUT_MAIN, 6 }, +}; + +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_pll6_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, + { .hw = &cam_cc_pll6.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_1[] = { + { 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_PLL6_OUT_ODD, 4 }, + { P_CAM_CC_PLL6_OUT_EVEN, 5 }, + { P_CAM_CC_PLL6_OUT_MAIN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .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_pll6_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, + { .hw = &cam_cc_pll6.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_2[] = { + { 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_PLL7_OUT_EVEN, 5 }, + { P_CAM_CC_PLL7_OUT_MAIN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_2[] = { + { .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_pll7.clkr.hw }, + { .hw = &cam_cc_pll7.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL1_OUT_EVEN, 4 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll1_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll2_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL8_OUT_EVEN, 4 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll8_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL3_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll4_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL5_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll5_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_9[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_9[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_rt_axi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(120000000, P_CAM_CC_PLL6_OUT_EVEN, 4, 0, 0), + F(160000000, P_CAM_CC_PLL6_OUT_EVEN, 3, 0, 0), + F(240000000, P_CAM_CC_PLL6_OUT_EVEN, 2, 0, 0), + F(320000000, P_CAM_CC_PLL6_OUT_EVEN, 1.5, 0, 0), + F(480000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_rt_axi_clk_src_maili[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_MAIN, 6, 0, 0), + F(240000000, P_CAM_CC_PLL0_OUT_MAIN, 5, 0, 0), + 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), + F(600000000, P_CAM_CC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_camnoc_rt_axi_clk_src = { + .cmd_rcgr = 0x212cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_camnoc_rt_axi_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_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_cci_0_clk_src[] = { + F(37500000, P_CAM_CC_PLL0_OUT_ODD, 1, 3, 32), + { } +}; + +static const struct freq_tbl ftbl_cam_cc_cci_0_clk_src_maili[] = { + F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .cmd_rcgr = 0x21250, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_cci_1_clk_src = { + .cmd_rcgr = 0x2126c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_cci_2_clk_src = { + .cmd_rcgr = 0x21288, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_2_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_cphy_rx_clk_src[] = { + F(200000000, P_CAM_CC_PLL0_OUT_MAIN, 6, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 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 = 0x21064, + .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_cre_clk_src[] = { + F(80000000, P_CAM_CC_PLL6_OUT_EVEN, 6, 0, 0), + F(137142857, P_CAM_CC_PLL6_OUT_EVEN, 3.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_PLL0_OUT_MAIN, 2.5, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cre_clk_src = { + .cmd_rcgr = 0x211a0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_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_csi0phytimer_clk_src[] = { + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x20000, + .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 = 0x20024, + .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_csi2phytimer_clk_src = { + .cmd_rcgr = 0x20044, + .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_csi2phytimer_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_csi3phytimer_clk_src = { + .cmd_rcgr = 0x20064, + .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_csi3phytimer_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 = 0x20084, + .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_csi5phytimer_clk_src = { + .cmd_rcgr = 0x200a4, + .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_csi5phytimer_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 = 0x212a4, + .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(128000000, P_CAM_CC_PLL6_OUT_ODD, 2.5, 0, 0), + F(213333333, P_CAM_CC_PLL6_OUT_ODD, 1.5, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 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 = 0x200dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_icp_0_clk_src[] = { + F(345000000, P_CAM_CC_PLL7_OUT_MAIN, 1, 0, 0), + F(500000000, P_CAM_CC_PLL7_OUT_MAIN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL7_OUT_MAIN, 1, 0, 0), + F(770000000, P_CAM_CC_PLL7_OUT_MAIN, 1, 0, 0), + F(900000000, P_CAM_CC_PLL7_OUT_MAIN, 1, 0, 0), + F(1150000000, P_CAM_CC_PLL7_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_0_clk_src = { + .cmd_rcgr = 0x211f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_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 struct clk_rcg2 cam_cc_icp_1_clk_src = { + .cmd_rcgr = 0x21220, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_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_lite_clk_src[] = { + F(200000000, P_CAM_CC_PLL0_OUT_MAIN, 6, 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_ife_lite_clk_src = { + .cmd_rcgr = 0x21144, + .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 = 0x21170, + .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_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(246600000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(411000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(475000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(575000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(825000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_nps_clk_src = { + .cmd_rcgr = 0x2019c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .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_3, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0x211c4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cre_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_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_ofe_clk_src[] = { + F(225600000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(300000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(376000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(445000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(500000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(609000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(688000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(841000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_cam_cc_ofe_clk_src_maili[] = { + F(300000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(376000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(445000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(500000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(609000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(688000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(841000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ofe_clk_src = { + .cmd_rcgr = 0x20120, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_4, + .freq_tbl = ftbl_cam_cc_ofe_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_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_qdss_debug_clk_src[] = { + F(40000000, P_CAM_CC_PLL6_OUT_ODD, 8, 0, 0), + F(60000000, P_CAM_CC_PLL0_OUT_EVEN, 10, 0, 0), + F(120000000, P_CAM_CC_PLL0_OUT_EVEN, 5, 0, 0), + F(240000000, P_CAM_CC_PLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qdss_debug_clk_src = { + .cmd_rcgr = 0x21310, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_slow_ahb_clk_src[] = { + F(56470588, P_CAM_CC_PLL6_OUT_EVEN, 8.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 = 0x20104, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_sqpf_clk_src[] = { + F(246600000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0), + F(411000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0), + F(475000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0), + F(575000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0), + F(825000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_sqpf_clk_src = { + .cmd_rcgr = 0x2021c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_sqpf_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sqpf_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_tfe_0_clk_src[] = { + F(238200000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(397000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(440000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(750000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_0_clk_src = { + .cmd_rcgr = 0x21018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_6, + .freq_tbl = ftbl_cam_cc_tfe_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_clk_src", + .parent_data = cam_cc_parent_data_6, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_tfe_1_clk_src[] = { + F(238200000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(397000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(440000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(750000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_1_clk_src = { + .cmd_rcgr = 0x21094, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_7, + .freq_tbl = ftbl_cam_cc_tfe_1_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_clk_src", + .parent_data = cam_cc_parent_data_7, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_tfe_2_clk_src[] = { + F(238200000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(397000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(440000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(750000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_2_clk_src = { + .cmd_rcgr = 0x210f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_8, + .freq_tbl = ftbl_cam_cc_tfe_2_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_clk_src", + .parent_data = cam_cc_parent_data_8, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_8), + .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, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_xo_clk_src = { + .cmd_rcgr = 0x21348, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_9, + .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_9, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch cam_cc_cam_top_ahb_clk = { + .halt_reg = 0x21378, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21378, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_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_cam_top_fast_ahb_clk = { + .halt_reg = 0x21368, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21368, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_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_nrt_axi_clk = { + .halt_reg = 0x212f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_cre_clk = { + .halt_reg = 0x211bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ipe_nps_clk = { + .halt_reg = 0x201c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_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_camnoc_nrt_ipe_scalers_clk = { + .halt_reg = 0x201e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ipe_scalers_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_camnoc_nrt_ofe_main_clk = { + .halt_reg = 0x20148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20148, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_sqpf_clk = { + .halt_reg = 0x20244, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20244, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_sqpf_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_sqpf_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_axi_clk = { + .halt_reg = 0x212e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_ife_lite_clk = { + .halt_reg = 0x2116c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2116c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_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_camnoc_rt_tfe_0_main_clk = { + .halt_reg = 0x21040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_1_main_clk = { + .halt_reg = 0x210bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_2_main_clk = { + .halt_reg = 0x21120, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21120, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_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 = 0x21268, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21268, + .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 = 0x21284, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21284, + .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_cci_2_clk = { + .halt_reg = 0x212a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_2_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 = 0x21344, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x21344, + .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_cre_ahb_clk = { + .halt_reg = 0x211c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_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_cre_clk = { + .halt_reg = 0x211b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_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 = 0x20018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20018, + .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 = 0x2003c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2003c, + .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_csi2phytimer_clk = { + .halt_reg = 0x2005c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2005c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi2phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi3phytimer_clk = { + .halt_reg = 0x2007c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2007c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi3phytimer_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 = 0x2009c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2009c, + .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_csi5phytimer_clk = { + .halt_reg = 0x200bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi5phytimer_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 = 0x212bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212bc, + .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 = 0x20020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20020, + .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 = 0x2001c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2001c, + .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 = 0x20040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20040, + .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_csiphy2_clk = { + .halt_reg = 0x20060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy2_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_csiphy3_clk = { + .halt_reg = 0x20080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy3_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 = 0x200a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200a0, + .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_csiphy5_clk = { + .halt_reg = 0x200c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy5_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_0_ahb_clk = { + .halt_reg = 0x21248, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21248, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_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_0_clk = { + .halt_reg = 0x21210, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21210, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_1_ahb_clk = { + .halt_reg = 0x2124c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2124c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_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_1_clk = { + .halt_reg = 0x21238, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21238, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_1_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 = 0x2119c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2119c, + .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 = 0x2115c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2115c, + .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 = 0x21198, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21198, + .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 = 0x21188, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21188, + .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 = 0x201f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201f4, + .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 = 0x201b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201b4, + .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 = 0x201f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201f8, + .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 = 0x201c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201c8, + .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 = 0x201fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201fc, + .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_ipe_scalers_clk = { + .halt_reg = 0x201d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_scalers_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_scalers_fast_ahb_clk = { + .halt_reg = 0x20200, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20200, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_scalers_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 = 0x211dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211dc, + .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_ofe_ahb_clk = { + .halt_reg = 0x2011c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2011c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_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_ofe_anchor_clk = { + .halt_reg = 0x2014c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2014c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_anchor_fast_ahb_clk = { + .halt_reg = 0x200f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_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_ofe_hdr_clk = { + .halt_reg = 0x2015c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2015c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_hdr_fast_ahb_clk = { + .halt_reg = 0x200fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_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_ofe_main_clk = { + .halt_reg = 0x20138, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20138, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_main_fast_ahb_clk = { + .halt_reg = 0x200f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_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_ofe_mp_clk = { + .halt_reg = 0x2016c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2016c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_mp_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_mp_fast_ahb_clk = { + .halt_reg = 0x20100, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20100, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_mp_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_qdss_debug_clk = { + .halt_reg = 0x21328, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21328, + .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 = 0x2132c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2132c, + .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 clk_branch cam_cc_sqpf_ahb_clk = { + .halt_reg = 0x20250, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20250, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sqpf_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_sqpf_clk = { + .halt_reg = 0x20234, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20234, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sqpf_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_sqpf_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sqpf_fast_ahb_clk = { + .halt_reg = 0x20254, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20254, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sqpf_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_tfe_0_bayer_clk = { + .halt_reg = 0x21044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_bayer_fast_ahb_clk = { + .halt_reg = 0x21060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_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_tfe_0_main_clk = { + .halt_reg = 0x21030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_main_fast_ahb_clk = { + .halt_reg = 0x2105c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2105c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_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_tfe_1_bayer_clk = { + .halt_reg = 0x210c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_bayer_fast_ahb_clk = { + .halt_reg = 0x210dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_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_tfe_1_main_clk = { + .halt_reg = 0x210ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_main_fast_ahb_clk = { + .halt_reg = 0x210d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_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_tfe_2_bayer_clk = { + .halt_reg = 0x21124, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21124, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_bayer_fast_ahb_clk = { + .halt_reg = 0x21140, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21140, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_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_tfe_2_main_clk = { + .halt_reg = 0x21110, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21110, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_main_fast_ahb_clk = { + .halt_reg = 0x2113c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2113c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_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_titan_mnoc_hf_clk = { + .halt_reg = 0x213a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x213a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_titan_mnoc_hf_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_titan_mnoc_sf_clk = { + .halt_reg = 0x213b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x213b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_titan_mnoc_sf_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tracenoc_tpdm_1_cmb_clk = { + .halt_reg = 0x213dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x213dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tracenoc_tpdm_1_cmb_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_cx_gdsc = { + .gdscr = 0x21388, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_titan_top_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .needs_icc = true, + .icc_path_index = DT_ICC_TOP_GDSC, +}; + +static struct gdsc cam_cc_titan_top_gdsc = { + .gdscr = 0x21330, + .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, + .needs_icc = true, + .icc_path_index = DT_ICC_TOP_GDSC, + .parent = &cam_cc_titan_top_cx_gdsc.pd, +}; + +static struct gdsc cam_cc_ipe_0_gdsc = { + .gdscr = 0x20188, + .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, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct gdsc cam_cc_ofe_gdsc = { + .gdscr = 0x200c8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ofe_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct gdsc cam_cc_sqpf_gdsc = { + .gdscr = 0x20208, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_sqpf_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct gdsc cam_cc_tfe_0_gdsc = { + .gdscr = 0x21004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct gdsc cam_cc_tfe_1_gdsc = { + .gdscr = 0x21080, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct gdsc cam_cc_tfe_2_gdsc = { + .gdscr = 0x210e4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct clk_regmap *cam_cc_hawi_clocks[] = { + [CAM_CC_CAM_TOP_AHB_CLK] = &cam_cc_cam_top_ahb_clk.clkr, + [CAM_CC_CAM_TOP_FAST_AHB_CLK] = &cam_cc_cam_top_fast_ahb_clk.clkr, + [CAM_CC_CAMNOC_NRT_AXI_CLK] = &cam_cc_camnoc_nrt_axi_clk.clkr, + [CAM_CC_CAMNOC_NRT_CRE_CLK] = &cam_cc_camnoc_nrt_cre_clk.clkr, + [CAM_CC_CAMNOC_NRT_IPE_NPS_CLK] = &cam_cc_camnoc_nrt_ipe_nps_clk.clkr, + [CAM_CC_CAMNOC_NRT_IPE_SCALERS_CLK] = &cam_cc_camnoc_nrt_ipe_scalers_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK] = &cam_cc_camnoc_nrt_ofe_main_clk.clkr, + [CAM_CC_CAMNOC_NRT_SQPF_CLK] = &cam_cc_camnoc_nrt_sqpf_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK] = &cam_cc_camnoc_rt_axi_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK_SRC] = &cam_cc_camnoc_rt_axi_clk_src.clkr, + [CAM_CC_CAMNOC_RT_IFE_LITE_CLK] = &cam_cc_camnoc_rt_ife_lite_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_0_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_1_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_2_main_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_CCI_2_CLK] = &cam_cc_cci_2_clk.clkr, + [CAM_CC_CCI_2_CLK_SRC] = &cam_cc_cci_2_clk_src.clkr, + [CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CRE_AHB_CLK] = &cam_cc_cre_ahb_clk.clkr, + [CAM_CC_CRE_CLK] = &cam_cc_cre_clk.clkr, + [CAM_CC_CRE_CLK_SRC] = &cam_cc_cre_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_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr, + [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr, + [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr, + [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_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_CSI5PHYTIMER_CLK] = &cam_cc_csi5phytimer_clk.clkr, + [CAM_CC_CSI5PHYTIMER_CLK_SRC] = &cam_cc_csi5phytimer_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_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr, + [CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr, + [CAM_CC_CSIPHY4_CLK] = &cam_cc_csiphy4_clk.clkr, + [CAM_CC_CSIPHY5_CLK] = &cam_cc_csiphy5_clk.clkr, + [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, + [CAM_CC_ICP_0_AHB_CLK] = &cam_cc_icp_0_ahb_clk.clkr, + [CAM_CC_ICP_0_CLK] = &cam_cc_icp_0_clk.clkr, + [CAM_CC_ICP_0_CLK_SRC] = &cam_cc_icp_0_clk_src.clkr, + [CAM_CC_ICP_1_AHB_CLK] = &cam_cc_icp_1_ahb_clk.clkr, + [CAM_CC_ICP_1_CLK] = &cam_cc_icp_1_clk.clkr, + [CAM_CC_ICP_1_CLK_SRC] = &cam_cc_icp_1_clk_src.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_IPE_SCALERS_CLK] = &cam_cc_ipe_scalers_clk.clkr, + [CAM_CC_IPE_SCALERS_FAST_AHB_CLK] = &cam_cc_ipe_scalers_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_OFE_AHB_CLK] = &cam_cc_ofe_ahb_clk.clkr, + [CAM_CC_OFE_ANCHOR_CLK] = &cam_cc_ofe_anchor_clk.clkr, + [CAM_CC_OFE_ANCHOR_FAST_AHB_CLK] = &cam_cc_ofe_anchor_fast_ahb_clk.clkr, + [CAM_CC_OFE_CLK_SRC] = &cam_cc_ofe_clk_src.clkr, + [CAM_CC_OFE_HDR_CLK] = &cam_cc_ofe_hdr_clk.clkr, + [CAM_CC_OFE_HDR_FAST_AHB_CLK] = &cam_cc_ofe_hdr_fast_ahb_clk.clkr, + [CAM_CC_OFE_MAIN_CLK] = &cam_cc_ofe_main_clk.clkr, + [CAM_CC_OFE_MAIN_FAST_AHB_CLK] = &cam_cc_ofe_main_fast_ahb_clk.clkr, + [CAM_CC_OFE_MP_CLK] = &cam_cc_ofe_mp_clk.clkr, + [CAM_CC_OFE_MP_FAST_AHB_CLK] = &cam_cc_ofe_mp_fast_ahb_clk.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_PLL2_OUT_EVEN] = &cam_cc_pll2_out_even.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_PLL6] = &cam_cc_pll6.clkr, + [CAM_CC_PLL6_OUT_EVEN] = &cam_cc_pll6_out_even.clkr, + [CAM_CC_PLL6_OUT_ODD] = &cam_cc_pll6_out_odd.clkr, + [CAM_CC_PLL7] = &cam_cc_pll7.clkr, + [CAM_CC_PLL8] = &cam_cc_pll8.clkr, + [CAM_CC_PLL8_OUT_EVEN] = &cam_cc_pll8_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_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, + [CAM_CC_SQPF_AHB_CLK] = &cam_cc_sqpf_ahb_clk.clkr, + [CAM_CC_SQPF_CLK] = &cam_cc_sqpf_clk.clkr, + [CAM_CC_SQPF_CLK_SRC] = &cam_cc_sqpf_clk_src.clkr, + [CAM_CC_SQPF_FAST_AHB_CLK] = &cam_cc_sqpf_fast_ahb_clk.clkr, + [CAM_CC_TFE_0_BAYER_CLK] = &cam_cc_tfe_0_bayer_clk.clkr, + [CAM_CC_TFE_0_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_0_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_0_CLK_SRC] = &cam_cc_tfe_0_clk_src.clkr, + [CAM_CC_TFE_0_MAIN_CLK] = &cam_cc_tfe_0_main_clk.clkr, + [CAM_CC_TFE_0_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_0_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_BAYER_CLK] = &cam_cc_tfe_1_bayer_clk.clkr, + [CAM_CC_TFE_1_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_1_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_CLK_SRC] = &cam_cc_tfe_1_clk_src.clkr, + [CAM_CC_TFE_1_MAIN_CLK] = &cam_cc_tfe_1_main_clk.clkr, + [CAM_CC_TFE_1_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_1_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_BAYER_CLK] = &cam_cc_tfe_2_bayer_clk.clkr, + [CAM_CC_TFE_2_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_2_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_CLK_SRC] = &cam_cc_tfe_2_clk_src.clkr, + [CAM_CC_TFE_2_MAIN_CLK] = &cam_cc_tfe_2_main_clk.clkr, + [CAM_CC_TFE_2_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_2_main_fast_ahb_clk.clkr, + [CAM_CC_TITAN_MNOC_HF_CLK] = &cam_cc_titan_mnoc_hf_clk.clkr, + [CAM_CC_TITAN_MNOC_SF_CLK] = &cam_cc_titan_mnoc_sf_clk.clkr, + [CAM_CC_TRACENOC_TPDM_1_CMB_CLK] = &cam_cc_tracenoc_tpdm_1_cmb_clk.clkr, + [CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr, +}; + +static struct gdsc *cam_cc_hawi_gdscs[] = { + [CAM_CC_IPE_0_GDSC] = &cam_cc_ipe_0_gdsc, + [CAM_CC_OFE_GDSC] = &cam_cc_ofe_gdsc, + [CAM_CC_SQPF_GDSC] = &cam_cc_sqpf_gdsc, + [CAM_CC_TFE_0_GDSC] = &cam_cc_tfe_0_gdsc, + [CAM_CC_TFE_1_GDSC] = &cam_cc_tfe_1_gdsc, + [CAM_CC_TFE_2_GDSC] = &cam_cc_tfe_2_gdsc, + [CAM_CC_TITAN_TOP_CX_GDSC] = &cam_cc_titan_top_cx_gdsc, + [CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc, +}; + +static const struct qcom_reset_map cam_cc_hawi_resets[] = { + [CAM_CC_DRV_BCR] = { 0x213d4 }, + [CAM_CC_ICP_BCR] = { 0x211f4 }, + [CAM_CC_IPE_0_BCR] = { 0x20184 }, + [CAM_CC_OFE_BCR] = { 0x200c4 }, + [CAM_CC_QDSS_DEBUG_BCR] = { 0x2130c }, + [CAM_CC_SQPF_BCR] = { 0x20204 }, + [CAM_CC_TFE_0_BCR] = { 0x21000 }, + [CAM_CC_TFE_1_BCR] = { 0x2107c }, + [CAM_CC_TFE_2_BCR] = { 0x210e0 }, +}; + +static struct clk_alpha_pll *cam_cc_hawi_plls[] = { + &cam_cc_pll0, + &cam_cc_pll1, + &cam_cc_pll2, + &cam_cc_pll3, + &cam_cc_pll4, + &cam_cc_pll5, + &cam_cc_pll6, + &cam_cc_pll7, + &cam_cc_pll8, +}; + +static const u32 cam_cc_hawi_critical_cbcrs[] = { + 0x21308, /* CAM_CC_CAMNOC_DCD_XO_CLK */ + 0x2139c, /* CAM_CC_CX_GDSC_CLK */ + 0x213e0, /* CAM_CC_DRV_AHB_CLK */ + 0x213d8, /* CAM_CC_DRV_XO_CLK */ + 0x21360, /* CAM_CC_GDSC_CLK */ + 0x213d0, /* CAM_CC_MMSS_AHB_CLK */ + 0x21364, /* CAM_CC_SLEEP_CLK */ + 0x213a0, /* CAM_CC_TITAN_CAMNOC_XO_CLK */ +}; + +static const struct regmap_config cam_cc_hawi_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x26024, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data cam_cc_hawi_driver_data = { + .alpha_plls = cam_cc_hawi_plls, + .num_alpha_plls = ARRAY_SIZE(cam_cc_hawi_plls), + .clk_cbcrs = cam_cc_hawi_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_hawi_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_cc_hawi_desc = { + .config = &cam_cc_hawi_regmap_config, + .clks = cam_cc_hawi_clocks, + .num_clks = ARRAY_SIZE(cam_cc_hawi_clocks), + .resets = cam_cc_hawi_resets, + .num_resets = ARRAY_SIZE(cam_cc_hawi_resets), + .gdscs = cam_cc_hawi_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_hawi_gdscs), + .use_rpm = true, + .driver_data = &cam_cc_hawi_driver_data, +}; + +static const struct of_device_id cam_cc_hawi_match_table[] = { + { .compatible = "qcom,hawi-camcc" }, + { .compatible = "qcom,maili-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_hawi_match_table); + +static int cam_cc_hawi_probe(struct platform_device *pdev) +{ + if (device_is_compatible(&pdev->dev, "qcom,maili-camcc")) { + cam_cc_pll0.config = &cam_cc_pll0_config_maili; + cam_cc_pll1.config = &cam_cc_pll1_config_maili; + cam_cc_pll2.config = &cam_cc_pll2_config_maili; + cam_cc_pll3.config = &cam_cc_pll3_config_maili; + cam_cc_pll4.config = &cam_cc_pll4_config_maili; + cam_cc_pll5.config = &cam_cc_pll5_config_maili; + cam_cc_pll6.config = &cam_cc_pll6_config_maili; + cam_cc_pll7.config = &cam_cc_pll7_config_maili; + cam_cc_pll8.config = &cam_cc_pll8_config_maili; + + cam_cc_camnoc_rt_axi_clk_src.freq_tbl = ftbl_cam_cc_camnoc_rt_axi_clk_src_maili; + cam_cc_cci_0_clk_src.freq_tbl = ftbl_cam_cc_cci_0_clk_src_maili; + cam_cc_cci_1_clk_src.freq_tbl = ftbl_cam_cc_cci_0_clk_src_maili; + cam_cc_ofe_clk_src.freq_tbl = ftbl_cam_cc_ofe_clk_src_maili; + + cam_cc_hawi_clocks[CAM_CC_CCI_2_CLK_SRC] = NULL; + cam_cc_hawi_clocks[CAM_CC_CCI_2_CLK] = NULL; + cam_cc_hawi_clocks[CAM_CC_CSI5PHYTIMER_CLK_SRC] = NULL; + cam_cc_hawi_clocks[CAM_CC_CSI5PHYTIMER_CLK] = NULL; + cam_cc_hawi_clocks[CAM_CC_CSIPHY5_CLK] = NULL; + } + + return qcom_cc_probe(pdev, &cam_cc_hawi_desc); +} + +static struct platform_driver cam_cc_hawi_driver = { + .probe = cam_cc_hawi_probe, + .driver = { + .name = "camcc-hawi", + .of_match_table = cam_cc_hawi_match_table, + }, +}; + +module_platform_driver(cam_cc_hawi_driver); + +MODULE_DESCRIPTION("QTI CAMCC Hawi Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-nord.c b/drivers/clk/qcom/camcc-nord.c new file mode 100644 index 000000000000..9e3c40cb3ad5 --- /dev/null +++ b/drivers/clk/qcom/camcc-nord.c @@ -0,0 +1,2941 @@ +// 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_IFACE, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK +}; + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL0_OUT_MAIN, + P_CAM_CC_PLL0_OUT_ODD, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CAM_CC_PLL4_OUT_EVEN, + P_CAM_CC_PLL5_OUT_EVEN, + P_CAM_CC_PLL6_OUT_EVEN, + P_SLEEP_CLK, +}; + +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + +/* 1200.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .alpha = 0x8000, + .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 = 0x00008400, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .config = &cam_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 = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO_AO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_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_LUCID_OLE], + .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_lucid_evo_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_LUCID_OLE], + .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_lucid_evo_ops, + }, +}; + +/* 720.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x25, + .alpha = 0x8000, + .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 = 0x00000400, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .config = &cam_cc_pll2_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 = "cam_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll2_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { + .offset = 0x2000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll2_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll2_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll2_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_evo_ops, + }, +}; + +/* 720.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x25, + .alpha = 0x8000, + .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 = 0x00000400, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .config = &cam_cc_pll3_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 = "cam_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_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_LUCID_OLE], + .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_lucid_evo_ops, + }, +}; + +/* 720.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x25, + .alpha = 0x8000, + .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 = 0x00000400, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll cam_cc_pll4 = { + .offset = 0x4000, + .config = &cam_cc_pll4_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 = "cam_cc_pll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_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_LUCID_OLE], + .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_lucid_evo_ops, + }, +}; + +/* 720.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll5_config = { + .l = 0x25, + .alpha = 0x8000, + .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 = 0x00000400, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll cam_cc_pll5 = { + .offset = 0x5000, + .config = &cam_cc_pll5_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 = "cam_cc_pll5", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_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_LUCID_OLE], + .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_lucid_evo_ops, + }, +}; + +/* 720.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll6_config = { + .l = 0x25, + .alpha = 0x8000, + .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 = 0x00000400, + .user_ctl_hi_val = 0x00400005, +}; + +static struct clk_alpha_pll cam_cc_pll6 = { + .offset = 0x6000, + .config = &cam_cc_pll6_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 = "cam_cc_pll6", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_even = { + .offset = 0x6000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll6_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_evo_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 }, +}; + +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 }, +}; + +static const struct parent_map cam_cc_parent_map_1[] = { + { 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 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .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 }, +}; + +static const struct parent_map cam_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 3 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll0.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, + { .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_PLL2_OUT_EVEN, 2 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll2_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll4_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL5_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll5_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL6_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll0.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_8[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_8[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map cam_cc_parent_map_9[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_9[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_rt_axi_clk_src[] = { + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_camnoc_rt_axi_clk_src = { + .cmd_rcgr = 0x13244, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_camnoc_rt_axi_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_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(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .cmd_rcgr = 0x13110, + .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 = 0x13130, + .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 struct clk_rcg2 cam_cc_cci_2_clk_src = { + .cmd_rcgr = 0x13150, + .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_2_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_3_clk_src = { + .cmd_rcgr = 0x13170, + .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_3_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_4_clk_src = { + .cmd_rcgr = 0x13190, + .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_4_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_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 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 = 0x120ac, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_csi0phytimer_clk_src[] = { + 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_csi0phytimer_clk_src = { + .cmd_rcgr = 0x10000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_csi1phytimer_clk_src = { + .cmd_rcgr = 0x10028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_csi2phytimer_clk_src = { + .cmd_rcgr = 0x1004c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_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_csi3phytimer_clk_src = { + .cmd_rcgr = 0x10070, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_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_csi4phytimer_clk_src = { + .cmd_rcgr = 0x10094, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .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_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_csid_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_csid_clk_src = { + .cmd_rcgr = 0x13214, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csid_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_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_fast_ahb_clk_src[] = { + 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 = 0x131dc, + .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_0_clk_src[] = { + F(360000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_0_clk_src = { + .cmd_rcgr = 0x130a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_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 struct clk_rcg2 cam_cc_icp_1_clk_src = { + .cmd_rcgr = 0x130dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_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_0_main_clk_src[] = { + F(360000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(650000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_0_main_clk_src = { + .cmd_rcgr = 0x12018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_4, + .freq_tbl = ftbl_cam_cc_ife_0_main_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_main_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_ife_1_main_clk_src[] = { + F(360000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(650000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_1_main_clk_src = { + .cmd_rcgr = 0x120dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_ife_1_main_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_main_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_ife_2_main_clk_src[] = { + F(360000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + F(650000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_2_main_clk_src = { + .cmd_rcgr = 0x12188, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_6, + .freq_tbl = ftbl_cam_cc_ife_2_main_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_main_clk_src", + .parent_data = cam_cc_parent_data_6, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +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_1, + .freq_tbl = ftbl_cam_cc_csid_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_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_ife_lite_csid_clk_src = { + .cmd_rcgr = 0x13024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csid_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_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_ipe_0_clk_src[] = { + F(360000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(650000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_0_clk_src = { + .cmd_rcgr = 0x11018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ipe_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_0_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 struct clk_rcg2 cam_cc_ipe_1_clk_src = { + .cmd_rcgr = 0x11074, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ipe_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_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_qdss_debug_clk_src[] = { + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qdss_debug_clk_src = { + .cmd_rcgr = 0x13330, + .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_qup_ahbm_clk_src[] = { + F(150000000, P_CAM_CC_PLL0_OUT_EVEN, 4, 0, 0), + F(240000000, P_CAM_CC_PLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qup_ahbm_clk_src = { + .cmd_rcgr = 0x132e8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_qup_ahbm_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qup_ahbm_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_qup_core_2x_clk_src[] = { + F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qup_core_2x_clk_src = { + .cmd_rcgr = 0x132a0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_qup_core_2x_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qup_core_2x_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_qup_se_clk_src = { + .cmd_rcgr = 0x13308, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_7, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qup_se_clk_src", + .parent_data = cam_cc_parent_data_7, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_7), + .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 = 0x13384, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_8, + .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_8, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = { + F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { + .cmd_rcgr = 0x131f8, + .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, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_xo_clk_src = { + .cmd_rcgr = 0x13368, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_9, + .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_9, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div cam_cc_qup_core_2x_div_clk_src = { + .reg = 0x132cc, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qup_core_2x_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qup_core_2x_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch cam_cc_camnoc_dcd_xo_clk = { + .halt_reg = 0x13290, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13290, + .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_nrt_axi_clk = { + .halt_reg = 0x13278, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13278, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_axi_clk = { + .halt_reg = 0x13260, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13260, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_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 = 0x1312c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1312c, + .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 = 0x1314c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1314c, + .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_cci_2_clk = { + .halt_reg = 0x1316c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1316c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_3_clk = { + .halt_reg = 0x1318c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1318c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_4_clk = { + .halt_reg = 0x131ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x131ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ccu_fast_ahb_clk = { + .halt_reg = 0x1329c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1329c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ccu_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_csi0phytimer_clk = { + .halt_reg = 0x1001c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1001c, + .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 = 0x10044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10044, + .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_csi2phytimer_clk = { + .halt_reg = 0x10068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi2phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi3phytimer_clk = { + .halt_reg = 0x1008c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1008c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi3phytimer_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 = 0x100b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100b0, + .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 = 0x13230, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13230, + .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 = 0x10024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10024, + .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 = 0x10020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10020, + .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 = 0x10048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10048, + .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_csiphy2_clk = { + .halt_reg = 0x1006c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1006c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy2_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_csiphy3_clk = { + .halt_reg = 0x10090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy3_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 = 0x100b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100b4, + .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_0_ahb_clk = { + .halt_reg = 0x130d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x130d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_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_0_clk = { + .halt_reg = 0x130c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x130c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_1_ahb_clk = { + .halt_reg = 0x1310c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1310c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_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_1_clk = { + .halt_reg = 0x130f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x130f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_main_clk = { + .halt_reg = 0x12034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_main_fast_ahb_clk = { + .halt_reg = 0x12054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_main_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_0_pcp_clk = { + .halt_reg = 0x12058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_pcp_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_pcp_fast_ahb_clk = { + .halt_reg = 0x12070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_pcp_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_0_scalar_clk = { + .halt_reg = 0x12074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_scalar_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_scalar_fast_ahb_clk = { + .halt_reg = 0x1208c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1208c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_scalar_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_0_tmc_clk = { + .halt_reg = 0x12090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_tmc_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_tmc_fast_ahb_clk = { + .halt_reg = 0x120a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x120a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_tmc_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_main_clk = { + .halt_reg = 0x120f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x120f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_main_fast_ahb_clk = { + .halt_reg = 0x12118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_main_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_pcp_clk = { + .halt_reg = 0x1211c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1211c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_pcp_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_pcp_fast_ahb_clk = { + .halt_reg = 0x12134, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_pcp_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_scalar_clk = { + .halt_reg = 0x12138, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12138, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_scalar_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_scalar_fast_ahb_clk = { + .halt_reg = 0x12150, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12150, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_scalar_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_tmc_clk = { + .halt_reg = 0x12154, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12154, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_tmc_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_tmc_fast_ahb_clk = { + .halt_reg = 0x1216c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1216c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_tmc_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_2_main_clk = { + .halt_reg = 0x121a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x121a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_2_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_2_main_fast_ahb_clk = { + .halt_reg = 0x121c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x121c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_main_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_2_pcp_clk = { + .halt_reg = 0x121c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x121c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_pcp_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_2_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_2_pcp_fast_ahb_clk = { + .halt_reg = 0x121e0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x121e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_pcp_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_2_scalar_clk = { + .halt_reg = 0x121e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x121e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_scalar_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_2_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_2_scalar_fast_ahb_clk = { + .halt_reg = 0x121fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x121fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_scalar_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_2_tmc_clk = { + .halt_reg = 0x12200, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12200, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_tmc_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_2_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_2_tmc_fast_ahb_clk = { + .halt_reg = 0x12218, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12218, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_tmc_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 = 0x13054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13054, + .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 = 0x1301c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1301c, + .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 = 0x13050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13050, + .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 = 0x1303c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1303c, + .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_0_ahb_clk = { + .halt_reg = 0x11054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_0_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_0_clk = { + .halt_reg = 0x11034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_fast_ahb_clk = { + .halt_reg = 0x11058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_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_ipe_1_ahb_clk = { + .halt_reg = 0x110b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_1_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_1_clk = { + .halt_reg = 0x11090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_1_fast_ahb_clk = { + .halt_reg = 0x110b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_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_qdss_debug_clk = { + .halt_reg = 0x13348, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13348, + .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 = 0x1334c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1334c, + .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 clk_branch cam_cc_qup_ahbm_clk = { + .halt_reg = 0x13300, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13300, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qup_ahbm_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qup_ahbm_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qup_core_2x_clk = { + .halt_reg = 0x132b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x132b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qup_core_2x_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qup_core_2x_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qup_core_clk = { + .halt_reg = 0x132d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x132d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qup_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qup_core_2x_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qup_se_clk = { + .halt_reg = 0x13320, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13320, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qup_se_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qup_se_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_lite_0_clk = { + .halt_reg = 0x1305c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1305c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_lite_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_lite_0_fast_ahb_clk = { + .halt_reg = 0x1306c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1306c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_lite_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_sfe_lite_1_clk = { + .halt_reg = 0x13074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_lite_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_lite_1_fast_ahb_clk = { + .halt_reg = 0x13084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13084, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_lite_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_sfe_lite_2_clk = { + .halt_reg = 0x1308c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1308c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_lite_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_2_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_lite_2_fast_ahb_clk = { + .halt_reg = 0x1309c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1309c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_lite_2_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_sm_obs_clk = { + .halt_reg = 0x1401c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1401c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sm_obs_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_top_ahb_clk = { + .halt_reg = 0x131b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x131b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_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_top_fast_ahb_clk = { + .halt_reg = 0x131c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x131c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_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_top_ife_0_clk = { + .halt_reg = 0x12048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_ife_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_top_ife_1_clk = { + .halt_reg = 0x1210c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1210c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_ife_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_top_ife_2_clk = { + .halt_reg = 0x121b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x121b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_ife_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_2_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_top_ife_lite_clk = { + .halt_reg = 0x13020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_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_top_ipe_0_clk = { + .halt_reg = 0x11048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_ipe_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_top_ipe_1_clk = { + .halt_reg = 0x110a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_ipe_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_top_qup_ahbm_clk = { + .halt_reg = 0x13304, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13304, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_qup_ahbm_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qup_ahbm_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_top_sfe_lite_0_clk = { + .halt_reg = 0x13060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_sfe_lite_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_top_sfe_lite_1_clk = { + .halt_reg = 0x13078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_sfe_lite_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_top_sfe_lite_2_clk = { + .halt_reg = 0x13090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_top_sfe_lite_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_2_main_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tpg_csiphy_rx_clk = { + .halt_reg = 0x100b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tpg_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 gdsc cam_cc_titan_top_gdsc = { + .gdscr = 0x13350, + .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_ife_0_gdsc = { + .gdscr = 0x12004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ife_0_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ife_1_gdsc = { + .gdscr = 0x120c8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ife_1_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ife_2_gdsc = { + .gdscr = 0x12174, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ife_2_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ipe_0_gdsc = { + .gdscr = 0x11004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ipe_0_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ipe_1_gdsc = { + .gdscr = 0x11060, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ipe_1_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *cam_cc_nord_clocks[] = { + [CAM_CC_CAMNOC_DCD_XO_CLK] = &cam_cc_camnoc_dcd_xo_clk.clkr, + [CAM_CC_CAMNOC_NRT_AXI_CLK] = &cam_cc_camnoc_nrt_axi_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK] = &cam_cc_camnoc_rt_axi_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK_SRC] = &cam_cc_camnoc_rt_axi_clk_src.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_CCI_2_CLK] = &cam_cc_cci_2_clk.clkr, + [CAM_CC_CCI_2_CLK_SRC] = &cam_cc_cci_2_clk_src.clkr, + [CAM_CC_CCI_3_CLK] = &cam_cc_cci_3_clk.clkr, + [CAM_CC_CCI_3_CLK_SRC] = &cam_cc_cci_3_clk_src.clkr, + [CAM_CC_CCI_4_CLK] = &cam_cc_cci_4_clk.clkr, + [CAM_CC_CCI_4_CLK_SRC] = &cam_cc_cci_4_clk_src.clkr, + [CAM_CC_CCU_FAST_AHB_CLK] = &cam_cc_ccu_fast_ahb_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_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr, + [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr, + [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr, + [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_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_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr, + [CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_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_0_AHB_CLK] = &cam_cc_icp_0_ahb_clk.clkr, + [CAM_CC_ICP_0_CLK] = &cam_cc_icp_0_clk.clkr, + [CAM_CC_ICP_0_CLK_SRC] = &cam_cc_icp_0_clk_src.clkr, + [CAM_CC_ICP_1_AHB_CLK] = &cam_cc_icp_1_ahb_clk.clkr, + [CAM_CC_ICP_1_CLK] = &cam_cc_icp_1_clk.clkr, + [CAM_CC_ICP_1_CLK_SRC] = &cam_cc_icp_1_clk_src.clkr, + [CAM_CC_IFE_0_MAIN_CLK] = &cam_cc_ife_0_main_clk.clkr, + [CAM_CC_IFE_0_MAIN_CLK_SRC] = &cam_cc_ife_0_main_clk_src.clkr, + [CAM_CC_IFE_0_MAIN_FAST_AHB_CLK] = &cam_cc_ife_0_main_fast_ahb_clk.clkr, + [CAM_CC_IFE_0_PCP_CLK] = &cam_cc_ife_0_pcp_clk.clkr, + [CAM_CC_IFE_0_PCP_FAST_AHB_CLK] = &cam_cc_ife_0_pcp_fast_ahb_clk.clkr, + [CAM_CC_IFE_0_SCALAR_CLK] = &cam_cc_ife_0_scalar_clk.clkr, + [CAM_CC_IFE_0_SCALAR_FAST_AHB_CLK] = &cam_cc_ife_0_scalar_fast_ahb_clk.clkr, + [CAM_CC_IFE_0_TMC_CLK] = &cam_cc_ife_0_tmc_clk.clkr, + [CAM_CC_IFE_0_TMC_FAST_AHB_CLK] = &cam_cc_ife_0_tmc_fast_ahb_clk.clkr, + [CAM_CC_IFE_1_MAIN_CLK] = &cam_cc_ife_1_main_clk.clkr, + [CAM_CC_IFE_1_MAIN_CLK_SRC] = &cam_cc_ife_1_main_clk_src.clkr, + [CAM_CC_IFE_1_MAIN_FAST_AHB_CLK] = &cam_cc_ife_1_main_fast_ahb_clk.clkr, + [CAM_CC_IFE_1_PCP_CLK] = &cam_cc_ife_1_pcp_clk.clkr, + [CAM_CC_IFE_1_PCP_FAST_AHB_CLK] = &cam_cc_ife_1_pcp_fast_ahb_clk.clkr, + [CAM_CC_IFE_1_SCALAR_CLK] = &cam_cc_ife_1_scalar_clk.clkr, + [CAM_CC_IFE_1_SCALAR_FAST_AHB_CLK] = &cam_cc_ife_1_scalar_fast_ahb_clk.clkr, + [CAM_CC_IFE_1_TMC_CLK] = &cam_cc_ife_1_tmc_clk.clkr, + [CAM_CC_IFE_1_TMC_FAST_AHB_CLK] = &cam_cc_ife_1_tmc_fast_ahb_clk.clkr, + [CAM_CC_IFE_2_MAIN_CLK] = &cam_cc_ife_2_main_clk.clkr, + [CAM_CC_IFE_2_MAIN_CLK_SRC] = &cam_cc_ife_2_main_clk_src.clkr, + [CAM_CC_IFE_2_MAIN_FAST_AHB_CLK] = &cam_cc_ife_2_main_fast_ahb_clk.clkr, + [CAM_CC_IFE_2_PCP_CLK] = &cam_cc_ife_2_pcp_clk.clkr, + [CAM_CC_IFE_2_PCP_FAST_AHB_CLK] = &cam_cc_ife_2_pcp_fast_ahb_clk.clkr, + [CAM_CC_IFE_2_SCALAR_CLK] = &cam_cc_ife_2_scalar_clk.clkr, + [CAM_CC_IFE_2_SCALAR_FAST_AHB_CLK] = &cam_cc_ife_2_scalar_fast_ahb_clk.clkr, + [CAM_CC_IFE_2_TMC_CLK] = &cam_cc_ife_2_tmc_clk.clkr, + [CAM_CC_IFE_2_TMC_FAST_AHB_CLK] = &cam_cc_ife_2_tmc_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_0_AHB_CLK] = &cam_cc_ipe_0_ahb_clk.clkr, + [CAM_CC_IPE_0_CLK] = &cam_cc_ipe_0_clk.clkr, + [CAM_CC_IPE_0_CLK_SRC] = &cam_cc_ipe_0_clk_src.clkr, + [CAM_CC_IPE_0_FAST_AHB_CLK] = &cam_cc_ipe_0_fast_ahb_clk.clkr, + [CAM_CC_IPE_1_AHB_CLK] = &cam_cc_ipe_1_ahb_clk.clkr, + [CAM_CC_IPE_1_CLK] = &cam_cc_ipe_1_clk.clkr, + [CAM_CC_IPE_1_CLK_SRC] = &cam_cc_ipe_1_clk_src.clkr, + [CAM_CC_IPE_1_FAST_AHB_CLK] = &cam_cc_ipe_1_fast_ahb_clk.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_PLL2] = &cam_cc_pll2.clkr, + [CAM_CC_PLL2_OUT_EVEN] = &cam_cc_pll2_out_even.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_PLL6] = &cam_cc_pll6.clkr, + [CAM_CC_PLL6_OUT_EVEN] = &cam_cc_pll6_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_QUP_AHBM_CLK] = &cam_cc_qup_ahbm_clk.clkr, + [CAM_CC_QUP_AHBM_CLK_SRC] = &cam_cc_qup_ahbm_clk_src.clkr, + [CAM_CC_QUP_CORE_2X_CLK] = &cam_cc_qup_core_2x_clk.clkr, + [CAM_CC_QUP_CORE_2X_CLK_SRC] = &cam_cc_qup_core_2x_clk_src.clkr, + [CAM_CC_QUP_CORE_2X_DIV_CLK_SRC] = &cam_cc_qup_core_2x_div_clk_src.clkr, + [CAM_CC_QUP_CORE_CLK] = &cam_cc_qup_core_clk.clkr, + [CAM_CC_QUP_SE_CLK] = &cam_cc_qup_se_clk.clkr, + [CAM_CC_QUP_SE_CLK_SRC] = &cam_cc_qup_se_clk_src.clkr, + [CAM_CC_SFE_LITE_0_CLK] = &cam_cc_sfe_lite_0_clk.clkr, + [CAM_CC_SFE_LITE_0_FAST_AHB_CLK] = &cam_cc_sfe_lite_0_fast_ahb_clk.clkr, + [CAM_CC_SFE_LITE_1_CLK] = &cam_cc_sfe_lite_1_clk.clkr, + [CAM_CC_SFE_LITE_1_FAST_AHB_CLK] = &cam_cc_sfe_lite_1_fast_ahb_clk.clkr, + [CAM_CC_SFE_LITE_2_CLK] = &cam_cc_sfe_lite_2_clk.clkr, + [CAM_CC_SFE_LITE_2_FAST_AHB_CLK] = &cam_cc_sfe_lite_2_fast_ahb_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_SM_OBS_CLK] = &cam_cc_sm_obs_clk.clkr, + [CAM_CC_TOP_AHB_CLK] = &cam_cc_top_ahb_clk.clkr, + [CAM_CC_TOP_FAST_AHB_CLK] = &cam_cc_top_fast_ahb_clk.clkr, + [CAM_CC_TOP_IFE_0_CLK] = &cam_cc_top_ife_0_clk.clkr, + [CAM_CC_TOP_IFE_1_CLK] = &cam_cc_top_ife_1_clk.clkr, + [CAM_CC_TOP_IFE_2_CLK] = &cam_cc_top_ife_2_clk.clkr, + [CAM_CC_TOP_IFE_LITE_CLK] = &cam_cc_top_ife_lite_clk.clkr, + [CAM_CC_TOP_IPE_0_CLK] = &cam_cc_top_ipe_0_clk.clkr, + [CAM_CC_TOP_IPE_1_CLK] = &cam_cc_top_ipe_1_clk.clkr, + [CAM_CC_TOP_QUP_AHBM_CLK] = &cam_cc_top_qup_ahbm_clk.clkr, + [CAM_CC_TOP_SFE_LITE_0_CLK] = &cam_cc_top_sfe_lite_0_clk.clkr, + [CAM_CC_TOP_SFE_LITE_1_CLK] = &cam_cc_top_sfe_lite_1_clk.clkr, + [CAM_CC_TOP_SFE_LITE_2_CLK] = &cam_cc_top_sfe_lite_2_clk.clkr, + [CAM_CC_TPG_CSIPHY_RX_CLK] = &cam_cc_tpg_csiphy_rx_clk.clkr, + [CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr, +}; + +static struct gdsc *cam_cc_nord_gdscs[] = { + [CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc, + [CAM_CC_IFE_0_GDSC] = &cam_cc_ife_0_gdsc, + [CAM_CC_IFE_1_GDSC] = &cam_cc_ife_1_gdsc, + [CAM_CC_IFE_2_GDSC] = &cam_cc_ife_2_gdsc, + [CAM_CC_IPE_0_GDSC] = &cam_cc_ipe_0_gdsc, + [CAM_CC_IPE_1_GDSC] = &cam_cc_ipe_1_gdsc, +}; + +static const struct qcom_reset_map cam_cc_nord_resets[] = { + [CAM_CC_CCU_BCR] = { 0x13298 }, + [CAM_CC_ICP_0_BCR] = { 0x130a0 }, + [CAM_CC_ICP_1_BCR] = { 0x130d8 }, + [CAM_CC_IFE_0_BCR] = { 0x12000 }, + [CAM_CC_IFE_1_BCR] = { 0x120c4 }, + [CAM_CC_IFE_2_BCR] = { 0x12170 }, + [CAM_CC_IPE_0_BCR] = { 0x11000 }, + [CAM_CC_IPE_1_BCR] = { 0x1105c }, + [CAM_CC_QDSS_DEBUG_BCR] = { 0x1332c }, + [CAM_CC_SFE_LITE_0_BCR] = { 0x13058 }, + [CAM_CC_SFE_LITE_1_BCR] = { 0x13070 }, + [CAM_CC_SFE_LITE_2_BCR] = { 0x13088 }, +}; + +static struct clk_alpha_pll *cam_cc_nord_plls[] = { + &cam_cc_pll0, + &cam_cc_pll2, + &cam_cc_pll3, + &cam_cc_pll4, + &cam_cc_pll5, + &cam_cc_pll6, +}; + +static const u32 cam_cc_nord_critical_cbcrs[] = { + 0x13294, /* CAM_CC_CAMNOC_XO_CLK */ + 0x13364, /* CAM_CC_CORE_AHB_CLK */ + 0x13380, /* CAM_CC_GDSC_CLK */ + 0x132e4, /* CAM_CC_QUP_SLEEP_CLK */ + 0x1339c, /* CAM_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_cc_nord_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x17000, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data cam_cc_nord_driver_data = { + .alpha_plls = cam_cc_nord_plls, + .num_alpha_plls = ARRAY_SIZE(cam_cc_nord_plls), + .clk_cbcrs = cam_cc_nord_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_nord_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_cc_nord_desc = { + .config = &cam_cc_nord_regmap_config, + .clks = cam_cc_nord_clocks, + .num_clks = ARRAY_SIZE(cam_cc_nord_clocks), + .resets = cam_cc_nord_resets, + .num_resets = ARRAY_SIZE(cam_cc_nord_resets), + .gdscs = cam_cc_nord_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_nord_gdscs), + .use_rpm = true, + .driver_data = &cam_cc_nord_driver_data, +}; + +static const struct of_device_id cam_cc_nord_match_table[] = { + { .compatible = "qcom,nord-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_nord_match_table); + +static int cam_cc_nord_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_cc_nord_desc); +} + +static struct platform_driver cam_cc_nord_driver = { + .probe = cam_cc_nord_probe, + .driver = { + .name = "camcc-nord", + .of_match_table = cam_cc_nord_match_table, + }, +}; + +module_platform_driver(cam_cc_nord_driver); + +MODULE_DESCRIPTION("QTI CAMCC Nord Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-sa8775p.c b/drivers/clk/qcom/camcc-sa8775p.c index 914478139e97..b0a8f0077dd8 100644 --- a/drivers/clk/qcom/camcc-sa8775p.c +++ b/drivers/clk/qcom/camcc-sa8775p.c @@ -1818,7 +1818,30 @@ static const struct regmap_config cam_cc_sa8775p_regmap_config = { .fast_io = true, }; +static const u32 cam_cc_sa8775p_critical_cbcrs[] = { + 0x13194, /* CAM_CC_CAMNOC_XO_CLK */ + 0x131ec, /* CAM_CC_GDSC_CLK */ + 0x13208, /* CAM_CC_SLEEP_CLK */ +}; + +static const u32 cam_cc_qcs8300_critical_cbcrs[] = { + 0x13178, /* CAM_CC_CAMNOC_XO_CLK */ + 0x131d0, /* CAM_CC_GDSC_CLK */ + 0x131ec, /* CAM_CC_SLEEP_CLK */ +}; + +static const struct qcom_cc_driver_data cam_cc_sa8775p_driver_data = { + .clk_cbcrs = cam_cc_sa8775p_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_sa8775p_critical_cbcrs), +}; + +static const struct qcom_cc_driver_data cam_cc_qcs8300_driver_data = { + .clk_cbcrs = cam_cc_qcs8300_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_qcs8300_critical_cbcrs), +}; + static const struct qcom_cc_desc cam_cc_sa8775p_desc = { + .driver_data = &cam_cc_sa8775p_driver_data, .config = &cam_cc_sa8775p_regmap_config, .clks = cam_cc_sa8775p_clocks, .num_clks = ARRAY_SIZE(cam_cc_sa8775p_clocks), @@ -1837,6 +1860,7 @@ MODULE_DEVICE_TABLE(of, cam_cc_sa8775p_match_table); static int cam_cc_sa8775p_probe(struct platform_device *pdev) { + struct qcom_cc_desc desc = cam_cc_sa8775p_desc; struct regmap *regmap; int ret; @@ -1927,18 +1951,10 @@ static int cam_cc_sa8775p_probe(struct platform_device *pdev) cam_cc_sa8775p_clocks[CAM_CC_TITAN_TOP_ACCU_SHIFT_CLK] = &cam_cc_titan_top_accu_shift_clk.clkr; - /* Keep some clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0x13178); /* CAM_CC_CAMNOC_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x131d0); /* CAM_CC_GDSC_CLK */ - qcom_branch_set_clk_en(regmap, 0x131ec); /* CAM_CC_SLEEP_CLK */ - } else { - /* Keep some clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0x13194); /* CAM_CC_CAMNOC_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x131ec); /* CAM_CC_GDSC_CLK */ - qcom_branch_set_clk_en(regmap, 0x13208); /* CAM_CC_SLEEP_CLK */ + desc.driver_data = &cam_cc_qcs8300_driver_data; } - ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_sa8775p_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/camcc-sc8280xp.c b/drivers/clk/qcom/camcc-sc8280xp.c index 660d8655d391..b0f1d40d1df5 100644 --- a/drivers/clk/qcom/camcc-sc8280xp.c +++ b/drivers/clk/qcom/camcc-sc8280xp.c @@ -2967,7 +2967,17 @@ static const struct regmap_config camcc_sc8280xp_regmap_config = { .fast_io = true, }; +static const u32 camcc_sc8280xp_critical_cbcrs[] = { + 0xc1e4, /* CAMCC_GDSC_CLK */ +}; + +static const struct qcom_cc_driver_data camcc_sc8280xp_driver_data = { + .clk_cbcrs = camcc_sc8280xp_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(camcc_sc8280xp_critical_cbcrs), +}; + static const struct qcom_cc_desc camcc_sc8280xp_desc = { + .driver_data = &camcc_sc8280xp_driver_data, .config = &camcc_sc8280xp_regmap_config, .clks = camcc_sc8280xp_clocks, .num_clks = ARRAY_SIZE(camcc_sc8280xp_clocks), @@ -3011,9 +3021,6 @@ static int camcc_sc8280xp_probe(struct platform_device *pdev) clk_lucid_pll_configure(&camcc_pll6, regmap, &camcc_pll6_config); clk_lucid_pll_configure(&camcc_pll7, regmap, &camcc_pll7_config); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0xc1e4); /* CAMCC_GDSC_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &camcc_sc8280xp_desc, regmap); if (ret) goto err_disable; diff --git a/drivers/clk/qcom/camcc-sm7150.c b/drivers/clk/qcom/camcc-sm7150.c index 6f75689e9847..d06258327ba7 100644 --- a/drivers/clk/qcom/camcc-sm7150.c +++ b/drivers/clk/qcom/camcc-sm7150.c @@ -2008,7 +2008,17 @@ static const struct regmap_config camcc_sm7150_regmap_config = { .fast_io = true, }; +static const u32 camcc_sm7150_critical_cbcrs[] = { + 0xc1a0, /* CAMCC_GDSC_CLK */ +}; + +static const struct qcom_cc_driver_data camcc_sm7150_driver_data = { + .clk_cbcrs = camcc_sm7150_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(camcc_sm7150_critical_cbcrs), +}; + static const struct qcom_cc_desc camcc_sm7150_desc = { + .driver_data = &camcc_sm7150_driver_data, .config = &camcc_sm7150_regmap_config, .clk_hws = camcc_sm7150_hws, .num_clk_hws = ARRAY_SIZE(camcc_sm7150_hws), @@ -2038,9 +2048,6 @@ static int camcc_sm7150_probe(struct platform_device *pdev) clk_fabia_pll_configure(&camcc_pll3, regmap, &camcc_pll3_config); clk_fabia_pll_configure(&camcc_pll4, regmap, &camcc_pll3_config); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0xc1a0); /* CAMCC_GDSC_CLK */ - return qcom_cc_really_probe(&pdev->dev, &camcc_sm7150_desc, regmap); } diff --git a/drivers/clk/qcom/camcc-sm8150.c b/drivers/clk/qcom/camcc-sm8150.c index fcbaff55fc27..27a51abddce2 100644 --- a/drivers/clk/qcom/camcc-sm8150.c +++ b/drivers/clk/qcom/camcc-sm8150.c @@ -2093,7 +2093,17 @@ static const struct regmap_config cam_cc_sm8150_regmap_config = { .fast_io = true, }; +static const u32 cam_cc_sm8150_critical_cbcrs[] = { + 0xc1e4, /* CAM_CC_GDSC_CLK */ +}; + +static const struct qcom_cc_driver_data cam_cc_sm8150_driver_data = { + .clk_cbcrs = cam_cc_sm8150_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_sm8150_critical_cbcrs), +}; + static const struct qcom_cc_desc cam_cc_sm8150_desc = { + .driver_data = &cam_cc_sm8150_driver_data, .config = &cam_cc_sm8150_regmap_config, .clks = cam_cc_sm8150_clocks, .num_clks = ARRAY_SIZE(cam_cc_sm8150_clocks), @@ -2134,9 +2144,6 @@ static int cam_cc_sm8150_probe(struct platform_device *pdev) clk_trion_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config); clk_trion_pll_configure(&cam_cc_pll4, regmap, &cam_cc_pll4_config); - /* Keep the critical clock always-on */ - qcom_branch_set_clk_en(regmap, 0xc1e4); /* cam_cc_gdsc_clk */ - ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_sm8150_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index f8313f9d0e30..60173b076cc5 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -2373,6 +2373,15 @@ void clk_lucid_ole_pll_configure(struct clk_alpha_pll *pll, struct regmap *regma { u32 lval = config->l; + /* + * If the bootloader left the PLL enabled it's likely that there are + * RCGs that will lock up if we disable the PLL below. + */ + if (trion_pll_is_enabled(pll, regmap)) { + pr_debug("Lucid Ole PLL is already enabled, skipping configuration\n"); + return; + } + lval |= TRION_PLL_CAL_VAL << LUCID_EVO_PLL_CAL_L_VAL_SHIFT; lval |= TRION_PLL_CAL_VAL << LUCID_OLE_PLL_RINGOSC_CAL_L_VAL_SHIFT; clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), lval); diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index d7914e59129f..c44c51d860e1 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -1332,7 +1332,10 @@ static int clk_rcg2_set_force_enable(struct clk_hw *hw) /* wait for RCG to turn ON */ for (count = 500; count > 0; count--) { - if (clk_rcg2_is_enabled(hw)) + ret = clk_rcg2_is_enabled(hw); + if (ret < 0) + return ret; + if (ret) return 0; udelay(1); @@ -1361,8 +1364,10 @@ clk_rcg2_shared_force_enable_clear(struct clk_hw *hw, const struct freq_tbl *f) return ret; ret = clk_rcg2_configure(rcg, f); - if (ret) + if (ret) { + clk_rcg2_clear_force_enable(hw); return ret; + } return clk_rcg2_clear_force_enable(hw); } @@ -1555,7 +1560,20 @@ const struct clk_ops clk_rcg2_shared_ops = { }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); +static int clk_rcg2_shared_no_init_park(struct clk_hw *hw) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + + /* + * Read the config register so that the parent is properly mapped at + * registration time. + */ + return regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, + &rcg->parked_cfg); +} + const struct clk_ops clk_rcg2_shared_floor_ops = { + .init = clk_rcg2_shared_no_init_park, .enable = clk_rcg2_shared_enable, .disable = clk_rcg2_shared_disable, .get_parent = clk_rcg2_shared_get_parent, @@ -1567,19 +1585,6 @@ const struct clk_ops clk_rcg2_shared_floor_ops = { }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_floor_ops); -static int clk_rcg2_shared_no_init_park(struct clk_hw *hw) -{ - struct clk_rcg2 *rcg = to_clk_rcg2(hw); - - /* - * Read the config register so that the parent is properly mapped at - * registration time. - */ - regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &rcg->parked_cfg); - - return 0; -} - /* * Like clk_rcg2_shared_ops but skip the init so that the clk frequency is left * unchanged at registration time. diff --git a/drivers/clk/qcom/clk-regmap-divider.c b/drivers/clk/qcom/clk-regmap-divider.c index 672e82caf205..6e12aebf14b6 100644 --- a/drivers/clk/qcom/clk-regmap-divider.c +++ b/drivers/clk/qcom/clk-regmap-divider.c @@ -27,7 +27,8 @@ static int div_ro_determine_rate(struct clk_hw *hw, val &= BIT(divider->width) - 1; return divider_ro_determine_rate(hw, req, NULL, divider->width, - CLK_DIVIDER_ROUND_CLOSEST, val); + CLK_DIVIDER_ROUND_CLOSEST | divider->flags, + val); } static int div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) @@ -35,7 +36,7 @@ static int div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) struct clk_regmap_div *divider = to_clk_regmap_div(hw); return divider_determine_rate(hw, req, NULL, divider->width, - CLK_DIVIDER_ROUND_CLOSEST); + CLK_DIVIDER_ROUND_CLOSEST | divider->flags); } static int div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -43,14 +44,16 @@ static int div_set_rate(struct clk_hw *hw, unsigned long rate, { struct clk_regmap_div *divider = to_clk_regmap_div(hw); struct clk_regmap *clkr = ÷r->clkr; - u32 div; + int div; div = divider_get_val(rate, parent_rate, NULL, divider->width, - CLK_DIVIDER_ROUND_CLOSEST); + CLK_DIVIDER_ROUND_CLOSEST | divider->flags); + if (div < 0) + return div; return regmap_update_bits(clkr->regmap, divider->reg, (BIT(divider->width) - 1) << divider->shift, - div << divider->shift); + (u32)div << divider->shift); } static unsigned long div_recalc_rate(struct clk_hw *hw, @@ -65,7 +68,8 @@ static unsigned long div_recalc_rate(struct clk_hw *hw, div &= BIT(divider->width) - 1; return divider_recalc_rate(hw, parent_rate, div, NULL, - CLK_DIVIDER_ROUND_CLOSEST, divider->width); + CLK_DIVIDER_ROUND_CLOSEST | divider->flags, + divider->width); } const struct clk_ops clk_regmap_div_ops = { diff --git a/drivers/clk/qcom/clk-regmap-divider.h b/drivers/clk/qcom/clk-regmap-divider.h index e75a65c3839c..4fde766b2633 100644 --- a/drivers/clk/qcom/clk-regmap-divider.h +++ b/drivers/clk/qcom/clk-regmap-divider.h @@ -13,6 +13,7 @@ struct clk_regmap_div { u32 reg; u32 shift; u32 width; + unsigned long flags; struct clk_regmap clkr; }; diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index a224a94ae273..68640e5904a6 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -393,6 +393,7 @@ DEFINE_CLK_RPMH_VRM(clk2, _a1_e0, "C2A_E0", 1); DEFINE_CLK_RPMH_VRM(clk3, _a1_e0, "C3A_E0", 1); DEFINE_CLK_RPMH_VRM(clk4, _a1_e0, "C4A_E0", 1); DEFINE_CLK_RPMH_VRM(clk5, _a1_e0, "C5A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk7, _a1_e0, "C7A_E0", 1); DEFINE_CLK_RPMH_VRM(clk8, _a1_e0, "C8A_E0", 1); DEFINE_CLK_RPMH_VRM(clk3, _a2_e0, "C3A_E0", 2); @@ -902,6 +903,10 @@ static struct clk_hw *glymur_rpmh_clocks[] = { [RPMH_RF_CLK4_A] = &clk_rpmh_clk4_a1_e0_ao.hw, [RPMH_RF_CLK5] = &clk_rpmh_clk5_a1_e0.hw, [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a1_e0_ao.hw, + [RPMH_LN_BB_CLK2] = &clk_rpmh_clk7_a1_e0.hw, + [RPMH_LN_BB_CLK2_A] = &clk_rpmh_clk7_a1_e0_ao.hw, + [RPMH_LN_BB_CLK3] = &clk_rpmh_clk8_a1_e0.hw, + [RPMH_LN_BB_CLK3_A] = &clk_rpmh_clk8_a1_e0_ao.hw, }; static const struct clk_rpmh_desc clk_rpmh_glymur = { @@ -937,6 +942,20 @@ static const struct clk_rpmh_desc clk_rpmh_kaanapali = { .num_clks = ARRAY_SIZE(kaanapali_rpmh_clocks), }; +static struct clk_hw *kuno_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, + [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, + [RPMH_RF_CLK1] = &clk_rpmh_rf_clk1_a.hw, + [RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_a_ao.hw, + [RPMH_QPIC_CLK] = &clk_rpmh_qpic_clk.hw, + [RPMH_IPA_CLK] = &clk_rpmh_ipa.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_kuno = { + .clks = kuno_rpmh_clocks, + .num_clks = ARRAY_SIZE(kuno_rpmh_clocks), +}; + static struct clk_hw *eliza_rpmh_clocks[] = { [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, @@ -1005,6 +1024,29 @@ static const struct clk_rpmh_desc clk_rpmh_hawi = { .num_clks = ARRAY_SIZE(hawi_rpmh_clocks), }; +static struct clk_hw *sm7250_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, + [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, + [RPMH_LN_BB_CLK2] = &clk_rpmh_ln_bb_clk2_a2.hw, + [RPMH_LN_BB_CLK2_A] = &clk_rpmh_ln_bb_clk2_a2_ao.hw, + [RPMH_LN_BB_CLK3] = &clk_rpmh_ln_bb_clk3_a2.hw, + [RPMH_LN_BB_CLK3_A] = &clk_rpmh_ln_bb_clk3_a2_ao.hw, + [RPMH_RF_CLK1] = &clk_rpmh_rf_clk1_d.hw, + [RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_d_ao.hw, + [RPMH_RF_CLK2] = &clk_rpmh_rf_clk2_d.hw, + [RPMH_RF_CLK2_A] = &clk_rpmh_rf_clk2_d_ao.hw, + [RPMH_RF_CLK3] = &clk_rpmh_rf_clk3_d.hw, + [RPMH_RF_CLK3_A] = &clk_rpmh_rf_clk3_d_ao.hw, + [RPMH_RF_CLK4] = &clk_rpmh_rf_clk4_d.hw, + [RPMH_RF_CLK4_A] = &clk_rpmh_rf_clk4_d_ao.hw, + [RPMH_IPA_CLK] = &clk_rpmh_ipa.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_sm7250 = { + .clks = sm7250_rpmh_clocks, + .num_clks = ARRAY_SIZE(sm7250_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -1097,6 +1139,7 @@ static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,glymur-rpmh-clk", .data = &clk_rpmh_glymur}, { .compatible = "qcom,hawi-rpmh-clk", .data = &clk_rpmh_hawi}, { .compatible = "qcom,kaanapali-rpmh-clk", .data = &clk_rpmh_kaanapali}, + { .compatible = "qcom,kuno-rpmh-clk", .data = &clk_rpmh_kuno}, { .compatible = "qcom,milos-rpmh-clk", .data = &clk_rpmh_milos}, { .compatible = "qcom,nord-rpmh-clk", .data = &clk_rpmh_nord}, { .compatible = "qcom,qcs615-rpmh-clk", .data = &clk_rpmh_qcs615}, @@ -1114,6 +1157,7 @@ static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,sdx75-rpmh-clk", .data = &clk_rpmh_sdx75}, { .compatible = "qcom,sm4450-rpmh-clk", .data = &clk_rpmh_sm4450}, { .compatible = "qcom,sm6350-rpmh-clk", .data = &clk_rpmh_sm6350}, + { .compatible = "qcom,sm7250-rpmh-clk", .data = &clk_rpmh_sm7250}, { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150}, { .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250}, { .compatible = "qcom,sm8350-rpmh-clk", .data = &clk_rpmh_sm8350}, diff --git a/drivers/clk/qcom/dispcc-sc7280.c b/drivers/clk/qcom/dispcc-sc7280.c index d11265debaf9..24a65cbb1ecf 100644 --- a/drivers/clk/qcom/dispcc-sc7280.c +++ b/drivers/clk/qcom/dispcc-sc7280.c @@ -860,7 +860,17 @@ static const struct regmap_config disp_cc_sc7280_regmap_config = { .fast_io = true, }; +static const u32 disp_cc_sc7280_critical_cbcrs[] = { + 0x5008, /* DISP_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data disp_cc_sc7280_driver_data = { + .clk_cbcrs = disp_cc_sc7280_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_sc7280_critical_cbcrs), +}; + static const struct qcom_cc_desc disp_cc_sc7280_desc = { + .driver_data = &disp_cc_sc7280_driver_data, .config = &disp_cc_sc7280_regmap_config, .clks = disp_cc_sc7280_clocks, .num_clks = ARRAY_SIZE(disp_cc_sc7280_clocks), @@ -886,9 +896,6 @@ static int disp_cc_sc7280_probe(struct platform_device *pdev) clk_lucid_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x5008); /* DISP_CC_XO_CLK */ - return qcom_cc_really_probe(&pdev->dev, &disp_cc_sc7280_desc, regmap); } diff --git a/drivers/clk/qcom/dispcc-sc8280xp.c b/drivers/clk/qcom/dispcc-sc8280xp.c index 96609bd5233f..96b3e5505279 100644 --- a/drivers/clk/qcom/dispcc-sc8280xp.c +++ b/drivers/clk/qcom/dispcc-sc8280xp.c @@ -3108,7 +3108,17 @@ static const struct regmap_config disp_cc_sc8280xp_regmap_config = { .fast_io = true, }; +static const u32 disp_cc_sc8280xp_critical_cbcrs[] = { + 0x605c, /* DISP_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data disp_cc_sc8280xp_driver_data = { + .clk_cbcrs = disp_cc_sc8280xp_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_sc8280xp_critical_cbcrs), +}; + static const struct qcom_cc_desc disp0_cc_sc8280xp_desc = { + .driver_data = &disp_cc_sc8280xp_driver_data, .config = &disp_cc_sc8280xp_regmap_config, .clks = disp0_cc_sc8280xp_clocks, .num_clks = ARRAY_SIZE(disp0_cc_sc8280xp_clocks), @@ -3119,6 +3129,7 @@ static const struct qcom_cc_desc disp0_cc_sc8280xp_desc = { }; static const struct qcom_cc_desc disp1_cc_sc8280xp_desc = { + .driver_data = &disp_cc_sc8280xp_driver_data, .config = &disp_cc_sc8280xp_regmap_config, .clks = disp1_cc_sc8280xp_clocks, .num_clks = ARRAY_SIZE(disp1_cc_sc8280xp_clocks), @@ -3167,13 +3178,8 @@ static int disp_cc_sc8280xp_probe(struct platform_device *pdev) clk_lucid_pll_configure(clkr_to_alpha_clk_pll(desc->clks[DISP_CC_PLL2]), regmap, &disp_cc_pll2_config); ret = qcom_cc_really_probe(&pdev->dev, desc, regmap); - if (ret) { + if (ret) dev_err(&pdev->dev, "Failed to register display clock controller\n"); - goto out_pm_runtime_put; - } - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x605c); /* DISP_CC_XO_CLK */ out_pm_runtime_put: pm_runtime_put_sync(&pdev->dev); diff --git a/drivers/clk/qcom/dispcc-sm4450.c b/drivers/clk/qcom/dispcc-sm4450.c index 4a4811db55dd..f39afa067cc6 100644 --- a/drivers/clk/qcom/dispcc-sm4450.c +++ b/drivers/clk/qcom/dispcc-sm4450.c @@ -719,7 +719,18 @@ static const struct regmap_config disp_cc_sm4450_regmap_config = { .fast_io = true, }; +static const u32 disp_cc_sm4450_critical_cbcrs[] = { + 0xe070, /* DISP_CC_SLEEP_CLK */ + 0xe054, /* DISP_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data disp_cc_sm4450_driver_data = { + .clk_cbcrs = disp_cc_sm4450_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_sm4450_critical_cbcrs), +}; + static const struct qcom_cc_desc disp_cc_sm4450_desc = { + .driver_data = &disp_cc_sm4450_driver_data, .config = &disp_cc_sm4450_regmap_config, .clks = disp_cc_sm4450_clocks, .num_clks = ARRAY_SIZE(disp_cc_sm4450_clocks), @@ -746,10 +757,6 @@ static int disp_cc_sm4450_probe(struct platform_device *pdev) clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll0_config); - /* Keep some clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0xe070); /* DISP_CC_SLEEP_CLK */ - qcom_branch_set_clk_en(regmap, 0xe054); /* DISP_CC_XO_CLK */ - return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm4450_desc, regmap); } diff --git a/drivers/clk/qcom/dispcc-sm6115.c b/drivers/clk/qcom/dispcc-sm6115.c index 9a7b8ad646ed..f6f5edf07f03 100644 --- a/drivers/clk/qcom/dispcc-sm6115.c +++ b/drivers/clk/qcom/dispcc-sm6115.c @@ -561,7 +561,17 @@ static const struct regmap_config disp_cc_sm6115_regmap_config = { .fast_io = true, }; +static const u32 disp_cc_sm6115_critical_cbcrs[] = { + 0x604c, /* DISP_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data disp_cc_sm6115_driver_data = { + .clk_cbcrs = disp_cc_sm6115_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_sm6115_critical_cbcrs), +}; + static const struct qcom_cc_desc disp_cc_sm6115_desc = { + .driver_data = &disp_cc_sm6115_driver_data, .config = &disp_cc_sm6115_regmap_config, .clks = disp_cc_sm6115_clocks, .num_clks = ARRAY_SIZE(disp_cc_sm6115_clocks), @@ -588,9 +598,6 @@ static int disp_cc_sm6115_probe(struct platform_device *pdev) 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_sm6115_desc, regmap); if (ret) { dev_err(&pdev->dev, "Failed to register DISP CC clocks\n"); diff --git a/drivers/clk/qcom/dispcc-sm7150.c b/drivers/clk/qcom/dispcc-sm7150.c index b9df6153e50f..da7610856e56 100644 --- a/drivers/clk/qcom/dispcc-sm7150.c +++ b/drivers/clk/qcom/dispcc-sm7150.c @@ -963,7 +963,17 @@ static const struct regmap_config dispcc_sm7150_regmap_config = { .fast_io = true, }; +static const u32 dispcc_sm7150_critical_cbcrs[] = { + 0x605c, /* DISPCC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data dispcc_sm7150_driver_data = { + .clk_cbcrs = dispcc_sm7150_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(dispcc_sm7150_critical_cbcrs), +}; + static const struct qcom_cc_desc dispcc_sm7150_desc = { + .driver_data = &dispcc_sm7150_driver_data, .config = &dispcc_sm7150_regmap_config, .clks = dispcc_sm7150_clocks, .num_clks = ARRAY_SIZE(dispcc_sm7150_clocks), @@ -991,9 +1001,6 @@ static int dispcc_sm7150_probe(struct platform_device *pdev) /* Enable clock gating for DSI and MDP clocks */ regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x605c); /* DISPCC_XO_CLK */ - return qcom_cc_really_probe(&pdev->dev, &dispcc_sm7150_desc, regmap); } diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c index fdc07323f298..dc62eb18deed 100644 --- a/drivers/clk/qcom/dispcc-sm8250.c +++ b/drivers/clk/qcom/dispcc-sm8250.c @@ -1232,7 +1232,17 @@ static const struct regmap_config disp_cc_sm8250_regmap_config = { .fast_io = true, }; +static const u32 disp_cc_sm8250_critical_cbcrs[] = { + 0x605c, /* DISP_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data disp_cc_sm8250_driver_data = { + .clk_cbcrs = disp_cc_sm8250_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_sm8250_critical_cbcrs), +}; + static const struct qcom_cc_desc disp_cc_sm8250_desc = { + .driver_data = &disp_cc_sm8250_driver_data, .config = &disp_cc_sm8250_regmap_config, .clks = disp_cc_sm8250_clocks, .num_clks = ARRAY_SIZE(disp_cc_sm8250_clocks), @@ -1370,9 +1380,6 @@ static int disp_cc_sm8250_probe(struct platform_device *pdev) /* Enable clock gating for MDP clocks */ regmap_update_bits(regmap, 0x8000, 0x10, 0x10); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x605c); /* DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8250_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/dispcc-sm8450.c b/drivers/clk/qcom/dispcc-sm8450.c index 3af120e54cdd..facbf040ab9a 100644 --- a/drivers/clk/qcom/dispcc-sm8450.c +++ b/drivers/clk/qcom/dispcc-sm8450.c @@ -613,7 +613,7 @@ static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { .parent_data = disp_cc_parent_data_5, .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }, }; @@ -1778,6 +1778,29 @@ static const struct regmap_config disp_cc_sm8450_regmap_config = { .fast_io = true, }; +static struct clk_alpha_pll *disp_cc_sm8450_plls[] = { + &disp_cc_pll0, + &disp_cc_pll1, +}; + +static const u32 disp_cc_sm8450_critical_cbcrs[] = { + 0xe05c, /* DISP_CC_XO_CLK */ +}; + +static void disp_cc_sm8450_clk_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Enable clock gating for MDP clocks */ + regmap_set_bits(regmap, DISP_CC_MISC_CMD, BIT(4)); +} + +static const struct qcom_cc_driver_data disp_cc_sm8450_driver_data = { + .alpha_plls = disp_cc_sm8450_plls, + .num_alpha_plls = ARRAY_SIZE(disp_cc_sm8450_plls), + .clk_cbcrs = disp_cc_sm8450_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_sm8450_critical_cbcrs), + .clk_regs_configure = disp_cc_sm8450_clk_regs_configure, +}; + static const struct qcom_cc_desc disp_cc_sm8450_desc = { .config = &disp_cc_sm8450_regmap_config, .clks = disp_cc_sm8450_clocks, @@ -1786,6 +1809,7 @@ static const struct qcom_cc_desc disp_cc_sm8450_desc = { .num_resets = ARRAY_SIZE(disp_cc_sm8450_resets), .gdscs = disp_cc_sm8450_gdscs, .num_gdscs = ARRAY_SIZE(disp_cc_sm8450_gdscs), + .driver_data = &disp_cc_sm8450_driver_data, }; static const struct of_device_id disp_cc_sm8450_match_table[] = { @@ -1823,19 +1847,13 @@ static int disp_cc_sm8450_probe(struct platform_device *pdev) disp_cc_pll1.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE]; disp_cc_pll1.clkr.hw.init = &sm8475_disp_cc_pll1_init; - clk_lucid_ole_pll_configure(&disp_cc_pll0, regmap, &sm8475_disp_cc_pll0_config); - clk_lucid_ole_pll_configure(&disp_cc_pll1, regmap, &sm8475_disp_cc_pll1_config); + disp_cc_pll0.config = &sm8475_disp_cc_pll0_config; + disp_cc_pll1.config = &sm8475_disp_cc_pll1_config; } else { - clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); - clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config); + disp_cc_pll0.config = &disp_cc_pll0_config; + disp_cc_pll1.config = &disp_cc_pll1_config; } - /* Enable clock gating for MDP clocks */ - regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10); - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0xe05c); /* DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8450_desc, regmap); if (ret) goto err_put_rpm; diff --git a/drivers/clk/qcom/dispcc-sm8550.c b/drivers/clk/qcom/dispcc-sm8550.c index 418dcea20f00..030fc7ef1fbf 100644 --- a/drivers/clk/qcom/dispcc-sm8550.c +++ b/drivers/clk/qcom/dispcc-sm8550.c @@ -1744,7 +1744,17 @@ static const struct regmap_config disp_cc_sm8550_regmap_config = { .fast_io = true, }; +static const u32 disp_cc_sm8550_critical_cbcrs[] = { + 0xe054, /* DISP_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data disp_cc_sm8550_driver_data = { + .clk_cbcrs = disp_cc_sm8550_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_sm8550_critical_cbcrs), +}; + static const struct qcom_cc_desc disp_cc_sm8550_desc = { + .driver_data = &disp_cc_sm8550_driver_data, .config = &disp_cc_sm8550_regmap_config, .clks = disp_cc_sm8550_clocks, .num_clks = ARRAY_SIZE(disp_cc_sm8550_clocks), @@ -1800,9 +1810,6 @@ static int disp_cc_sm8550_probe(struct platform_device *pdev) /* Enable clock gating for MDP clocks */ regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0xe054); /* DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8550_desc, regmap); if (ret) goto err_put_rpm; diff --git a/drivers/clk/qcom/dispcc-sm8750.c b/drivers/clk/qcom/dispcc-sm8750.c index 18e86b80e581..3205ce5c1ad9 100644 --- a/drivers/clk/qcom/dispcc-sm8750.c +++ b/drivers/clk/qcom/dispcc-sm8750.c @@ -1884,7 +1884,20 @@ static const struct regmap_config disp_cc_sm8750_regmap_config = { .fast_io = true, }; +static const u32 disp_cc_sm8750_critical_cbcrs[] = { + 0xe07c, /* DISP_CC_SLEEP_CLK */ + 0xe05c, /* DISP_CC_XO_CLK */ + 0xc00c, /* DISP_CC_MDSS_RSCC_AHB_CLK */ + 0xc008, /* DISP_CC_MDSS_RSCC_VSYNC_CLK */ +}; + +static const struct qcom_cc_driver_data disp_cc_sm8750_driver_data = { + .clk_cbcrs = disp_cc_sm8750_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_sm8750_critical_cbcrs), +}; + static const struct qcom_cc_desc disp_cc_sm8750_desc = { + .driver_data = &disp_cc_sm8750_driver_data, .config = &disp_cc_sm8750_regmap_config, .clks = disp_cc_sm8750_clocks, .num_clks = ARRAY_SIZE(disp_cc_sm8750_clocks), @@ -1926,12 +1939,6 @@ static int disp_cc_sm8750_probe(struct platform_device *pdev) /* Enable clock gating for MDP clocks */ regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0xe07c); /* DISP_CC_SLEEP_CLK */ - qcom_branch_set_clk_en(regmap, 0xe05c); /* DISP_CC_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0xc00c); /* DISP_CC_MDSS_RSCC_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0xc008); /* DISP_CC_MDSS_RSCC_VSYNC_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8750_desc, regmap); if (ret) goto err_put_rpm; diff --git a/drivers/clk/qcom/dispcc-x1e80100.c b/drivers/clk/qcom/dispcc-x1e80100.c index 795279609c0b..aed06203a886 100644 --- a/drivers/clk/qcom/dispcc-x1e80100.c +++ b/drivers/clk/qcom/dispcc-x1e80100.c @@ -1637,7 +1637,18 @@ static const struct regmap_config disp_cc_x1e80100_regmap_config = { .fast_io = true, }; +static const u32 disp_cc_x1e80100_critical_cbcrs[] = { + 0xe074, /* DISP_CC_SLEEP_CLK */ + 0xe054, /* DISP_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data disp_cc_x1e80100_driver_data = { + .clk_cbcrs = disp_cc_x1e80100_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_x1e80100_critical_cbcrs), +}; + static const struct qcom_cc_desc disp_cc_x1e80100_desc = { + .driver_data = &disp_cc_x1e80100_driver_data, .config = &disp_cc_x1e80100_regmap_config, .clks = disp_cc_x1e80100_clocks, .num_clks = ARRAY_SIZE(disp_cc_x1e80100_clocks), @@ -1678,10 +1689,6 @@ static int disp_cc_x1e80100_probe(struct platform_device *pdev) /* Enable clock gating for MDP clocks */ regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10); - /* Keep clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0xe074); /* DISP_CC_SLEEP_CLK */ - qcom_branch_set_clk_en(regmap, 0xe054); /* DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_x1e80100_desc, regmap); if (ret) goto err_put_rpm; @@ -1704,17 +1711,7 @@ static struct platform_driver disp_cc_x1e80100_driver = { }, }; -static int __init disp_cc_x1e80100_init(void) -{ - return platform_driver_register(&disp_cc_x1e80100_driver); -} -subsys_initcall(disp_cc_x1e80100_init); - -static void __exit disp_cc_x1e80100_exit(void) -{ - platform_driver_unregister(&disp_cc_x1e80100_driver); -} -module_exit(disp_cc_x1e80100_exit); +subsys_platform_driver(disp_cc_x1e80100_driver); MODULE_DESCRIPTION("QTI Display Clock Controller X1E80100 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/dispcc0-sa8775p.c b/drivers/clk/qcom/dispcc0-sa8775p.c index 0e976442834a..a1861cc8343e 100644 --- a/drivers/clk/qcom/dispcc0-sa8775p.c +++ b/drivers/clk/qcom/dispcc0-sa8775p.c @@ -1414,7 +1414,18 @@ static const struct regmap_config disp_cc_0_sa8775p_regmap_config = { .fast_io = true, }; +static const u32 disp_cc_0_sa8775p_critical_cbcrs[] = { + 0xc070, /* MDSS_0_DISP_CC_SLEEP_CLK */ + 0xc054, /* MDSS_0_DISP_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data disp_cc_0_sa8775p_driver_data = { + .clk_cbcrs = disp_cc_0_sa8775p_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_0_sa8775p_critical_cbcrs), +}; + static const struct qcom_cc_desc disp_cc_0_sa8775p_desc = { + .driver_data = &disp_cc_0_sa8775p_driver_data, .config = &disp_cc_0_sa8775p_regmap_config, .clks = disp_cc_0_sa8775p_clocks, .num_clks = ARRAY_SIZE(disp_cc_0_sa8775p_clocks), @@ -1452,10 +1463,6 @@ static int disp_cc_0_sa8775p_probe(struct platform_device *pdev) clk_lucid_evo_pll_configure(&mdss_0_disp_cc_pll0, regmap, &mdss_0_disp_cc_pll0_config); clk_lucid_evo_pll_configure(&mdss_0_disp_cc_pll1, regmap, &mdss_0_disp_cc_pll1_config); - /* Keep some clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0xc070); /* MDSS_0_DISP_CC_SLEEP_CLK */ - qcom_branch_set_clk_en(regmap, 0xc054); /* MDSS_0_DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_0_sa8775p_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/dispcc1-sa8775p.c b/drivers/clk/qcom/dispcc1-sa8775p.c index 58008c1afc76..330d953b5e9e 100644 --- a/drivers/clk/qcom/dispcc1-sa8775p.c +++ b/drivers/clk/qcom/dispcc1-sa8775p.c @@ -1414,7 +1414,18 @@ static const struct regmap_config disp_cc_1_sa8775p_regmap_config = { .fast_io = true, }; +static const u32 disp_cc_1_sa8775p_critical_cbcrs[] = { + 0xc070, /* MDSS_1_DISP_CC_SLEEP_CLK */ + 0xc054, /* MDSS_1_DISP_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data disp_cc_1_sa8775p_driver_data = { + .clk_cbcrs = disp_cc_1_sa8775p_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_1_sa8775p_critical_cbcrs), +}; + static const struct qcom_cc_desc disp_cc_1_sa8775p_desc = { + .driver_data = &disp_cc_1_sa8775p_driver_data, .config = &disp_cc_1_sa8775p_regmap_config, .clks = disp_cc_1_sa8775p_clocks, .num_clks = ARRAY_SIZE(disp_cc_1_sa8775p_clocks), @@ -1452,10 +1463,6 @@ static int disp_cc_1_sa8775p_probe(struct platform_device *pdev) clk_lucid_evo_pll_configure(&mdss_1_disp_cc_pll0, regmap, &mdss_1_disp_cc_pll0_config); clk_lucid_evo_pll_configure(&mdss_1_disp_cc_pll1, regmap, &mdss_1_disp_cc_pll1_config); - /* Keep some clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0xc070); /* MDSS_1_DISP_CC_SLEEP_CLK */ - qcom_branch_set_clk_en(regmap, 0xc054); /* MDSS_1_DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_1_sa8775p_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/gcc-eliza.c b/drivers/clk/qcom/gcc-eliza.c index fe18942a59ac..064771726e9b 100644 --- a/drivers/clk/qcom/gcc-eliza.c +++ b/drivers/clk/qcom/gcc-eliza.c @@ -3068,6 +3068,7 @@ static const struct qcom_cc_desc gcc_eliza_desc = { .num_resets = ARRAY_SIZE(gcc_eliza_resets), .gdscs = gcc_eliza_gdscs, .num_gdscs = ARRAY_SIZE(gcc_eliza_gdscs), + .use_rpm = true, .driver_data = &gcc_eliza_driver_data, }; @@ -3090,17 +3091,7 @@ static struct platform_driver gcc_eliza_driver = { }, }; -static int __init gcc_eliza_init(void) -{ - return platform_driver_register(&gcc_eliza_driver); -} -subsys_initcall(gcc_eliza_init); - -static void __exit gcc_eliza_exit(void) -{ - platform_driver_unregister(&gcc_eliza_driver); -} -module_exit(gcc_eliza_exit); +subsys_platform_driver(gcc_eliza_driver); MODULE_DESCRIPTION("QTI GCC Eliza Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-glymur.c b/drivers/clk/qcom/gcc-glymur.c index 2ee4820b6fdf..be18a555fe31 100644 --- a/drivers/clk/qcom/gcc-glymur.c +++ b/drivers/clk/qcom/gcc-glymur.c @@ -481,36 +481,6 @@ static const struct clk_parent_data gcc_parent_data_17[] = { { .hw = &gcc_gpll0_out_even.clkr.hw }, }; -static const struct parent_map gcc_parent_map_18[] = { - { P_UFS_PHY_RX_SYMBOL_0_CLK, 0 }, - { P_BI_TCXO, 2 }, -}; - -static const struct clk_parent_data gcc_parent_data_18[] = { - { .index = DT_UFS_PHY_RX_SYMBOL_0_CLK }, - { .index = DT_BI_TCXO }, -}; - -static const struct parent_map gcc_parent_map_19[] = { - { P_UFS_PHY_RX_SYMBOL_1_CLK, 0 }, - { P_BI_TCXO, 2 }, -}; - -static const struct clk_parent_data gcc_parent_data_19[] = { - { .index = DT_UFS_PHY_RX_SYMBOL_1_CLK }, - { .index = DT_BI_TCXO }, -}; - -static const struct parent_map gcc_parent_map_20[] = { - { P_UFS_PHY_TX_SYMBOL_0_CLK, 0 }, - { P_BI_TCXO, 2 }, -}; - -static const struct clk_parent_data gcc_parent_data_20[] = { - { .index = DT_UFS_PHY_TX_SYMBOL_0_CLK }, - { .index = DT_BI_TCXO }, -}; - static const struct parent_map gcc_parent_map_21[] = { { P_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC, 0 }, { P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, @@ -907,47 +877,44 @@ static struct clk_regmap_phy_mux gcc_pcie_6_pipe_clk_src = { }, }; -static struct clk_regmap_mux gcc_ufs_phy_rx_symbol_0_clk_src = { +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_0_clk_src = { .reg = 0x7706c, - .shift = 0, - .width = 2, - .parent_map = gcc_parent_map_18, .clkr = { .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_rx_symbol_0_clk_src", - .parent_data = gcc_parent_data_18, - .num_parents = ARRAY_SIZE(gcc_parent_data_18), - .ops = &clk_regmap_mux_closest_ops, + .parent_data = &(const struct clk_parent_data){ + .index = DT_UFS_PHY_RX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, }, }, }; -static struct clk_regmap_mux gcc_ufs_phy_rx_symbol_1_clk_src = { +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_1_clk_src = { .reg = 0x770f0, - .shift = 0, - .width = 2, - .parent_map = gcc_parent_map_19, .clkr = { .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_rx_symbol_1_clk_src", - .parent_data = gcc_parent_data_19, - .num_parents = ARRAY_SIZE(gcc_parent_data_19), - .ops = &clk_regmap_mux_closest_ops, + .parent_data = &(const struct clk_parent_data){ + .index = DT_UFS_PHY_RX_SYMBOL_1_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, }, }, }; -static struct clk_regmap_mux gcc_ufs_phy_tx_symbol_0_clk_src = { +static struct clk_regmap_phy_mux gcc_ufs_phy_tx_symbol_0_clk_src = { .reg = 0x7705c, - .shift = 0, - .width = 2, - .parent_map = gcc_parent_map_20, .clkr = { .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_tx_symbol_0_clk_src", - .parent_data = gcc_parent_data_20, - .num_parents = ARRAY_SIZE(gcc_parent_data_20), - .ops = &clk_regmap_mux_closest_ops, + .parent_data = &(const struct clk_parent_data){ + .index = DT_UFS_PHY_TX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, }, }, }; @@ -8571,17 +8538,7 @@ static struct platform_driver gcc_glymur_driver = { }, }; -static int __init gcc_glymur_init(void) -{ - return platform_driver_register(&gcc_glymur_driver); -} -subsys_initcall(gcc_glymur_init); - -static void __exit gcc_glymur_exit(void) -{ - platform_driver_unregister(&gcc_glymur_driver); -} -module_exit(gcc_glymur_exit); +subsys_platform_driver(gcc_glymur_driver); MODULE_DESCRIPTION("QTI GCC Glymur Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-hawi.c b/drivers/clk/qcom/gcc-hawi.c index f1b95753c3a3..39fd5f56ca61 100644 --- a/drivers/clk/qcom/gcc-hawi.c +++ b/drivers/clk/qcom/gcc-hawi.c @@ -3843,17 +3843,7 @@ static struct platform_driver gcc_hawi_driver = { }, }; -static int __init gcc_hawi_init(void) -{ - return platform_driver_register(&gcc_hawi_driver); -} -subsys_initcall(gcc_hawi_init); - -static void __exit gcc_hawi_exit(void) -{ - platform_driver_unregister(&gcc_hawi_driver); -} -module_exit(gcc_hawi_exit); +subsys_platform_driver(gcc_hawi_driver); MODULE_DESCRIPTION("QTI GCC HAWI Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-ipq5018.c b/drivers/clk/qcom/gcc-ipq5018.c index 594dae3bac4c..add6a53d4df5 100644 --- a/drivers/clk/qcom/gcc-ipq5018.c +++ b/drivers/clk/qcom/gcc-ipq5018.c @@ -68,6 +68,15 @@ static struct clk_alpha_pll gpll0_main = { .parent_data = gcc_xo_data, .num_parents = ARRAY_SIZE(gcc_xo_data), .ops = &clk_alpha_pll_stromer_ops, + /* + * During system boot, this PLL feeds the CPUs. + * Mark it as critical to ensure that CCF does + * not disable it, even if there are no active + * consumers. This is needed to avoid a system + * hang caused by turning off the clock driving + * the CPUs. + */ + .flags = CLK_IS_CRITICAL, }, }, }; @@ -1260,6 +1269,7 @@ static struct clk_rcg2 usb0_master_clk_src = { }; static const struct freq_tbl ftbl_usb0_mock_utmi_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), F(60000000, P_GPLL4, 10, 1, 2), { } }; diff --git a/drivers/clk/qcom/gcc-ipq5210.c b/drivers/clk/qcom/gcc-ipq5210.c index 3a786a21bdff..76adfa8bf2ad 100644 --- a/drivers/clk/qcom/gcc-ipq5210.c +++ b/drivers/clk/qcom/gcc-ipq5210.c @@ -716,6 +716,7 @@ static struct clk_rcg2 gcc_usb0_master_clk_src = { }; static const struct freq_tbl ftbl_gcc_usb0_mock_utmi_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), F(60000000, P_GPLL4_OUT_AUX, 10, 1, 2), { } }; diff --git a/drivers/clk/qcom/gcc-ipq5332.c b/drivers/clk/qcom/gcc-ipq5332.c index ecd9ebeed754..4625b447c235 100644 --- a/drivers/clk/qcom/gcc-ipq5332.c +++ b/drivers/clk/qcom/gcc-ipq5332.c @@ -1038,6 +1038,7 @@ static struct clk_rcg2 gcc_usb0_master_clk_src = { }; static const struct freq_tbl ftbl_gcc_usb0_mock_utmi_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), F(60000000, P_GPLL4_OUT_AUX, 10, 1, 2), { } }; diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c index 3ddd4b3aedea..32243e110b27 100644 --- a/drivers/clk/qcom/gcc-ipq5424.c +++ b/drivers/clk/qcom/gcc-ipq5424.c @@ -2949,7 +2949,7 @@ static const struct qcom_reset_map gcc_ipq5424_resets[] = { [GCC_QUPV3_SPI0_BCR] = { 0x04000, 0 }, [GCC_QUPV3_SPI1_BCR] = { 0x05000, 0 }, [GCC_IMEM_BCR] = { 0x0e000, 0 }, - [GCC_TME_BCR] = { 0x100000, 0 }, + [GCC_TME_BCR] = { 0x10000, 0 }, [GCC_DDRSS_BCR] = { 0x11000, 0 }, [GCC_PRNG_BCR] = { 0x13020, 0 }, [GCC_BOOT_ROM_BCR] = { 0x13028, 0 }, @@ -2960,7 +2960,7 @@ static const struct qcom_reset_map gcc_ipq5424_resets[] = { [GCC_UNIPHY2_BCR] = { 0x17064, 0 }, [GCC_WCSS_BCR] = { 0x18004, 0 }, [GCC_SEC_CTRL_BCR] = { 0x1a000, 0 }, - [GCC_TME_SEC_BUS_BCR] = { 0xa1030, 0 }, + [GCC_TME_SEC_BUS_BCR] = { 0x1a030, 0 }, [GCC_ADSS_BCR] = { 0x1c000, 0 }, [GCC_LPASS_BCR] = { 0x27000, 0 }, [GCC_PCIE0_BCR] = { 0x28000, 0 }, diff --git a/drivers/clk/qcom/gcc-ipq9650.c b/drivers/clk/qcom/gcc-ipq9650.c index e65a52fdfa91..8c09a757c11d 100644 --- a/drivers/clk/qcom/gcc-ipq9650.c +++ b/drivers/clk/qcom/gcc-ipq9650.c @@ -4,11 +4,13 @@ */ #include +#include #include #include #include #include +#include #include #include "clk-alpha-pll.h" @@ -3474,6 +3476,22 @@ static const struct qcom_reset_map gcc_ipq9650_resets[] = { [GCC_USB_BCR] = { 0x2c000 }, }; +#define IPQ_APPS_ID 9650 /* some unique value */ + +static const struct qcom_icc_hws_data icc_ipq9650_hws[] = { + { MASTER_ANOC_PCIE0, SLAVE_ANOC_PCIE0, GCC_ANOC_PCIE0_1LANE_M_CLK }, + { MASTER_CNOC_PCIE0, SLAVE_CNOC_PCIE0, GCC_ANOC_PCIE0_1LANE_S_CLK }, + { MASTER_ANOC_PCIE1, SLAVE_ANOC_PCIE1, GCC_ANOC_PCIE1_2LANE_M_CLK }, + { MASTER_CNOC_PCIE1, SLAVE_CNOC_PCIE1, GCC_ANOC_PCIE1_2LANE_S_CLK }, + { MASTER_ANOC_PCIE2, SLAVE_ANOC_PCIE2, GCC_ANOC_PCIE2_2LANE_M_CLK }, + { MASTER_CNOC_PCIE2, SLAVE_CNOC_PCIE2, GCC_ANOC_PCIE2_2LANE_S_CLK }, + { MASTER_ANOC_PCIE3, SLAVE_ANOC_PCIE3, GCC_ANOC_PCIE3_2LANE_M_CLK }, + { MASTER_CNOC_PCIE3, SLAVE_CNOC_PCIE3, GCC_ANOC_PCIE3_2LANE_S_CLK }, + { MASTER_ANOC_PCIE4, SLAVE_ANOC_PCIE4, GCC_ANOC_PCIE4_1LANE_M_CLK }, + { MASTER_CNOC_PCIE4, SLAVE_CNOC_PCIE4, GCC_ANOC_PCIE4_1LANE_S_CLK }, + { MASTER_SNOC_USB, SLAVE_SNOC_USB, GCC_SNOC_USB_CLK }, +}; + static const struct of_device_id gcc_ipq9650_match_table[] = { { .compatible = "qcom,ipq9650-gcc" }, { } @@ -3503,6 +3521,9 @@ static const struct qcom_cc_desc gcc_ipq9650_desc = { .num_resets = ARRAY_SIZE(gcc_ipq9650_resets), .clk_hws = gcc_ipq9650_hws, .num_clk_hws = ARRAY_SIZE(gcc_ipq9650_hws), + .icc_hws = icc_ipq9650_hws, + .num_icc_hws = ARRAY_SIZE(icc_ipq9650_hws), + .icc_first_node_id = IPQ_APPS_ID, }; static int gcc_ipq9650_probe(struct platform_device *pdev) @@ -3515,6 +3536,7 @@ static struct platform_driver gcc_ipq9650_driver = { .driver = { .name = "qcom,gcc-ipq9650", .of_match_table = gcc_ipq9650_match_table, + .sync_state = icc_sync_state, }, }; diff --git a/drivers/clk/qcom/gcc-kaanapali.c b/drivers/clk/qcom/gcc-kaanapali.c index 5bcbcd178657..c9473fb79ccc 100644 --- a/drivers/clk/qcom/gcc-kaanapali.c +++ b/drivers/clk/qcom/gcc-kaanapali.c @@ -3502,6 +3502,7 @@ static const struct qcom_cc_desc gcc_kaanapali_desc = { .num_resets = ARRAY_SIZE(gcc_kaanapali_resets), .gdscs = gcc_kaanapali_gdscs, .num_gdscs = ARRAY_SIZE(gcc_kaanapali_gdscs), + .use_rpm = true, .driver_data = &gcc_kaanapali_driver_data, }; @@ -3524,17 +3525,7 @@ static struct platform_driver gcc_kaanapali_driver = { }, }; -static int __init gcc_kaanapali_init(void) -{ - return platform_driver_register(&gcc_kaanapali_driver); -} -subsys_initcall(gcc_kaanapali_init); - -static void __exit gcc_kaanapali_exit(void) -{ - platform_driver_unregister(&gcc_kaanapali_driver); -} -module_exit(gcc_kaanapali_exit); +subsys_platform_driver(gcc_kaanapali_driver); MODULE_DESCRIPTION("QTI GCC Kaanapali Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-kuno.c b/drivers/clk/qcom/gcc-kuno.c new file mode 100644 index 000000000000..55a2fbc74268 --- /dev/null +++ b/drivers/clk/qcom/gcc-kuno.c @@ -0,0 +1,1473 @@ +// 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 "clk-regmap-mux.h" +#include "clk-regmap-phy-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +/* Need to match the order of clocks in DT binding */ +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, + DT_PCIE_PIPE_CLK, +}; + +enum { + P_BI_TCXO, + P_GPLL0_OUT_EVEN, + P_GPLL0_OUT_MAIN, + P_GPLL2_OUT_MAIN, + P_GPLL3_OUT_MAIN, + P_GPLL4_OUT_EVEN, + P_GPLL4_OUT_MAIN, + P_SLEEP_CLK, +}; + +static struct clk_alpha_pll gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], + .clkr = { + .enable_reg = 0x7d000, + .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_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_gpll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_lucid_evo_ops, + }, +}; + +static struct clk_alpha_pll gpll2 = { + .offset = 0x2000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], + .clkr = { + .enable_reg = 0x7d000, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gpll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_lucid_evo_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll3 = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], + .clkr = { + .enable_reg = 0x7d000, + .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_lucid_evo_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll4 = { + .offset = 0x4000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], + .clkr = { + .enable_reg = 0x7d000, + .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_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll4_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll4_out_even = { + .offset = 0x4000, + .post_div_shift = 10, + .post_div_table = post_div_table_gpll4_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gpll4_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll4_out_even", + .parent_hws = (const struct clk_hw*[]) { + &gpll4.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_lucid_evo_ops, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL4_OUT_EVEN, 2 }, + { P_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll4_out_even.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL4_OUT_EVEN, 2 }, + { P_SLEEP_CLK, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll4_out_even.clkr.hw }, + { .index = DT_SLEEP_CLK }, + { .hw = &gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL4_OUT_EVEN, 2 }, + { P_GPLL4_OUT_MAIN, 3 }, + { P_GPLL2_OUT_MAIN, 4 }, + { P_GPLL3_OUT_MAIN, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll4_out_even.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll2.clkr.hw }, + { .hw = &gpll3.clkr.hw }, + { .hw = &gpll0_out_even.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_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 2 }, +}; + +static struct clk_regmap_mux gcc_pcie_aux_clk_src = { + .reg = 0x5308c, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_6, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_aux_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_pcie_pipe_clk_src = { + .reg = 0x53070, + .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 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 = 0x7102c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_phy_aux_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac0_ptp_clk_src[] = { + F(62500000, P_GPLL4_OUT_EVEN, 4, 0, 0), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(125000000, P_GPLL2_OUT_MAIN, 4, 0, 0), + F(230400000, P_GPLL3_OUT_MAIN, 3.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac0_ptp_clk_src = { + .cmd_rcgr = 0x71064, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_emac0_ptp_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_ptp_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac0_rgmii_clk_src[] = { + F(41666667, P_GPLL4_OUT_EVEN, 6, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(125000000, P_GPLL2_OUT_MAIN, 4, 0, 0), + F(250000000, P_GPLL2_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac0_rgmii_clk_src = { + .cmd_rcgr = 0x7104c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_emac0_rgmii_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_rgmii_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(41666667, P_GPLL4_OUT_EVEN, 6, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x47004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .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_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x48004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .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_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x49004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .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_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_aux_phy_clk_src = { + .cmd_rcgr = 0x53074, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .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_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_rchng_phy_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(83333333, P_GPLL4_OUT_EVEN, 3, 0, 0), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_rchng_phy_clk_src = { + .cmd_rcgr = 0x53038, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_rchng_phy_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_rchng_phy_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x34010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_pdm2_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm2_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25), + F(62500000, P_GPLL4_OUT_EVEN, 4, 0, 0), + F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GPLL0_OUT_MAIN, 6, 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_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { + .cmd_rcgr = 0x6c004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .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_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { + .cmd_rcgr = 0x6c13c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .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_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { + .cmd_rcgr = 0x6c274, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .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_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { + .cmd_rcgr = 0x6c3ac, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .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_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { + .cmd_rcgr = 0x6c4e4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_EVEN, 12, 1, 1), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(83333333, P_GPLL4_OUT_EVEN, 3, 0, 0), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { + .cmd_rcgr = 0x6a01c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_apps_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb20_master_clk_src[] = { + F(50000000, P_GPLL4_OUT_EVEN, 5, 0, 0), + F(60000000, P_GPLL0_OUT_EVEN, 5, 0, 0), + F(120000000, P_GPLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb20_master_clk_src = { + .cmd_rcgr = 0x27048, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb20_master_clk_src, + .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_ops, + }, +}; + +static struct clk_rcg2 gcc_usb20_mock_utmi_clk_src = { + .cmd_rcgr = 0x2702c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_mock_utmi_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div gcc_usb20_mock_utmi_postdiv_clk_src = { + .reg = 0x27044, + .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_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x37004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x37004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7d008, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_axi_clk = { + .halt_reg = 0x71018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x71018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_phy_aux_clk = { + .halt_reg = 0x71028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x71028, + .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 = 0x71044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x71044, + .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 = 0x71048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x71048, + .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_emac0_slv_ahb_clk = { + .halt_reg = 0x71024, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x71024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_slv_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac_0_clkref_en = { + .halt_reg = 0x94004, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x94004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac_0_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x47000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x47000, + .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 = 0x48000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x48000, + .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 = 0x49000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x49000, + .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_pcie_0_clkref_en = { + .halt_reg = 0x94000, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x94000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_aux_clk = { + .halt_reg = 0x53054, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x53054, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7d010, + .enable_mask = BIT(15), + .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 = 0x53034, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x53034, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7d010, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_mstr_axi_clk = { + .halt_reg = 0x53028, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x53028, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7d010, + .enable_mask = BIT(12), + .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 = 0x53064, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x53064, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7d010, + .enable_mask = BIT(17), + .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 = 0x53050, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x53050, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7d010, + .enable_mask = BIT(14), + .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 = 0x53060, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x53060, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7d010, + .enable_mask = BIT(16), + .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 = 0x5301c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d010, + .enable_mask = BIT(11), + .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 = 0x53018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x53018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7d010, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3400c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3400c, + .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 = 0x34004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x34004, + .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 = 0x34008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x34008, + .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_qupv3_wrap0_core_2x_clk = { + .halt_reg = 0x2d018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d008, + .enable_mask = BIT(15), + .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 = 0x2d008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d008, + .enable_mask = BIT(14), + .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 = 0x6c130, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d008, + .enable_mask = BIT(16), + .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 = 0x6c268, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d008, + .enable_mask = BIT(17), + .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 = 0x6c3a0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d008, + .enable_mask = BIT(18), + .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 = 0x6c4d8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d008, + .enable_mask = BIT(19), + .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 = 0x6c610, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d008, + .enable_mask = BIT(20), + .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_wrap_0_m_ahb_clk = { + .halt_reg = 0x2d000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2d000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7d008, + .enable_mask = BIT(12), + .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 = 0x2d004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2d004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7d008, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_0_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_ahb_clk = { + .halt_reg = 0x6a010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6a010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_apps_clk = { + .halt_reg = 0x6a004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6a004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc4_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_snoc_cnoc_usb3_clk = { + .halt_reg = 0x27060, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x27060, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x27060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_snoc_cnoc_usb3_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_usb_sf_axi_clk = { + .halt_reg = 0x27064, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x27064, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x27064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sys_noc_usb_sf_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_usb20_master_clk = { + .halt_reg = 0x27018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x27018, + .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 = 0x27028, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x27028, + .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 = 0x27024, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x27024, + .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_usb2_clkref_en = { + .halt_reg = 0x94008, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x94008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb2_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_clkref_en = { + .halt_reg = 0x9400c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x9400c, + .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_usb_phy_cfg_ahb2phy_clk = { + .halt_reg = 0x29004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x29004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x29004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb_phy_cfg_ahb2phy_clk", + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct gdsc gcc_emac0_gdsc = { + .gdscr = 0x71004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_emac0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_pcie_gdsc = { + .gdscr = 0x53004, + .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 = RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb20_gdsc = { + .gdscr = 0x27004, + .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 = RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gcc_kuno_clocks[] = { + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_EMAC0_AXI_CLK] = &gcc_emac0_axi_clk.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_EMAC0_SLV_AHB_CLK] = &gcc_emac0_slv_ahb_clk.clkr, + [GCC_EMAC_0_CLKREF_EN] = &gcc_emac_0_clkref_en.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_PCIE_0_CLKREF_EN] = &gcc_pcie_0_clkref_en.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_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_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_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_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_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, + [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, + [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr, + [GCC_SNOC_CNOC_USB3_CLK] = &gcc_snoc_cnoc_usb3_clk.clkr, + [GCC_SYS_NOC_USB_SF_AXI_CLK] = &gcc_sys_noc_usb_sf_axi_clk.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_USB2_CLKREF_EN] = &gcc_usb2_clkref_en.clkr, + [GCC_USB3_PRIM_CLKREF_EN] = &gcc_usb3_prim_clkref_en.clkr, + [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr, + [GPLL0] = &gpll0.clkr, + [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, + [GPLL2] = &gpll2.clkr, + [GPLL3] = &gpll3.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL4_OUT_EVEN] = &gpll4_out_even.clkr, +}; + +static const struct qcom_reset_map gcc_kuno_resets[] = { + [GCC_EMAC0_BCR] = { 0x71000 }, + [GCC_PCIE_BCR] = { 0x53000 }, + [GCC_PCIE_LINK_DOWN_BCR] = { 0x87000 }, + [GCC_PCIE_NOCSR_COM_PHY_BCR] = { 0x88008 }, + [GCC_PCIE_PHY_BCR] = { 0x54000 }, + [GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x88000 }, + [GCC_PCIE_PHY_COM_BCR] = { 0x88004 }, + [GCC_PCIE_PHY_NOCSR_COM_PHY_BCR] = { 0x8800c }, + [GCC_PDM_BCR] = { 0x34000 }, + [GCC_QUPV3_WRAPPER_0_BCR] = { 0x6c000 }, + [GCC_QUSB2PHY_BCR] = { 0x2a000 }, + [GCC_SDCC4_BCR] = { 0x6a000 }, + [GCC_TCSR_PCIE_BCR] = { 0x84000 }, + [GCC_USB20_BCR] = { 0x27000 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x29000 }, +}; + +static struct gdsc *gcc_kuno_gdscs[] = { + [GCC_EMAC0_GDSC] = &gcc_emac0_gdsc, + [GCC_PCIE_GDSC] = &gcc_pcie_gdsc, + [GCC_USB20_GDSC] = &gcc_usb20_gdsc, +}; + +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), + 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), +}; + +static const struct regmap_config gcc_kuno_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1f41f0, + .fast_io = true, +}; + +static const u32 gcc_kuno_critical_cbcrs[] = { + 0x3e004, /* GCC_AHB_PCIE_LINK_CLK */ + 0x3e008, /* GCC_XO_PCIE_LINK_CLK */ +}; + +static const struct qcom_cc_driver_data gcc_kuno_driver_data = { + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_cbcrs = gcc_kuno_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_kuno_critical_cbcrs), +}; + +static const struct qcom_cc_desc gcc_kuno_desc = { + .config = &gcc_kuno_regmap_config, + .clks = gcc_kuno_clocks, + .num_clks = ARRAY_SIZE(gcc_kuno_clocks), + .resets = gcc_kuno_resets, + .num_resets = ARRAY_SIZE(gcc_kuno_resets), + .gdscs = gcc_kuno_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_kuno_gdscs), + .use_rpm = true, + .driver_data = &gcc_kuno_driver_data, +}; + +static const struct of_device_id gcc_kuno_match_table[] = { + { .compatible = "qcom,kuno-gcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_kuno_match_table); + +static int gcc_kuno_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gcc_kuno_desc); +} + +static struct platform_driver gcc_kuno_driver = { + .probe = gcc_kuno_probe, + .driver = { + .name = "gcc-kuno", + .of_match_table = gcc_kuno_match_table, + }, +}; + +subsys_platform_driver(gcc_kuno_driver); + +MODULE_DESCRIPTION("QTI GCC Kuno Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-milos.c b/drivers/clk/qcom/gcc-milos.c index 4219af2879d9..10a5f3ab0d42 100644 --- a/drivers/clk/qcom/gcc-milos.c +++ b/drivers/clk/qcom/gcc-milos.c @@ -3208,17 +3208,7 @@ static struct platform_driver gcc_milos_driver = { }, }; -static int __init gcc_milos_init(void) -{ - return platform_driver_register(&gcc_milos_driver); -} -subsys_initcall(gcc_milos_init); - -static void __exit gcc_milos_exit(void) -{ - platform_driver_unregister(&gcc_milos_driver); -} -module_exit(gcc_milos_exit); +subsys_platform_driver(gcc_milos_driver); MODULE_DESCRIPTION("QTI GCC Milos Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c index ffd7f14fcbaf..3900a06189ff 100644 --- a/drivers/clk/qcom/gcc-msm8939.c +++ b/drivers/clk/qcom/gcc-msm8939.c @@ -3665,6 +3665,7 @@ static struct clk_branch gcc_venus0_vcodec0_clk = { static struct clk_branch gcc_venus0_core0_vcodec0_clk = { .halt_reg = 0x4c02c, + .halt_check = BRANCH_HALT, .clkr = { .enable_reg = 0x4c02c, .enable_mask = BIT(0), @@ -3682,6 +3683,7 @@ static struct clk_branch gcc_venus0_core0_vcodec0_clk = { static struct clk_branch gcc_venus0_core1_vcodec0_clk = { .halt_reg = 0x4c034, + .halt_check = BRANCH_HALT, .clkr = { .enable_reg = 0x4c034, .enable_mask = BIT(0), @@ -3754,6 +3756,7 @@ static struct gdsc venus_core0_gdsc = { .pd = { .name = "venus_core0", }, + .flags = HW_CTRL_TRIGGER, .pwrsts = PWRSTS_OFF_ON, }; @@ -3762,6 +3765,7 @@ static struct gdsc venus_core1_gdsc = { .pd = { .name = "venus_core1", }, + .flags = HW_CTRL_TRIGGER, .pwrsts = PWRSTS_OFF_ON, }; diff --git a/drivers/clk/qcom/gcc-msm8952.c b/drivers/clk/qcom/gcc-msm8952.c new file mode 100644 index 000000000000..de2811307a86 --- /dev/null +++ b/drivers/clk/qcom/gcc-msm8952.c @@ -0,0 +1,3548 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2026 Muzaffer Kadir + * + * Based on gcc-msm8939.c: + * Copyright 2020 Linaro Limited + * adapted with data from clock-gcc-8952.c in Qualcomm's msm-3.10 release + * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. + * with parts taken from gcc-msm8976.c: + * Copyright (c) 2016-2021, AngeloGioacchino Del Regno + * + * Copyright (c) 2021, Konrad Dybcio + * Marijn Suijten + * with some resets copied from gcc-msm8953: + * Copyright (c) 2021, The Linux Foundation. All rights reserved + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-alpha-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" +#include "gdsc.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_DSI0PLL, + DT_DSI0PLL_BYTE, +}; + +enum { + P_XO, + P_XO_A, + P_GPLL0, + P_GPLL0_OUT_MAIN, + P_GPLL0_AUX, + P_GPLL3, + P_GPLL4, + P_GPLL6, + P_GPLL6_AUX, + P_GPLL6_OUT_MAIN, + P_DSI0_PHYPLL_BYTE, + P_DSI0_PHYPLL_DSI, +}; + +static const struct clk_parent_data gcc_xo_parent_data[] = { + { .index = DT_BI_TCXO }, +}; + +static struct clk_pll gpll0 = { + .l_reg = 0x21004, + .m_reg = 0x21008, + .n_reg = 0x2100c, + .config_reg = 0x21014, + .mode_reg = 0x21000, + .status_reg = 0x2101c, + .status_bit = 17, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_data = gcc_xo_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_parent_data), + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap gpll0_vote = { + .enable_reg = 0x45000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_vote", + .parent_hws = (const struct clk_hw*[]) { + &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static const struct pll_vco gpll3_p_vco[] = { + { 700000000, 1400000000, 0 }, +}; + +static const struct alpha_pll_config gpll3_early_config = { + .l = 63, + .config_ctl_val = 0x4001055b, + .main_output_mask = BIT(0), + .test_ctl_val = 0x0, + .test_ctl_mask = GENMASK(31, 0), + .test_ctl_hi_val = 0x40000600, + .test_ctl_hi_mask = GENMASK(31, 0), + .alpha_en_mask = BIT(24), + .post_div_val = BIT(8), + .post_div_mask = GENMASK(11, 8), +}; + +static struct clk_alpha_pll gpll3_early = { + .offset = 0x22000, + .config = &gpll3_early_config, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .vco_table = gpll3_p_vco, + .num_vco = ARRAY_SIZE(gpll3_p_vco), + .flags = SUPPORTS_DYNAMIC_UPDATE, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll3_early", + .parent_data = gcc_xo_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_parent_data), + .ops = &clk_alpha_pll_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll3 = { + .offset = 0x22000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll3", + .parent_hws = (const struct clk_hw*[]){ + &gpll3_early.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_pll gpll4 = { + .l_reg = 0x24004, + .m_reg = 0x24008, + .n_reg = 0x2400c, + .config_reg = 0x24018, + .mode_reg = 0x24000, + .status_reg = 0x24000, + .status_bit = 30, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll4", + .parent_data = gcc_xo_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_parent_data), + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap gpll4_vote = { + .enable_reg = 0x45000, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gpll4_vote", + .parent_hws = (const struct clk_hw*[]) { + &gpll4.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static struct clk_pll gpll6 = { + .l_reg = 0x37004, + .m_reg = 0x37008, + .n_reg = 0x3700c, + .config_reg = 0x37014, + .mode_reg = 0x37000, + .status_reg = 0x3701c, + .status_bit = 17, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll6", + .parent_data = gcc_xo_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_parent_data), + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap gpll6_vote = { + .enable_reg = 0x45000, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gpll6_vote", + .parent_hws = (const struct clk_hw*[]) { + &gpll6.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static const struct parent_map gcc_xo_gpll0_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_parent_data[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0_vote.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_out_main_map[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_out_main_parent_data[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0_vote.hw }, +}; + +static const struct parent_map gcc_xo_a_gpll0_map[] = { + { P_XO_A, 0 }, + { P_GPLL0, 1 }, +}; + +static const struct clk_parent_data gcc_xo_a_gpll0_parent_data[] = { + { .index = DT_BI_TCXO_AO }, + { .hw = &gpll0_vote.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll3_gpll6a_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL3, 2 }, + { P_GPLL6_AUX, 3 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll3_gpll6a_parent_data[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0_vote.hw }, + { .hw = &gpll3.clkr.hw }, + { .hw = &gpll6_vote.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll4_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL4, 2 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll4_parent_data[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0_vote.hw }, + { .hw = &gpll4_vote.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll6_map[] = { + { P_XO, 0 }, + { P_GPLL6, 2 }, + { P_GPLL0, 1 }, +}; + +static const struct parent_map gcc_xo_gpll6_out_main_map[] = { + { P_XO, 0 }, + { P_GPLL6_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll6_parent_data[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll6_vote.hw }, + { .hw = &gpll0_vote.hw }, +}; + +static const struct parent_map gcc_xo_gpll0a_map[] = { + { P_XO, 0 }, + { P_GPLL0_AUX, 2 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0a_parent_data[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0_vote.hw }, +}; + +static const struct clk_parent_data gcc_gpll0_parent_data[] = { + { .hw = &gpll0_vote.hw }, +}; + +static const struct parent_map gcc_gpll0_map[] = { + { P_GPLL0, 1 }, +}; + +static const struct parent_map gcc_xo_map[] = { + { P_XO, 0, }, +}; + +static const struct parent_map gcc_xo_dsibyte_map[] = { + { P_XO, 0 }, + { P_DSI0_PHYPLL_BYTE, 1 }, +}; + +static const struct clk_parent_data gcc_xo_dsibyte_parent_data[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0PLL_BYTE }, +}; + +static const struct parent_map gcc_xo_dsiphy_map[] = { + { P_XO, 0 }, + { P_DSI0_PHYPLL_DSI, 1 }, +}; + +static const struct clk_parent_data gcc_xo_dsiphy_parent_data[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0PLL }, +}; + +static const struct parent_map gcc_xo_gpll0_dsiphy_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_DSI0_PHYPLL_DSI, 2 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_dsiphy_parent_data[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0_vote.hw }, + { .index = DT_DSI0PLL }, +}; + +static const struct clk_parent_data gcc_xo_gpll6_out_main_parent_data[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll6_vote.hw }, +}; + +static const struct freq_tbl ftbl_gcc_camss_top_ahb_clk_src[] = { + F(40000000, P_GPLL0, 10, 1, 2), + F(61540000, P_GPLL0, 13, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 camss_top_ahb_clk_src = { + .cmd_rcgr = 0x5a000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_camss_top_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_top_ahb_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_apss_ahb_clk[] = { + F(19200000, P_XO_A, 1, 0, 0), + { } +}; + +static struct clk_rcg2 apss_ahb_clk_src = { + .cmd_rcgr = 0x46000, + .hid_width = 5, + .parent_map = gcc_xo_a_gpll0_map, + .freq_tbl = ftbl_apss_ahb_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "apss_ahb_clk_src", + .parent_data = gcc_xo_a_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_a_gpll0_parent_data), + .ops = &clk_rcg2_ops, + /* + * This clock allows the CPUs to communicate with + * the rest of the SoC. Without it, the brain will + * operate without the rest of the body. + */ + .flags = CLK_IS_CRITICAL, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_csi0_1_2_clk[] = { + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 csi0_clk_src = { + .cmd_rcgr = 0x4e020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_camss_csi0_1_2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi1_clk_src = { + .cmd_rcgr = 0x4f020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_camss_csi0_1_2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi2_clk_src = { + .cmd_rcgr = 0x3c020, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_camss_csi0_1_2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi2_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_oxili_gfx3d_clk[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(228570000, P_GPLL0, 3.5, 0, 0), + F(240000000, P_GPLL6_AUX, 4.5, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(400000000, P_GPLL0, 2, 0, 0), + F(465000000, P_GPLL3, 1, 0, 0), + F(500000000, P_GPLL3, 1, 0, 0), + F(550000000, P_GPLL3, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gfx3d_clk_src = { + .cmd_rcgr = 0x59000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll3_gpll6a_map, + .freq_tbl = ftbl_gcc_oxili_gfx3d_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk_src", + .parent_data = gcc_xo_gpll0_gpll3_gpll6a_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll3_gpll6a_parent_data), + .ops = &clk_rcg2_ops, + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_vfe0_clk[] = { + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(133330000, P_GPLL0, 6, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(177780000, P_GPLL0, 4.5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(308570000, P_GPLL6, 3.5, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + F(360000000, P_GPLL6, 3, 0, 0), + { } +}; + +static struct clk_rcg2 vfe0_clk_src = { + .cmd_rcgr = 0x58000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_map, + .freq_tbl = ftbl_gcc_camss_vfe0_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vfe0_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 vfe1_clk_src = { + .cmd_rcgr = 0x58054, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_map, + .freq_tbl = ftbl_gcc_camss_vfe0_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vfe1_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_parent_data), + .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), + { } +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x0200c, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = { + F(960000, P_XO, 10, 1, 2), + F(4800000, P_XO, 4, 0, 0), + F(9600000, P_XO, 2, 0, 0), + F(16000000, P_GPLL0, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0, 16, 1, 2), + F(50000000, P_GPLL0, 16, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x02024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x03000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x03014, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x04000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x04024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x05000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x05024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = { + F(3686400, P_GPLL0, 1, 72, 15625), + F(7372800, P_GPLL0, 1, 144, 15625), + F(14745600, P_GPLL0, 1, 288, 15625), + F(16000000, P_GPLL0, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0, 1, 3, 100), + F(25000000, P_GPLL0, 16, 1, 2), + F(32000000, P_GPLL0, 1, 1, 25), + F(40000000, P_GPLL0, 1, 1, 20), + F(46400000, P_GPLL0, 1, 29, 500), + F(48000000, P_GPLL0, 1, 3, 50), + F(51200000, P_GPLL0, 1, 8, 125), + F(56000000, P_GPLL0, 1, 7, 100), + F(58982400, P_GPLL0, 1, 1152, 15625), + F(60000000, P_GPLL0, 1, 3, 40), + { } +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x02044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart1_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .cmd_rcgr = 0x03034, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart2_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x0c00c, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup1_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x0c024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup1_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x0d000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup2_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x0d014, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup2_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x0f000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup3_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x0f024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup3_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x18000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup4_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x18024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup4_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart1_apps_clk_src = { + .cmd_rcgr = 0x0c044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart1_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart2_apps_clk_src = { + .cmd_rcgr = 0x0d034, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart2_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_cci_clk[] = { + F(19200000, P_XO, 1, 0, 0), + F(37500000, P_GPLL0_AUX, 1, 3, 64), + { } +}; + +static struct clk_rcg2 cci_clk_src = { + .cmd_rcgr = 0x51000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0a_map, + .freq_tbl = ftbl_gcc_camss_cci_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cci_clk_src", + .parent_data = gcc_xo_gpll0a_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_camss_gp0_1_clk_src[] = { + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 camss_gp0_clk_src = { + .cmd_rcgr = 0x54000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_gpll0_map, + .freq_tbl = ftbl_camss_gp0_1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_gp0_clk_src", + .parent_data = gcc_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 camss_gp1_clk_src = { + .cmd_rcgr = 0x55000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_gpll0_map, + .freq_tbl = ftbl_camss_gp0_1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_gp1_clk_src", + .parent_data = gcc_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_jpeg0_clk[] = { + F(133330000, P_GPLL0, 6, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 jpeg0_clk_src = { + .cmd_rcgr = 0x57000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_camss_jpeg0_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "jpeg0_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_mclk0_1_2_clk[] = { + F(6150000, P_GPLL0, 1, 1, 130), + F(8000000, P_GPLL0, 1, 1, 100), + F(24000000, P_GPLL6, 1, 1, 45), + F(66670000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 mclk0_clk_src = { + .cmd_rcgr = 0x52000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_map, + .freq_tbl = ftbl_gcc_camss_mclk0_1_2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk0_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mclk1_clk_src = { + .cmd_rcgr = 0x53000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_map, + .freq_tbl = ftbl_gcc_camss_mclk0_1_2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk1_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mclk2_clk_src = { + .cmd_rcgr = 0x5c000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_map, + .freq_tbl = ftbl_gcc_camss_mclk0_1_2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk2_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_csi0_1phytimer_clk[] = { + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 csi0phytimer_clk_src = { + .cmd_rcgr = 0x4e000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_camss_csi0_1phytimer_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0phytimer_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi1phytimer_clk_src = { + .cmd_rcgr = 0x4f000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_camss_csi0_1phytimer_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1phytimer_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_cpp_clk[] = { + F(133330000, P_GPLL0, 6, 0, 0), + F(180000000, P_GPLL6, 6, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(308570000, P_GPLL6, 3.5, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cpp_clk_src = { + .cmd_rcgr = 0x58018, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_map, + .freq_tbl = ftbl_gcc_camss_cpp_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cpp_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_crypto_clk[] = { + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + { } +}; + +static struct clk_rcg2 crypto_clk_src = { + .cmd_rcgr = 0x16004, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_crypto_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "crypto_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +/* + * This is a frequency table for "General Purpose" clocks. + * These clocks can be muxed to the SoC pins and may be used by + * external devices. They're often used as PWM source. + * + * Please note that MND divider must be enabled for duty-cycle + * control to be possible. (M != N) Also since D register is configured + * with a value multiplied by 2, and duty cycle is calculated as + * (2 * D) % 2^W + * DutyCycle = ---------------- + * 2 * (N % 2^W) + * (where W = .mnd_width) + * N must be half or less than maximum value for the register. + * Otherwise duty-cycle control would be limited. + * (e.g. for 8-bit NMD N should be less than 128) + */ +static const struct freq_tbl ftbl_gcc_gp1_3_clk[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x08004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_map, + .freq_tbl = ftbl_gcc_gp1_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_data = gcc_xo_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x09004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_map, + .freq_tbl = ftbl_gcc_gp1_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_data = gcc_xo_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0x0a004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_map, + .freq_tbl = ftbl_gcc_gp1_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_data = gcc_xo_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 byte0_clk_src = { + .cmd_rcgr = 0x4d044, + .hid_width = 5, + .parent_map = gcc_xo_dsibyte_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte0_clk_src", + .parent_data = gcc_xo_dsibyte_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_dsibyte_parent_data), + .ops = &clk_byte2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_gcc_mdss_esc_clk[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 esc0_clk_src = { + .cmd_rcgr = 0x4d05c, + .hid_width = 5, + .parent_map = gcc_xo_map, + .freq_tbl = ftbl_gcc_mdss_esc_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc0_clk_src", + .parent_data = gcc_xo_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_mdss_mdp_clk[] = { + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(145450000, P_GPLL0, 5.5, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(177780000, P_GPLL0, 4.5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 mdp_clk_src = { + .cmd_rcgr = 0x4d014, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_dsiphy_map, + .freq_tbl = ftbl_gcc_mdss_mdp_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mdp_clk_src", + .parent_data = gcc_xo_gpll0_dsiphy_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_dsiphy_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 pclk0_clk_src = { + .cmd_rcgr = 0x4d000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_dsiphy_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk0_clk_src", + .parent_data = gcc_xo_dsiphy_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_dsiphy_parent_data), + .ops = &clk_pixel_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_gcc_mdss_vsync_clk[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 vsync_clk_src = { + .cmd_rcgr = 0x4d02c, + .hid_width = 5, + .parent_map = gcc_xo_gpll0a_map, + .freq_tbl = ftbl_gcc_mdss_vsync_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vsync_clk_src", + .parent_data = gcc_xo_gpll0a_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk[] = { + F(64000000, P_GPLL0, 12.5, 0, 0), + { } +}; + +static struct clk_rcg2 pdm2_clk_src = { + .cmd_rcgr = 0x44010, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_pdm2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pdm2_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0, 10, 1, 4), + F(25000000, P_GPLL0, 16, 1, 2), + F(50000000, P_GPLL0, 16, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(177770000, P_GPLL0, 4.5, 0, 0), + F(192000000, P_GPLL4, 6, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(384000000, P_GPLL4, 3, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x42004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll4_map, + .freq_tbl = ftbl_gcc_sdcc1_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll4_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4_parent_data), + .ops = &clk_rcg2_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0, 10, 1, 4), + F(25000000, P_GPLL0, 16, 1, 2), + F(50000000, P_GPLL0, 16, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(177770000, P_GPLL0, 4.5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc2_apps_clk_src = { + .cmd_rcgr = 0x43004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc2_apps_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk[] = { + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x5d000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_out_main_map, + .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_ice_core_clk_src", + .parent_data = gcc_xo_gpll0_out_main_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_out_main_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x5d014, + .clkr = { + .enable_reg = 0x5d014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk", + .parent_hws = (const struct clk_hw*[]){ + &sdcc1_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = { + F(57140000, P_GPLL0, 14, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(133330000, P_GPLL0, 6, 0, 0), + F(177780000, P_GPLL0, 4.5, 0, 0), + { } +}; + +static struct clk_rcg2 usb_hs_system_clk_src = { + .cmd_rcgr = 0x41010, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_usb_hs_system_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hs_system_clk_src", + .parent_data = gcc_xo_gpll0_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb_fs_system_clk[] = { + F(64000000, P_GPLL0_AUX, 12.5, 0, 0), + { } +}; + +static struct clk_rcg2 usb_fs_system_clk_src = { + .cmd_rcgr = 0x3f010, + .hid_width = 5, + .parent_map = gcc_xo_gpll0a_map, + .freq_tbl = ftbl_gcc_usb_fs_system_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_fs_system_clk_src", + .parent_data = gcc_xo_gpll0a_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0a_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb_fs_ic_clk[] = { + F(60000000, P_GPLL6_OUT_MAIN, 9, 1, 2), + { } +}; + +static struct clk_rcg2 usb_fs_ic_clk_src = { + .cmd_rcgr = 0x3f034, + .hid_width = 5, + .mnd_width = 8, + .parent_map = gcc_xo_gpll6_out_main_map, + .freq_tbl = ftbl_gcc_usb_fs_ic_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_fs_ic_clk_src", + .parent_data = gcc_xo_gpll6_out_main_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll6_out_main_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_venus0_vcodec0_clk[] = { + F(133330000, P_GPLL0, 6, 0, 0), + F(180000000, P_GPLL6, 6, 0, 0), + F(228570000, P_GPLL0, 3.5, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(308570000, P_GPLL6, 3.5, 0, 0), + { } +}; + +static struct clk_rcg2 vcodec0_clk_src = { + .cmd_rcgr = 0x4C000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_map, + .freq_tbl = ftbl_gcc_venus0_vcodec0_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vcodec0_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_parent_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x01008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x02008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x02008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_i2c_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_qup1_i2c_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { + .halt_reg = 0x02004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x02004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_spi_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_qup1_spi_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { + .halt_reg = 0x03010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x03010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_i2c_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_qup2_i2c_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { + .halt_reg = 0x0300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_spi_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_qup2_spi_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = { + .halt_reg = 0x04020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x04020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_i2c_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_qup3_i2c_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = { + .halt_reg = 0x0401c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0401c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_spi_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_qup3_spi_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = { + .halt_reg = 0x05020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x05020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_i2c_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_qup4_i2c_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = { + .halt_reg = 0x0501c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0501c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_spi_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_qup4_spi_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart1_apps_clk = { + .halt_reg = 0x0203c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0203c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart1_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_uart1_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart2_apps_clk = { + .halt_reg = 0x0302c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0302c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart2_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_uart2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_ahb_clk = { + .halt_reg = 0x0b008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(20), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = { + .halt_reg = 0x0c008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0c008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup1_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp2_qup1_i2c_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = { + .halt_reg = 0x0c004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup1_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp2_qup1_spi_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart1_apps_clk = { + .halt_reg = 0x0c03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0c03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart1_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp2_uart1_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = { + .halt_reg = 0x0d010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0d010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup2_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp2_qup2_i2c_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = { + .halt_reg = 0x0d00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0d00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup2_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp2_qup2_spi_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart2_apps_clk = { + .halt_reg = 0x0d02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0d02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart2_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp2_uart2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = { + .halt_reg = 0x0f020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0f020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup3_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp2_qup3_i2c_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = { + .halt_reg = 0x0f01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x0f01c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup3_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp2_qup3_spi_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = { + .halt_reg = 0x18020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x18020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup4_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp2_qup4_i2c_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = { + .halt_reg = 0x1801c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1801c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup4_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp2_qup4_spi_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x1300c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cci_ahb_clk = { + .halt_reg = 0x5101c, + .clkr = { + .enable_reg = 0x5101c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cci_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cci_clk = { + .halt_reg = 0x51018, + .clkr = { + .enable_reg = 0x51018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cci_clk", + .parent_hws = (const struct clk_hw*[]){ + &cci_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0_ahb_clk = { + .halt_reg = 0x4e040, + .clkr = { + .enable_reg = 0x4e040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0_clk = { + .halt_reg = 0x4e03c, + .clkr = { + .enable_reg = 0x4e03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0phy_clk = { + .halt_reg = 0x4e048, + .clkr = { + .enable_reg = 0x4e048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0phy_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0pix_clk = { + .halt_reg = 0x4e058, + .clkr = { + .enable_reg = 0x4e058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0pix_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0rdi_clk = { + .halt_reg = 0x4e050, + .clkr = { + .enable_reg = 0x4e050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0rdi_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1_ahb_clk = { + .halt_reg = 0x4f040, + .clkr = { + .enable_reg = 0x4f040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1_clk = { + .halt_reg = 0x4f03c, + .clkr = { + .enable_reg = 0x4f03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1phy_clk = { + .halt_reg = 0x4f048, + .clkr = { + .enable_reg = 0x4f048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1phy_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1pix_clk = { + .halt_reg = 0x4f058, + .clkr = { + .enable_reg = 0x4f058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1pix_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1rdi_clk = { + .halt_reg = 0x4f050, + .clkr = { + .enable_reg = 0x4f050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1rdi_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi2_ahb_clk = { + .halt_reg = 0x3c040, + .clkr = { + .enable_reg = 0x3c040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi2_clk = { + .halt_reg = 0x3c03c, + .clkr = { + .enable_reg = 0x3c03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi2phy_clk = { + .halt_reg = 0x3c048, + .clkr = { + .enable_reg = 0x3c048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2phy_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi2pix_clk = { + .halt_reg = 0x3c058, + .clkr = { + .enable_reg = 0x3c058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2pix_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi2rdi_clk = { + .halt_reg = 0x3c050, + .clkr = { + .enable_reg = 0x3c050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2rdi_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi2_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 = 0x5c018, + .clkr = { + .enable_reg = 0x5c018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_mclk2_clk", + .parent_hws = (const struct clk_hw *[]){ + &mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi_vfe0_clk = { + .halt_reg = 0x58050, + .clkr = { + .enable_reg = 0x58050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi_vfe0_clk", + .parent_hws = (const struct clk_hw*[]){ + &vfe0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_gp0_clk = { + .halt_reg = 0x54018, + .clkr = { + .enable_reg = 0x54018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_gp0_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_gp0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_gp1_clk = { + .halt_reg = 0x55018, + .clkr = { + .enable_reg = 0x55018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_gp1_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_gp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_ispif_ahb_clk = { + .halt_reg = 0x50004, + .clkr = { + .enable_reg = 0x50004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_ispif_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_jpeg0_clk = { + .halt_reg = 0x57020, + .clkr = { + .enable_reg = 0x57020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_jpeg0_clk", + .parent_hws = (const struct clk_hw*[]){ + &jpeg0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_jpeg_ahb_clk = { + .halt_reg = 0x57024, + .clkr = { + .enable_reg = 0x57024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_jpeg_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_jpeg_axi_clk = { + .halt_reg = 0x57028, + .clkr = { + .enable_reg = 0x57028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_jpeg_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk0_clk = { + .halt_reg = 0x52018, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_mclk0_clk", + .parent_hws = (const struct clk_hw*[]){ + &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 = 0x53018, + .clkr = { + .enable_reg = 0x53018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_mclk1_clk", + .parent_hws = (const struct clk_hw*[]){ + &mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_micro_ahb_clk = { + .halt_reg = 0x5600c, + .clkr = { + .enable_reg = 0x5600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_micro_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_top_ahb_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 = 0x4e01c, + .clkr = { + .enable_reg = 0x4e01c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0phytimer_clk", + .parent_hws = (const struct clk_hw*[]){ + &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 = 0x4f01c, + .clkr = { + .enable_reg = 0x4f01c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1phytimer_clk", + .parent_hws = (const struct clk_hw*[]){ + &csi1phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_ahb_clk = { + .halt_reg = 0x56004, + .clkr = { + .enable_reg = 0x56004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_top_ahb_clk = { + .halt_reg = 0x5a014, + .clkr = { + .enable_reg = 0x5a014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_top_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe0_ahb_clk = { + .halt_reg = 0x58044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x58044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) { + .name = "gcc_camss_vfe0_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + } + } +}; + +static struct clk_branch gcc_camss_vfe0_axi_clk = { + .halt_reg = 0x58048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x58048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) { + .name = "gcc_camss_vfe0_axi_clk", + .ops = &clk_branch2_ops, + } + } +}; + +static struct clk_branch gcc_camss_cpp_ahb_clk = { + .halt_reg = 0x58040, + .clkr = { + .enable_reg = 0x58040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cpp_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cpp_clk = { + .halt_reg = 0x5803c, + .clkr = { + .enable_reg = 0x5803c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cpp_clk", + .parent_hws = (const struct clk_hw*[]){ + &cpp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe0_clk = { + .halt_reg = 0x58038, + .clkr = { + .enable_reg = 0x58038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe0_clk", + .parent_hws = (const struct clk_hw*[]){ + &vfe0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cpp_axi_clk = { + .halt_reg = 0x58064, + .clkr = { + .enable_reg = 0x58064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cpp_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_ahb_clk = { + .halt_reg = 0x16024, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_axi_clk = { + .halt_reg = 0x16020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_clk = { + .halt_reg = 0x1601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_clk", + .parent_hws = (const struct clk_hw*[]){ + &crypto_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_oxili_gmem_clk = { + .halt_reg = 0x59024, + .clkr = { + .enable_reg = 0x59024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_oxili_gmem_clk", + .parent_hws = (const struct clk_hw*[]){ + &gfx3d_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 = 0x08000, + .clkr = { + .enable_reg = 0x08000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_hws = (const struct clk_hw*[]){ + &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 = 0x09000, + .clkr = { + .enable_reg = 0x09000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_hws = (const struct clk_hw*[]){ + &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 = 0x0a000, + .clkr = { + .enable_reg = 0x0a000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_hws = (const struct clk_hw*[]){ + &gp3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_ahb_clk = { + .halt_reg = 0x4d07c, + .clkr = { + .enable_reg = 0x4d07c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_axi_clk = { + .halt_reg = 0x4d080, + .clkr = { + .enable_reg = 0x4d080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_byte0_clk = { + .halt_reg = 0x4d094, + .clkr = { + .enable_reg = 0x4d094, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_byte0_clk", + .parent_hws = (const struct clk_hw*[]){ + &byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_esc0_clk = { + .halt_reg = 0x4d098, + .clkr = { + .enable_reg = 0x4d098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_esc0_clk", + .parent_hws = (const struct clk_hw*[]){ + &esc0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_mdp_clk = { + .halt_reg = 0x4D088, + .clkr = { + .enable_reg = 0x4D088, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_mdp_clk", + .parent_hws = (const struct clk_hw*[]){ + &mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_pclk0_clk = { + .halt_reg = 0x4d084, + .clkr = { + .enable_reg = 0x4d084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_pclk0_clk", + .parent_hws = (const struct clk_hw*[]){ + &pclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_vsync_clk = { + .halt_reg = 0x4d090, + .clkr = { + .enable_reg = 0x4d090, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_vsync_clk", + .parent_hws = (const struct clk_hw*[]){ + &vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_cfg_ahb_clk = { + .halt_reg = 0x49000, + .clkr = { + .enable_reg = 0x49000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .halt_reg = 0x49004, + .clkr = { + .enable_reg = 0x49004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_bimc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_oxili_ahb_clk = { + .halt_reg = 0x59028, + .clkr = { + .enable_reg = 0x59028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_oxili_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_oxili_gfx3d_clk = { + .halt_reg = 0x59020, + .clkr = { + .enable_reg = 0x59020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_oxili_gfx3d_clk", + .parent_hws = (const struct clk_hw*[]){ + &gfx3d_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 = 0x4400c, + .clkr = { + .enable_reg = 0x4400c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_hws = (const struct clk_hw*[]){ + &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 = 0x44004, + .clkr = { + .enable_reg = 0x44004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x13004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x4201c, + .clkr = { + .enable_reg = 0x4201c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x42018, + .clkr = { + .enable_reg = 0x42018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &sdcc1_apps_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 = 0x4301c, + .clkr = { + .enable_reg = 0x4301c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x43018, + .clkr = { + .enable_reg = 0x43018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &sdcc2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_apss_tcu_clk = { + .halt_reg = 0x12018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_tcu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gfx_tcu_clk = { + .halt_reg = 0x12020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gfx_tcu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gfx_tbu_clk = { + .halt_reg = 0x12010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gfx_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdp_tbu_clk = { + .halt_reg = 0x1201c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdp_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_venus_tbu_clk = { + .halt_reg = 0x12014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_venus_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi_vfe1_clk = { + .halt_reg = 0x58074, + .clkr = { + .enable_reg = 0x58074, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi_vfe1_clk", + .parent_hws = (const struct clk_hw *[]){ + &vfe1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe1_clk = { + .halt_reg = 0x5805c, + .clkr = { + .enable_reg = 0x5805c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe1_clk", + .parent_hws = (const struct clk_hw *[]){ + &vfe1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe1_ahb_clk = { + .halt_reg = 0x58060, + .clkr = { + .enable_reg = 0x58060, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe1_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe1_axi_clk = { + .halt_reg = 0x58068, + .clkr = { + .enable_reg = 0x58068, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe1_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_vfe_tbu_clk = { + .halt_reg = 0x1203c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gcc_vfe_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_jpeg_tbu_clk = { + .halt_reg = 0x12034, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_jpeg_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_smmu_cfg_clk = { + .halt_reg = 0x12038, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "gcc_smmu_cfg_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gtcu_ahb_clk = { + .halt_reg = 0x12044, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gtcu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpp_tbu_clk = { + .halt_reg = 0x12040, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpp_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_vfe1_tbu_clk = { + .halt_reg = 0x12090, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(17), + .hw.init = &(struct clk_init_data){ + .name = "gcc_vfe1_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ipa_tbu_clk = { + .halt_reg = 0x120a0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(16), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ipa_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_gfx_clk = { + .halt_reg = 0x59034, + .clkr = { + .enable_reg = 0x59034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_gpu_clk = { + .halt_reg = 0x59030, + .clkr = { + .enable_reg = 0x59030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_gpu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2a_phy_sleep_clk = { + .halt_reg = 0x4102c, + .clkr = { + .enable_reg = 0x4102c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2a_phy_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_fs_ahb_clk = { + .halt_reg = 0x3f008, + .clkr = { + .enable_reg = 0x3f008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_fs_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_phy_cfg_ahb_clk = { + .halt_reg = 0x41030, + .clkr = { + .enable_reg = 0x41030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_phy_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_fs_ic_clk = { + .halt_reg = 0x3f030, + .clkr = { + .enable_reg = 0x3f030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_fs_ic_clk", + .parent_hws = (const struct clk_hw*[]){ + &usb_fs_ic_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_fs_system_clk = { + .halt_reg = 0x3f004, + .clkr = { + .enable_reg = 0x3f004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_fs_system_clk", + .parent_hws = (const struct clk_hw*[]){ + &usb_fs_system_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_ahb_clk = { + .halt_reg = 0x41008, + .clkr = { + .enable_reg = 0x41008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_system_clk = { + .halt_reg = 0x41004, + .clkr = { + .enable_reg = 0x41004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_system_clk", + .parent_hws = (const struct clk_hw*[]){ + &usb_hs_system_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_venus0_ahb_clk = { + .halt_reg = 0x4c020, + .clkr = { + .enable_reg = 0x4c020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_venus0_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_venus0_axi_clk = { + .halt_reg = 0x4c024, + .clkr = { + .enable_reg = 0x4c024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_venus0_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_venus0_vcodec0_clk = { + .halt_reg = 0x4c01c, + .clkr = { + .enable_reg = 0x4c01c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_venus0_vcodec0_clk", + .parent_hws = (const struct clk_hw*[]){ + &vcodec0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_venus0_core0_vcodec0_clk = { + .halt_reg = 0x4c02c, + .clkr = { + .enable_reg = 0x4c02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_venus0_core0_vcodec0_clk", + .parent_hws = (const struct clk_hw*[]){ + &vcodec0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_venus0_core1_vcodec0_clk = { + .halt_reg = 0x4c034, + .clkr = { + .enable_reg = 0x4c034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_venus0_core1_vcodec0_clk", + .parent_hws = (const struct clk_hw*[]){ + &vcodec0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_oxili_timer_clk = { + .halt_reg = 0x59040, + .clkr = { + .enable_reg = 0x59040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_oxili_timer_clk", + .parent_data = gcc_xo_parent_data, + .num_parents = ARRAY_SIZE(gcc_xo_parent_data), + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc venus_gdsc = { + .gdscr = 0x4c018, + .cxcs = (unsigned int []){ 0x4c024, 0x4c01c }, + .cxc_count = 2, + .pd = { + .name = "venus_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc mdss_gdsc = { + .gdscr = 0x4d078, + .cxcs = (unsigned int []){ 0x4d080, 0x4d088 }, + .cxc_count = 2, + .pd = { + .name = "mdss_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc jpeg_gdsc = { + .gdscr = 0x5701c, + .cxcs = (unsigned int []){ 0x57020, 0x57028 }, + .cxc_count = 2, + .pd = { + .name = "jpeg_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc vfe0_gdsc = { + .gdscr = 0x58034, + .cxcs = (unsigned int []){ 0x58038, 0x58048, 0x5600c, 0x58050 }, + .cxc_count = 4, + .pd = { + .name = "vfe0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc vfe1_gdsc = { + .gdscr = 0x5806c, + .cxcs = (unsigned int []){ 0x5805c, 0x58068, 0x5600c, 0x58074 }, + .cxc_count = 4, + .pd = { + .name = "vfe1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc cpp_gdsc = { + .gdscr = 0x58078, + .cxcs = (unsigned int []){ 0x5803c, 0x58064 }, + .cxc_count = 2, + .pd = { + .name = "cpp_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc oxili_gx_gdsc = { + .gdscr = 0x5901c, + .cxcs = (unsigned int []){ 0x59000, 0x59024 }, + .cxc_count = 2, + .pd = { + .name = "oxili_gx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc venus_core0_gdsc = { + .gdscr = 0x4c028, + .cxcs = (unsigned int []){ 0x4c02c }, + .cxc_count = 1, + .pd = { + .name = "venus_core0_gdsc", + }, + .flags = HW_CTRL_TRIGGER, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc venus_core1_gdsc = { + .gdscr = 0x4c030, + .cxcs = (unsigned int []){ 0x4c034 }, + .cxc_count = 1, + .pd = { + .name = "venus_core1_gdsc", + }, + .flags = HW_CTRL_TRIGGER, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct clk_regmap *gcc_msm8952_clocks[] = { + [GPLL0] = &gpll0.clkr, + [GPLL0_VOTE] = &gpll0_vote, + [CAMSS_TOP_AHB_CLK_SRC] = &camss_top_ahb_clk_src.clkr, + [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr, + [CSI0_CLK_SRC] = &csi0_clk_src.clkr, + [CSI1_CLK_SRC] = &csi1_clk_src.clkr, + [CSI2_CLK_SRC] = &csi2_clk_src.clkr, + [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr, + [VFE0_CLK_SRC] = &vfe0_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, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [CCI_CLK_SRC] = &cci_clk_src.clkr, + [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr, + [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr, + [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr, + [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr, + [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr, + [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr, + [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr, + [CPP_CLK_SRC] = &cpp_clk_src.clkr, + [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [BYTE0_CLK_SRC] = &byte0_clk_src.clkr, + [ESC0_CLK_SRC] = &esc0_clk_src.clkr, + [MDP_CLK_SRC] = &mdp_clk_src.clkr, + [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr, + [VSYNC_CLK_SRC] = &vsync_clk_src.clkr, + [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, + [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr, + [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr, + [VCODEC0_CLK_SRC] = &vcodec0_clk_src.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMSS_CCI_AHB_CLK] = &gcc_camss_cci_ahb_clk.clkr, + [GCC_CAMSS_CCI_CLK] = &gcc_camss_cci_clk.clkr, + [GCC_CAMSS_CSI0_AHB_CLK] = &gcc_camss_csi0_ahb_clk.clkr, + [GCC_CAMSS_CSI0_CLK] = &gcc_camss_csi0_clk.clkr, + [GCC_CAMSS_CSI0PHY_CLK] = &gcc_camss_csi0phy_clk.clkr, + [GCC_CAMSS_CSI0PIX_CLK] = &gcc_camss_csi0pix_clk.clkr, + [GCC_CAMSS_CSI0RDI_CLK] = &gcc_camss_csi0rdi_clk.clkr, + [GCC_CAMSS_CSI1_AHB_CLK] = &gcc_camss_csi1_ahb_clk.clkr, + [GCC_CAMSS_CSI1_CLK] = &gcc_camss_csi1_clk.clkr, + [GCC_CAMSS_CSI1PHY_CLK] = &gcc_camss_csi1phy_clk.clkr, + [GCC_CAMSS_CSI1PIX_CLK] = &gcc_camss_csi1pix_clk.clkr, + [GCC_CAMSS_CSI1RDI_CLK] = &gcc_camss_csi1rdi_clk.clkr, + [GCC_CAMSS_CSI2_AHB_CLK] = &gcc_camss_csi2_ahb_clk.clkr, + [GCC_CAMSS_CSI2_CLK] = &gcc_camss_csi2_clk.clkr, + [GCC_CAMSS_CSI2PHY_CLK] = &gcc_camss_csi2phy_clk.clkr, + [GCC_CAMSS_CSI2PIX_CLK] = &gcc_camss_csi2pix_clk.clkr, + [GCC_CAMSS_CSI2RDI_CLK] = &gcc_camss_csi2rdi_clk.clkr, + [GCC_CAMSS_CSI_VFE0_CLK] = &gcc_camss_csi_vfe0_clk.clkr, + [GCC_CAMSS_GP0_CLK] = &gcc_camss_gp0_clk.clkr, + [GCC_CAMSS_GP1_CLK] = &gcc_camss_gp1_clk.clkr, + [GCC_CAMSS_ISPIF_AHB_CLK] = &gcc_camss_ispif_ahb_clk.clkr, + [GCC_CAMSS_JPEG0_CLK] = &gcc_camss_jpeg0_clk.clkr, + [GCC_CAMSS_JPEG_AHB_CLK] = &gcc_camss_jpeg_ahb_clk.clkr, + [GCC_CAMSS_JPEG_AXI_CLK] = &gcc_camss_jpeg_axi_clk.clkr, + [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr, + [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr, + [GCC_CAMSS_MICRO_AHB_CLK] = &gcc_camss_micro_ahb_clk.clkr, + [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr, + [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr, + [GCC_CAMSS_AHB_CLK] = &gcc_camss_ahb_clk.clkr, + [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr, + [GCC_CAMSS_VFE0_AHB_CLK] = &gcc_camss_vfe0_ahb_clk.clkr, + [GCC_CAMSS_VFE0_AXI_CLK] = &gcc_camss_vfe0_axi_clk.clkr, + [GCC_CAMSS_CPP_AHB_CLK] = &gcc_camss_cpp_ahb_clk.clkr, + [GCC_CAMSS_CPP_CLK] = &gcc_camss_cpp_clk.clkr, + [GCC_CAMSS_VFE0_CLK] = &gcc_camss_vfe0_clk.clkr, + [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr, + [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr, + [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr, + [GCC_OXILI_GMEM_CLK] = &gcc_oxili_gmem_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_MDSS_AHB_CLK] = &gcc_mdss_ahb_clk.clkr, + [GCC_MDSS_AXI_CLK] = &gcc_mdss_axi_clk.clkr, + [GCC_MDSS_BYTE0_CLK] = &gcc_mdss_byte0_clk.clkr, + [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr, + [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr, + [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr, + [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr, + [GCC_OXILI_GFX3D_CLK] = &gcc_oxili_gfx3d_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_GTCU_AHB_CLK] = &gcc_gtcu_ahb_clk.clkr, + [GCC_JPEG_TBU_CLK] = &gcc_jpeg_tbu_clk.clkr, + [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_clk.clkr, + [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr, + [GCC_VENUS_TBU_CLK] = &gcc_venus_tbu_clk.clkr, + [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr, + [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr, + [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr, + [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr, + [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr, + [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr, + [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr, + [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr, + [GCC_GFX_TCU_CLK] = &gcc_gfx_tcu_clk.clkr, + [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, + [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [GPLL3] = &gpll3.clkr, + [GPLL3_EARLY] = &gpll3_early.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL4_VOTE] = &gpll4_vote, + [GPLL6] = &gpll6.clkr, + [GPLL6_VOTE] = &gpll6_vote, + [GCC_GFX_TBU_CLK] = &gcc_gfx_tbu_clk.clkr, + [GCC_CPP_TBU_CLK] = &gcc_cpp_tbu_clk.clkr, + [USB_FS_SYSTEM_CLK_SRC] = &usb_fs_system_clk_src.clkr, + [USB_FS_IC_CLK_SRC] = &usb_fs_ic_clk_src.clkr, + [GCC_USB_FS_AHB_CLK] = &gcc_usb_fs_ahb_clk.clkr, + [GCC_USB_HS_PHY_CFG_AHB_CLK] = &gcc_usb_hs_phy_cfg_ahb_clk.clkr, + [GCC_USB_FS_IC_CLK] = &gcc_usb_fs_ic_clk.clkr, + [GCC_USB_FS_SYSTEM_CLK] = &gcc_usb_fs_system_clk.clkr, + [GCC_VENUS0_CORE0_VCODEC0_CLK] = &gcc_venus0_core0_vcodec0_clk.clkr, + [GCC_VENUS0_CORE1_VCODEC0_CLK] = &gcc_venus0_core1_vcodec0_clk.clkr, + [GCC_OXILI_TIMER_CLK] = &gcc_oxili_timer_clk.clkr, + [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr, + [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr, + [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr, + [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr, + [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr, + [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr, + [BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr, + [BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr, + [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr, + [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr, + [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr, + [GCC_BLSP2_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr, + [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr, + [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr, + [GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr, + [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr, + [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr, + [VFE1_CLK_SRC] = &vfe1_clk_src.clkr, + [GCC_CAMSS_VFE1_CLK] = &gcc_camss_vfe1_clk.clkr, + [GCC_CAMSS_VFE1_AHB_CLK] = &gcc_camss_vfe1_ahb_clk.clkr, + [GCC_CAMSS_VFE1_AXI_CLK] = &gcc_camss_vfe1_axi_clk.clkr, + [GCC_CAMSS_CSI_VFE1_CLK] = &gcc_camss_csi_vfe1_clk.clkr, + [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr, + [GCC_CAMSS_MCLK2_CLK] = &gcc_camss_mclk2_clk.clkr, + [GCC_VFE1_TBU_CLK] = &gcc_vfe1_tbu_clk.clkr, + [GCC_IPA_TBU_CLK] = &gcc_ipa_tbu_clk.clkr, + [GCC_CAMSS_CPP_AXI_CLK] = &gcc_camss_cpp_axi_clk.clkr, +}; + +static struct gdsc *gcc_msm8952_gdscs[] = { + [CPP_GDSC] = &cpp_gdsc, + [VENUS_GDSC] = &venus_gdsc, + [MDSS_GDSC] = &mdss_gdsc, + [JPEG_GDSC] = &jpeg_gdsc, + [VFE0_GDSC] = &vfe0_gdsc, + [VFE1_GDSC] = &vfe1_gdsc, + [OXILI_GX_GDSC] = &oxili_gx_gdsc, + [VENUS_CORE0_GDSC] = &venus_core0_gdsc, + [VENUS_CORE1_GDSC] = &venus_core1_gdsc, +}; + +static const struct qcom_reset_map gcc_msm8952_resets[] = { + [GCC_CRYPTO_BCR] = { 0x16000 }, + [GCC_USB_FS_BCR] = { 0x3f000 }, + [GCC_USB_HS_BCR] = { 0x41000 }, + [GCC_QUSB2_PHY_BCR] = { 0x4103c }, + [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, + [GCC_SDCC1_BCR] = { 0x42000 }, + [GCC_SDCC2_BCR] = { 0x43000 }, + [GCC_MDSS_BCR] = { 0x4d074 }, + [GCC_CAMSS_MICRO_BCR] = { 0x56008 }, + [GCC_MSS_BCR] = { 0x71000 }, +}; + +static const struct regmap_config gcc_msm8952_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x80000, + .fast_io = true, +}; + +static struct clk_alpha_pll *gcc_msm8952_alpha_plls[] = { + &gpll3_early, +}; + +static void clk_msm8952_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Set Sleep and Wakeup cycles to 0 for GMEM clock */ + regmap_update_bits(regmap, gcc_oxili_gmem_clk.clkr.enable_reg, 0xff0, 0); + + /* Disable GMEM HW Dynamic, Without this write, GMEM can't get enabled */ + regmap_write(regmap, 0x7E004, 0x1); +} + +static const struct qcom_cc_driver_data gcc_msm8952_driver_data = { + .alpha_plls = gcc_msm8952_alpha_plls, + .num_alpha_plls = ARRAY_SIZE(gcc_msm8952_alpha_plls), + .clk_regs_configure = clk_msm8952_regs_configure, +}; + +static const struct qcom_cc_desc gcc_msm8952_desc = { + .config = &gcc_msm8952_regmap_config, + .clks = gcc_msm8952_clocks, + .num_clks = ARRAY_SIZE(gcc_msm8952_clocks), + .resets = gcc_msm8952_resets, + .num_resets = ARRAY_SIZE(gcc_msm8952_resets), + .gdscs = gcc_msm8952_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_msm8952_gdscs), + .use_rpm = true, + .driver_data = &gcc_msm8952_driver_data +}; + +static const struct of_device_id gcc_msm8952_match_table[] = { + { .compatible = "qcom,gcc-msm8952" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_msm8952_match_table); + +static int gcc_msm8952_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gcc_msm8952_desc); +} + +static struct platform_driver gcc_msm8952_driver = { + .probe = gcc_msm8952_probe, + .driver = { + .name = "gcc-msm8952", + .of_match_table = gcc_msm8952_match_table, + }, +}; + +static int __init gcc_msm8952_init(void) +{ + return platform_driver_register(&gcc_msm8952_driver); +} +core_initcall(gcc_msm8952_init); + +static void __exit gcc_msm8952_exit(void) +{ + platform_driver_unregister(&gcc_msm8952_driver); +} +module_exit(gcc_msm8952_exit); + +MODULE_DESCRIPTION("Qualcomm GCC MSM8952 Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-nord.c b/drivers/clk/qcom/gcc-nord.c index 5c9d25f53a6d..4f87e06b33ab 100644 --- a/drivers/clk/qcom/gcc-nord.c +++ b/drivers/clk/qcom/gcc-nord.c @@ -1862,17 +1862,7 @@ static struct platform_driver gcc_nord_driver = { }, }; -static int __init gcc_nord_init(void) -{ - return platform_driver_register(&gcc_nord_driver); -} -subsys_initcall(gcc_nord_init); - -static void __exit gcc_nord_exit(void) -{ - platform_driver_unregister(&gcc_nord_driver); -} -module_exit(gcc_nord_exit); +subsys_platform_driver(gcc_nord_driver); MODULE_DESCRIPTION("QTI GCC NORD Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-qcm2290.c b/drivers/clk/qcom/gcc-qcm2290.c index 2532c0b36bc5..cf7d05558be9 100644 --- a/drivers/clk/qcom/gcc-qcm2290.c +++ b/drivers/clk/qcom/gcc-qcm2290.c @@ -2923,17 +2923,7 @@ static struct platform_driver gcc_qcm2290_driver = { }, }; -static int __init gcc_qcm2290_init(void) -{ - return platform_driver_register(&gcc_qcm2290_driver); -} -subsys_initcall(gcc_qcm2290_init); - -static void __exit gcc_qcm2290_exit(void) -{ - platform_driver_unregister(&gcc_qcm2290_driver); -} -module_exit(gcc_qcm2290_exit); +subsys_platform_driver(gcc_qcm2290_driver); MODULE_DESCRIPTION("QTI GCC QCM2290 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-qcs615.c b/drivers/clk/qcom/gcc-qcs615.c index 57f8c80c6f32..e096af7d82bf 100644 --- a/drivers/clk/qcom/gcc-qcs615.c +++ b/drivers/clk/qcom/gcc-qcs615.c @@ -2958,7 +2958,34 @@ static const struct regmap_config gcc_qcs615_regmap_config = { .fast_io = true, }; +static const u32 gcc_qcs615_critical_cbcrs[] = { + 0xb008, /* GCC_CAMERA_AHB_CLK */ + 0xb044, /* GCC_CAMERA_XO_CLK */ + 0xb00c, /* GCC_DISP_AHB_CLK */ + 0xb048, /* GCC_DISP_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0xb004, /* GCC_VIDEO_AHB_CLK */ + 0xb040, /* GCC_VIDEO_XO_CLK */ + 0x48004, /* GCC_CPUSS_GNOC_CLK */ +}; + +static void gcc_qcs615_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Disable the GPLL0 active input to MM blocks and GPU via MISC registers. */ + regmap_update_bits(regmap, 0x0b084, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x9b000, BIT(0), BIT(0)); +} + +static const struct qcom_cc_driver_data gcc_qcs615_driver_data = { + .clk_cbcrs = gcc_qcs615_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_qcs615_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_qcs615_regs_configure, +}; + static const struct qcom_cc_desc gcc_qcs615_desc = { + .driver_data = &gcc_qcs615_driver_data, .config = &gcc_qcs615_regmap_config, .clk_hws = gcc_qcs615_hws, .num_clk_hws = ARRAY_SIZE(gcc_qcs615_hws), @@ -2978,35 +3005,7 @@ MODULE_DEVICE_TABLE(of, gcc_qcs615_match_table); static int gcc_qcs615_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_qcs615_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - /* - * Disable the GPLL0 active input to MM blocks and GPU - * via MISC registers. - */ - regmap_update_bits(regmap, 0x0b084, BIT(0), BIT(0)); - regmap_update_bits(regmap, 0x9b000, BIT(0), BIT(0)); - - /* Keep some clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0xb008); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0xb044); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0xb00c); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0xb048); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0xb004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0xb040); /* GCC_VIDEO_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x480040); /* GCC_CPUSS_GNOC_CLK */ - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - return qcom_cc_really_probe(&pdev->dev, &gcc_qcs615_desc, regmap); + return qcom_cc_probe(pdev, &gcc_qcs615_desc); } static struct platform_driver gcc_qcs615_driver = { @@ -3017,17 +3016,7 @@ static struct platform_driver gcc_qcs615_driver = { }, }; -static int __init gcc_qcs615_init(void) -{ - return platform_driver_register(&gcc_qcs615_driver); -} -subsys_initcall(gcc_qcs615_init); - -static void __exit gcc_qcs615_exit(void) -{ - platform_driver_unregister(&gcc_qcs615_driver); -} -module_exit(gcc_qcs615_exit); +subsys_platform_driver(gcc_qcs615_driver); MODULE_DESCRIPTION("QTI GCC QCS615 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-qcs8300.c b/drivers/clk/qcom/gcc-qcs8300.c index 31fd870b10f7..916617a001c8 100644 --- a/drivers/clk/qcom/gcc-qcs8300.c +++ b/drivers/clk/qcom/gcc-qcs8300.c @@ -42,6 +42,7 @@ enum { P_GCC_GPLL0_OUT_MAIN, P_GCC_GPLL1_OUT_MAIN, P_GCC_GPLL4_OUT_MAIN, + P_GCC_GPLL5_OUT_MAIN, P_GCC_GPLL7_OUT_MAIN, P_GCC_GPLL9_OUT_MAIN, P_PCIE_0_PIPE_CLK, @@ -128,6 +129,23 @@ static struct clk_alpha_pll gcc_gpll4 = { }, }; +static struct clk_alpha_pll gcc_gpll5 = { + .offset = 0x5000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], + .clkr = { + .enable_reg = 0x4b028, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll5", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_lucid_evo_ops, + }, + }, +}; + static struct clk_alpha_pll gcc_gpll7 = { .offset = 0x7000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], @@ -364,6 +382,22 @@ static const struct clk_parent_data gcc_parent_data_18[] = { { .index = DT_BI_TCXO }, }; +static const struct parent_map gcc_parent_map_19[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL7_OUT_MAIN, 2 }, + { P_GCC_GPLL5_OUT_MAIN, 3 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_19[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll7.clkr.hw }, + { .hw = &gcc_gpll5.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + static struct clk_regmap_mux gcc_pcie_0_phy_aux_clk_src = { .reg = 0xa9074, .shift = 0, @@ -1094,6 +1128,25 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { }, }; +static const struct freq_tbl ftbl_gcc_tscss_cntr_clk_src[] = { + F(15625000, P_GCC_GPLL7_OUT_MAIN, 16, 1, 4), + { } +}; + +static struct clk_rcg2 gcc_tscss_cntr_clk_src = { + .cmd_rcgr = 0x21008, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_19, + .freq_tbl = ftbl_gcc_tscss_cntr_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_tscss_cntr_clk_src", + .parent_data = gcc_parent_data_19, + .num_parents = ARRAY_SIZE(gcc_parent_data_19), + .ops = &clk_rcg2_shared_ops, + }, +}; + static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = { F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), @@ -2899,6 +2952,50 @@ static struct clk_branch gcc_sgmi_clkref_en = { }, }; +static struct clk_branch gcc_tscss_ahb_clk = { + .halt_reg = 0x21024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21024, + .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_etu_clk = { + .halt_reg = 0x21020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_tscss_etu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tscss_global_cntr_clk = { + .halt_reg = 0x21004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x21004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_tscss_global_cntr_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_tscss_cntr_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_ufs_phy_ahb_clk = { .halt_reg = 0x83020, .halt_check = BRANCH_HALT_VOTED, @@ -3360,6 +3457,7 @@ static struct clk_regmap *gcc_qcs8300_clocks[] = { [GCC_GPLL0_OUT_EVEN] = &gcc_gpll0_out_even.clkr, [GCC_GPLL1] = &gcc_gpll1.clkr, [GCC_GPLL4] = &gcc_gpll4.clkr, + [GCC_GPLL5] = &gcc_gpll5.clkr, [GCC_GPLL7] = &gcc_gpll7.clkr, [GCC_GPLL9] = &gcc_gpll9.clkr, [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, @@ -3464,6 +3562,10 @@ static struct clk_regmap *gcc_qcs8300_clocks[] = { [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_SGMI_CLKREF_EN] = &gcc_sgmi_clkref_en.clkr, + [GCC_TSCSS_AHB_CLK] = &gcc_tscss_ahb_clk.clkr, + [GCC_TSCSS_CNTR_CLK_SRC] = &gcc_tscss_cntr_clk_src.clkr, + [GCC_TSCSS_ETU_CLK] = &gcc_tscss_etu_clk.clkr, + [GCC_TSCSS_GLOBAL_CNTR_CLK] = &gcc_tscss_global_cntr_clk.clkr, [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr, [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr, [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr, @@ -3523,6 +3625,7 @@ static const struct qcom_reset_map gcc_qcs8300_resets[] = { [GCC_PCIE_1_PHY_BCR] = { 0xae08c }, [GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR] = { 0xae094 }, [GCC_SDCC1_BCR] = { 0x20000 }, + [GCC_TSCSS_BCR] = { 0x21000 }, [GCC_UFS_PHY_BCR] = { 0x83000 }, [GCC_USB20_PRIM_BCR] = { 0x1c000 }, [GCC_USB2_PHY_PRIM_BCR] = { 0x5c01c }, @@ -3570,7 +3673,32 @@ static const struct regmap_config gcc_qcs8300_regmap_config = { .fast_io = true, }; +static const u32 gcc_qcs8300_critical_cbcrs[] = { + 0x32004, /* GCC_CAMERA_AHB_CLK */ + 0x32020, /* GCC_CAMERA_XO_CLK */ + 0x33004, /* GCC_DISP_AHB_CLK */ + 0x33018, /* GCC_DISP_XO_CLK */ + 0x7d004, /* GCC_GPU_CFG_AHB_CLK */ + 0x34004, /* GCC_VIDEO_AHB_CLK */ + 0x34024, /* GCC_VIDEO_XO_CLK */ +}; + +static void gcc_qcs8300_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); +} + +static const struct qcom_cc_driver_data gcc_qcs8300_driver_data = { + .clk_cbcrs = gcc_qcs8300_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_qcs8300_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_qcs8300_regs_configure, +}; + static const struct qcom_cc_desc gcc_qcs8300_desc = { + .driver_data = &gcc_qcs8300_driver_data, .config = &gcc_qcs8300_regmap_config, .clks = gcc_qcs8300_clocks, .num_clks = ARRAY_SIZE(gcc_qcs8300_clocks), @@ -3578,6 +3706,7 @@ static const struct qcom_cc_desc gcc_qcs8300_desc = { .num_resets = ARRAY_SIZE(gcc_qcs8300_resets), .gdscs = gcc_qcs8300_gdscs, .num_gdscs = ARRAY_SIZE(gcc_qcs8300_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_qcs8300_match_table[] = { @@ -3588,31 +3717,7 @@ MODULE_DEVICE_TABLE(of, gcc_qcs8300_match_table); static int gcc_qcs8300_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_qcs8300_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - /* Keep some clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0x32004); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x32020); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x33004); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x33018); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x7d004); /* GCC_GPU_CFG_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x34004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x34024); /* GCC_VIDEO_XO_CLK */ - - /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ - qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); - - return qcom_cc_really_probe(&pdev->dev, &gcc_qcs8300_desc, regmap); + return qcom_cc_probe(pdev, &gcc_qcs8300_desc); } static struct platform_driver gcc_qcs8300_driver = { @@ -3623,17 +3728,7 @@ static struct platform_driver gcc_qcs8300_driver = { }, }; -static int __init gcc_qcs8300_init(void) -{ - return platform_driver_register(&gcc_qcs8300_driver); -} -subsys_initcall(gcc_qcs8300_init); - -static void __exit gcc_qcs8300_exit(void) -{ - platform_driver_unregister(&gcc_qcs8300_driver); -} -module_exit(gcc_qcs8300_exit); +subsys_platform_driver(gcc_qcs8300_driver); MODULE_DESCRIPTION("QTI GCC QCS8300 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-qdu1000.c b/drivers/clk/qcom/gcc-qdu1000.c index 915bb9b4ff81..a139fd8f722d 100644 --- a/drivers/clk/qcom/gcc-qdu1000.c +++ b/drivers/clk/qcom/gcc-qdu1000.c @@ -2689,17 +2689,7 @@ static struct platform_driver gcc_qdu1000_driver = { }, }; -static int __init gcc_qdu1000_init(void) -{ - return platform_driver_register(&gcc_qdu1000_driver); -} -subsys_initcall(gcc_qdu1000_init); - -static void __exit gcc_qdu1000_exit(void) -{ - platform_driver_unregister(&gcc_qdu1000_driver); -} -module_exit(gcc_qdu1000_exit); +subsys_platform_driver(gcc_qdu1000_driver); MODULE_DESCRIPTION("QTI GCC QDU1000 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-sa8775p.c b/drivers/clk/qcom/gcc-sa8775p.c index dca316decd0e..0e02af686614 100644 --- a/drivers/clk/qcom/gcc-sa8775p.c +++ b/drivers/clk/qcom/gcc-sa8775p.c @@ -4644,7 +4644,34 @@ static const struct regmap_config gcc_sa8775p_regmap_config = { .fast_io = true, }; +static const u32 gcc_sa8775p_critical_cbcrs[] = { + 0x32004, /* GCC_CAMERA_AHB_CLK */ + 0x32020, /* GCC_CAMERA_XO_CLK */ + 0xc7004, /* GCC_DISP1_AHB_CLK */ + 0xc7018, /* GCC_DISP1_XO_CLK */ + 0x33004, /* GCC_DISP_AHB_CLK */ + 0x33018, /* GCC_DISP_XO_CLK */ + 0x7d004, /* GCC_GPU_CFG_AHB_CLK */ + 0x34004, /* GCC_VIDEO_AHB_CLK */ + 0x34024, /* GCC_VIDEO_XO_CLK */ +}; + +static void gcc_sa8775p_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); +} + +static const struct qcom_cc_driver_data gcc_sa8775p_driver_data = { + .clk_cbcrs = gcc_sa8775p_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sa8775p_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_sa8775p_regs_configure, +}; + static const struct qcom_cc_desc gcc_sa8775p_desc = { + .driver_data = &gcc_sa8775p_driver_data, .config = &gcc_sa8775p_regmap_config, .clks = gcc_sa8775p_clocks, .num_clks = ARRAY_SIZE(gcc_sa8775p_clocks), @@ -4652,6 +4679,7 @@ static const struct qcom_cc_desc gcc_sa8775p_desc = { .num_resets = ARRAY_SIZE(gcc_sa8775p_resets), .gdscs = gcc_sa8775p_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sa8775p_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_sa8775p_match_table[] = { @@ -4662,33 +4690,7 @@ MODULE_DEVICE_TABLE(of, gcc_sa8775p_match_table); static int gcc_sa8775p_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sa8775p_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x32004); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x32020); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0xc7004); /* GCC_DISP1_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0xc7018); /* GCC_DISP1_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x33004); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x33018); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x7d004); /* GCC_GPU_CFG_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x34004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x34024); /* GCC_VIDEO_XO_CLK */ - - /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ - qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); - - return qcom_cc_really_probe(&pdev->dev, &gcc_sa8775p_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sa8775p_desc); } static struct platform_driver gcc_sa8775p_driver = { diff --git a/drivers/clk/qcom/gcc-sar2130p.c b/drivers/clk/qcom/gcc-sar2130p.c index 475e2cda3618..8b6118f95835 100644 --- a/drivers/clk/qcom/gcc-sar2130p.c +++ b/drivers/clk/qcom/gcc-sar2130p.c @@ -2300,7 +2300,29 @@ static const struct regmap_config gcc_sar2130p_regmap_config = { .fast_io = true, }; +static const u32 gcc_sar2130p_critical_cbcrs[] = { + 0x37004, /* GCC_DISP_AHB_CLK */ + 0x42004, /* GCC_VIDEO_AHB_CLK */ + 0x42028, /* GCC_VIDEO_XO_CLK */ + 0x9b004, /* GCC_GPU_CFG_AHB_CLK */ +}; + +static void gcc_sar2130p_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */ + regmap_write(regmap, 0x62204, 0x0); +} + +static const struct qcom_cc_driver_data gcc_sar2130p_driver_data = { + .clk_cbcrs = gcc_sar2130p_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sar2130p_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_sar2130p_regs_configure, +}; + static const struct qcom_cc_desc gcc_sar2130p_desc = { + .driver_data = &gcc_sar2130p_driver_data, .config = &gcc_sar2130p_regmap_config, .clks = gcc_sar2130p_clocks, .num_clks = ARRAY_SIZE(gcc_sar2130p_clocks), @@ -2308,6 +2330,7 @@ static const struct qcom_cc_desc gcc_sar2130p_desc = { .num_resets = ARRAY_SIZE(gcc_sar2130p_resets), .gdscs = gcc_sar2130p_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sar2130p_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_sar2130p_match_table[] = { @@ -2318,28 +2341,7 @@ MODULE_DEVICE_TABLE(of, gcc_sar2130p_match_table); static int gcc_sar2130p_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sar2130p_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x37004); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x42004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x42028); /* GCC_VIDEO_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x9b004); /* GCC_GPU_CFG_AHB_CLK */ - - /* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */ - regmap_write(regmap, 0x62204, 0x0); - - return qcom_cc_really_probe(&pdev->dev, &gcc_sar2130p_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sar2130p_desc); } static struct platform_driver gcc_sar2130p_driver = { @@ -2350,17 +2352,7 @@ static struct platform_driver gcc_sar2130p_driver = { }, }; -static int __init gcc_sar2130p_init(void) -{ - return platform_driver_register(&gcc_sar2130p_driver); -} -subsys_initcall(gcc_sar2130p_init); - -static void __exit gcc_sar2130p_exit(void) -{ - platform_driver_unregister(&gcc_sar2130p_driver); -} -module_exit(gcc_sar2130p_exit); +subsys_platform_driver(gcc_sar2130p_driver); MODULE_DESCRIPTION("QTI GCC SAR2130P Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index 4a49ad7a9e5b..6d9ee31044a5 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -2408,7 +2408,35 @@ static const struct regmap_config gcc_sc7180_regmap_config = { .fast_io = true, }; +static const u32 gcc_sc7180_critical_cbcrs[] = { + 0x48004, /* GCC_CPUSS_GNOC_CLK */ + 0x0b004, /* GCC_VIDEO_AHB_CLK */ + 0x0b008, /* GCC_CAMERA_AHB_CLK */ + 0x0b00c, /* GCC_DISP_AHB_CLK */ + 0x0b02c, /* GCC_CAMERA_XO_CLK */ + 0x0b028, /* GCC_VIDEO_XO_CLK */ + 0x0b030, /* GCC_DISP_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ +}; + +static void gcc_sc7180_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Disable the GPLL0 active input to MM blocks, NPU and GPU via MISC registers. */ + regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); + regmap_update_bits(regmap, 0x4d110, 0x3, 0x3); + regmap_update_bits(regmap, 0x71028, 0x3, 0x3); +} + +static const struct qcom_cc_driver_data gcc_sc7180_driver_data = { + .clk_cbcrs = gcc_sc7180_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sc7180_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_sc7180_regs_configure, +}; + static const struct qcom_cc_desc gcc_sc7180_desc = { + .driver_data = &gcc_sc7180_driver_data, .config = &gcc_sc7180_regmap_config, .clk_hws = gcc_sc7180_hws, .num_clk_hws = ARRAY_SIZE(gcc_sc7180_hws), @@ -2428,37 +2456,7 @@ MODULE_DEVICE_TABLE(of, gcc_sc7180_match_table); static int gcc_sc7180_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sc7180_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - /* - * Disable the GPLL0 active input to MM blocks, NPU - * and GPU via MISC registers. - */ - regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); - regmap_update_bits(regmap, 0x4d110, 0x3, 0x3); - regmap_update_bits(regmap, 0x71028, 0x3, 0x3); - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x48004); /* GCC_CPUSS_GNOC_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b008); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b00c); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b02c); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b028); /* GCC_VIDEO_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b030); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */ - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - return qcom_cc_really_probe(&pdev->dev, &gcc_sc7180_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sc7180_desc); } static struct platform_driver gcc_sc7180_driver = { diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c index 4502926a2691..78399993cdce 100644 --- a/drivers/clk/qcom/gcc-sc7280.c +++ b/drivers/clk/qcom/gcc-sc7280.c @@ -3438,7 +3438,34 @@ static const struct regmap_config gcc_sc7280_regmap_config = { .fast_io = true, }; +static const u32 gcc_sc7280_critical_cbcrs[] = { + 0x26004, /* GCC_CAMERA_AHB_CLK */ + 0x26028, /* GCC_CAMERA_XO_CLK */ + 0x27004, /* GCC_DISP_AHB_CLK */ + 0x2701c, /* GCC_DISP_XO_CLK */ + 0x28004, /* GCC_VIDEO_AHB_CLK */ + 0x28014, /* GCC_VIDEO_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ +}; + +static void gcc_sc7280_regs_configure(struct device *dev, struct regmap *regmap) +{ + regmap_update_bits(regmap, 0x7100C, BIT(13), BIT(13)); + + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); +} + +static const struct qcom_cc_driver_data gcc_sc7280_driver_data = { + .clk_cbcrs = gcc_sc7280_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sc7280_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_sc7280_regs_configure, +}; + static const struct qcom_cc_desc gcc_sc7280_desc = { + .driver_data = &gcc_sc7280_driver_data, .config = &gcc_sc7280_regmap_config, .clks = gcc_sc7280_clocks, .num_clks = ARRAY_SIZE(gcc_sc7280_clocks), @@ -3446,6 +3473,7 @@ static const struct qcom_cc_desc gcc_sc7280_desc = { .num_resets = ARRAY_SIZE(gcc_sc7280_resets), .gdscs = gcc_sc7280_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sc7280_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_sc7280_match_table[] = { @@ -3456,32 +3484,7 @@ MODULE_DEVICE_TABLE(of, gcc_sc7280_match_table); static int gcc_sc7280_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sc7280_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x26004);/* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x26028);/* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x27004);/* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x2701c);/* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x28004);/* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x28014);/* GCC_VIDEO_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x71004);/* GCC_GPU_CFG_AHB_CLK */ - regmap_update_bits(regmap, 0x7100C, BIT(13), BIT(13)); - - /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ - qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - return qcom_cc_really_probe(&pdev->dev, &gcc_sc7280_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sc7280_desc); } static struct platform_driver gcc_sc7280_driver = { @@ -3492,17 +3495,7 @@ static struct platform_driver gcc_sc7280_driver = { }, }; -static int __init gcc_sc7280_init(void) -{ - return platform_driver_register(&gcc_sc7280_driver); -} -subsys_initcall(gcc_sc7280_init); - -static void __exit gcc_sc7280_exit(void) -{ - platform_driver_unregister(&gcc_sc7280_driver); -} -module_exit(gcc_sc7280_exit); +subsys_platform_driver(gcc_sc7280_driver); MODULE_DESCRIPTION("QTI GCC SC7280 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-sc8280xp.c b/drivers/clk/qcom/gcc-sc8280xp.c index 2ab111585d7f..918c70648d57 100644 --- a/drivers/clk/qcom/gcc-sc8280xp.c +++ b/drivers/clk/qcom/gcc-sc8280xp.c @@ -7509,7 +7509,27 @@ static const struct regmap_config gcc_sc8280xp_regmap_config = { .fast_io = true, }; +static const u32 gcc_sc8280xp_critical_cbcrs[] = { + 0x26004, /* GCC_CAMERA_AHB_CLK */ + 0x26020, /* GCC_CAMERA_XO_CLK */ + 0x27004, /* GCC_DISP_AHB_CLK */ + 0x27028, /* GCC_DISP_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0x28004, /* GCC_VIDEO_AHB_CLK */ + 0x28028, /* GCC_VIDEO_XO_CLK */ + 0xbb004, /* GCC_DISP1_AHB_CLK */ + 0xbb028, /* GCC_DISP1_XO_CLK */ +}; + +static const struct qcom_cc_driver_data gcc_sc8280xp_driver_data = { + .clk_cbcrs = gcc_sc8280xp_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sc8280xp_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), +}; + static const struct qcom_cc_desc gcc_sc8280xp_desc = { + .driver_data = &gcc_sc8280xp_driver_data, .config = &gcc_sc8280xp_regmap_config, .clks = gcc_sc8280xp_clocks, .num_clks = ARRAY_SIZE(gcc_sc8280xp_clocks), @@ -7538,21 +7558,6 @@ static int gcc_sc8280xp_probe(struct platform_device *pdev) goto err_put_rpm; } - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x26004); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x26020); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x27004); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x27028); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x28004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x28028); /* GCC_VIDEO_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0xbb004); /* GCC_DISP1_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0xbb028); /* GCC_DISP1_XO_CLK */ - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - goto err_put_rpm; - ret = qcom_cc_really_probe(&pdev->dev, &gcc_sc8280xp_desc, regmap); if (ret) goto err_put_rpm; @@ -7581,17 +7586,7 @@ static struct platform_driver gcc_sc8280xp_driver = { }, }; -static int __init gcc_sc8280xp_init(void) -{ - return platform_driver_register(&gcc_sc8280xp_driver); -} -subsys_initcall(gcc_sc8280xp_init); - -static void __exit gcc_sc8280xp_exit(void) -{ - platform_driver_unregister(&gcc_sc8280xp_driver); -} -module_exit(gcc_sc8280xp_exit); +subsys_platform_driver(gcc_sc8280xp_driver); MODULE_DESCRIPTION("Qualcomm SC8280XP GCC driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-sdx55.c b/drivers/clk/qcom/gcc-sdx55.c index 84c507656e8f..8d8547c12b19 100644 --- a/drivers/clk/qcom/gcc-sdx55.c +++ b/drivers/clk/qcom/gcc-sdx55.c @@ -1587,7 +1587,25 @@ static const struct regmap_config gcc_sdx55_regmap_config = { .fast_io = true, }; +static const u32 gcc_sdx55_critical_cbcrs[] = { + 0x6d008, /* GCC_SYS_NOC_CPUSS_AHB_CLK */ +}; + +static void gcc_sdx55_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Keep some clocks always-on */ + regmap_update_bits(regmap, 0x6d008, BIT(21), BIT(21)); /* GCC_CPUSS_AHB_CLK */ + regmap_update_bits(regmap, 0x6d008, BIT(22), BIT(22)); /* GCC_CPUSS_GNOC_CLK */ +} + +static const struct qcom_cc_driver_data gcc_sdx55_driver_data = { + .clk_cbcrs = gcc_sdx55_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sdx55_critical_cbcrs), + .clk_regs_configure = gcc_sdx55_regs_configure, +}; + static const struct qcom_cc_desc gcc_sdx55_desc = { + .driver_data = &gcc_sdx55_driver_data, .config = &gcc_sdx55_regmap_config, .clks = gcc_sdx55_clocks, .num_clks = ARRAY_SIZE(gcc_sdx55_clocks), @@ -1605,18 +1623,7 @@ MODULE_DEVICE_TABLE(of, gcc_sdx55_match_table); static int gcc_sdx55_probe(struct platform_device *pdev) { - struct regmap *regmap; - - regmap = qcom_cc_map(pdev, &gcc_sdx55_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x6d008); /* GCC_SYS_NOC_CPUSS_AHB_CLK */ - regmap_update_bits(regmap, 0x6d008, BIT(21), BIT(21)); /* GCC_CPUSS_AHB_CLK */ - regmap_update_bits(regmap, 0x6d008, BIT(22), BIT(22)); /* GCC_CPUSS_GNOC_CLK */ - - return qcom_cc_really_probe(&pdev->dev, &gcc_sdx55_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sdx55_desc); } static struct platform_driver gcc_sdx55_driver = { @@ -1627,17 +1634,7 @@ static struct platform_driver gcc_sdx55_driver = { }, }; -static int __init gcc_sdx55_init(void) -{ - return platform_driver_register(&gcc_sdx55_driver); -} -subsys_initcall(gcc_sdx55_init); - -static void __exit gcc_sdx55_exit(void) -{ - platform_driver_unregister(&gcc_sdx55_driver); -} -module_exit(gcc_sdx55_exit); +subsys_platform_driver(gcc_sdx55_driver); MODULE_DESCRIPTION("QTI GCC SDX55 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-sdx65.c b/drivers/clk/qcom/gcc-sdx65.c index fe297c606f97..b1ab265ba2c1 100644 --- a/drivers/clk/qcom/gcc-sdx65.c +++ b/drivers/clk/qcom/gcc-sdx65.c @@ -1551,7 +1551,25 @@ static const struct regmap_config gcc_sdx65_regmap_config = { .fast_io = true, }; +static const u32 gcc_sdx65_critical_cbcrs[] = { + 0x6d008, /* GCC_SYS_NOC_CPUSS_AHB_CLK */ +}; + +static void gcc_sdx65_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Keep some clocks always-on */ + regmap_update_bits(regmap, 0x6d008, BIT(21), BIT(21)); /* GCC_CPUSS_AHB_CLK */ + regmap_update_bits(regmap, 0x6d008, BIT(22), BIT(22)); /* GCC_CPUSS_GNOC_CLK */ +} + +static const struct qcom_cc_driver_data gcc_sdx65_driver_data = { + .clk_cbcrs = gcc_sdx65_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sdx65_critical_cbcrs), + .clk_regs_configure = gcc_sdx65_regs_configure, +}; + static const struct qcom_cc_desc gcc_sdx65_desc = { + .driver_data = &gcc_sdx65_driver_data, .config = &gcc_sdx65_regmap_config, .clks = gcc_sdx65_clocks, .num_clks = ARRAY_SIZE(gcc_sdx65_clocks), @@ -1569,18 +1587,7 @@ MODULE_DEVICE_TABLE(of, gcc_sdx65_match_table); static int gcc_sdx65_probe(struct platform_device *pdev) { - struct regmap *regmap; - - regmap = qcom_cc_map(pdev, &gcc_sdx65_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x6d008); /* GCC_SYS_NOC_CPUSS_AHB_CLK */ - regmap_update_bits(regmap, 0x6d008, BIT(21), BIT(21)); /* GCC_CPUSS_AHB_CLK */ - regmap_update_bits(regmap, 0x6d008, BIT(22), BIT(22)); /* GCC_CPUSS_GNOC_CLK */ - - return qcom_cc_really_probe(&pdev->dev, &gcc_sdx65_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sdx65_desc); } static struct platform_driver gcc_sdx65_driver = { @@ -1591,17 +1598,7 @@ static struct platform_driver gcc_sdx65_driver = { }, }; -static int __init gcc_sdx65_init(void) -{ - return platform_driver_register(&gcc_sdx65_driver); -} -subsys_initcall(gcc_sdx65_init); - -static void __exit gcc_sdx65_exit(void) -{ - platform_driver_unregister(&gcc_sdx65_driver); -} -module_exit(gcc_sdx65_exit); +subsys_platform_driver(gcc_sdx65_driver); MODULE_DESCRIPTION("QTI GCC SDX65 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-sdx75.c b/drivers/clk/qcom/gcc-sdx75.c index 6712e76f875c..080e14e832f0 100644 --- a/drivers/clk/qcom/gcc-sdx75.c +++ b/drivers/clk/qcom/gcc-sdx75.c @@ -2905,7 +2905,20 @@ static const struct regmap_config gcc_sdx75_regmap_config = { .fast_io = true, }; +static const u32 gcc_sdx75_critical_cbcrs[] = { + 0x3e004, /* GCC_AHB_PCIE_LINK_CLK */ + 0x3e008, /* GCC_XO_PCIE_LINK_CLK */ +}; + +static const struct qcom_cc_driver_data gcc_sdx75_driver_data = { + .clk_cbcrs = gcc_sdx75_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sdx75_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), +}; + static const struct qcom_cc_desc gcc_sdx75_desc = { + .driver_data = &gcc_sdx75_driver_data, .config = &gcc_sdx75_regmap_config, .clks = gcc_sdx75_clocks, .num_clks = ARRAY_SIZE(gcc_sdx75_clocks), @@ -2913,6 +2926,7 @@ static const struct qcom_cc_desc gcc_sdx75_desc = { .num_resets = ARRAY_SIZE(gcc_sdx75_resets), .gdscs = gcc_sdx75_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sdx75_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_sdx75_match_table[] = { @@ -2923,23 +2937,7 @@ MODULE_DEVICE_TABLE(of, gcc_sdx75_match_table); static int gcc_sdx75_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sdx75_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x3e004); /* GCC_AHB_PCIE_LINK_CLK */ - qcom_branch_set_clk_en(regmap, 0x3e008); /* GCC_XO_PCIE_LINK_CLK */ - - return qcom_cc_really_probe(&pdev->dev, &gcc_sdx75_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sdx75_desc); } static struct platform_driver gcc_sdx75_driver = { @@ -2950,17 +2948,7 @@ static struct platform_driver gcc_sdx75_driver = { }, }; -static int __init gcc_sdx75_init(void) -{ - return platform_driver_register(&gcc_sdx75_driver); -} -subsys_initcall(gcc_sdx75_init); - -static void __exit gcc_sdx75_exit(void) -{ - platform_driver_unregister(&gcc_sdx75_driver); -} -module_exit(gcc_sdx75_exit); +subsys_platform_driver(gcc_sdx75_driver); MODULE_DESCRIPTION("QTI GCC SDX75 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-shikra.c b/drivers/clk/qcom/gcc-shikra.c index 2a1c1fc253aa..13c99a883e29 100644 --- a/drivers/clk/qcom/gcc-shikra.c +++ b/drivers/clk/qcom/gcc-shikra.c @@ -4416,17 +4416,7 @@ static struct platform_driver gcc_shikra_driver = { }, }; -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); +subsys_platform_driver(gcc_shikra_driver); MODULE_DESCRIPTION("QTI GCC Shikra Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-sm4450.c b/drivers/clk/qcom/gcc-sm4450.c index 30fc7af09930..a3e157c52be6 100644 --- a/drivers/clk/qcom/gcc-sm4450.c +++ b/drivers/clk/qcom/gcc-sm4450.c @@ -140,6 +140,7 @@ static const struct alpha_pll_config gcc_gpll3_config = { }; static struct clk_alpha_pll gcc_gpll3 = { + .config = &gcc_gpll3_config, .offset = 0x3000, .vco_table = lucid_evo_vco, .num_vco = ARRAY_SIZE(lucid_evo_vco), @@ -2815,7 +2816,41 @@ static const struct regmap_config gcc_sm4450_regmap_config = { .fast_io = true, }; +static struct clk_alpha_pll *gcc_sm4450_plls[] = { + &gcc_gpll3, +}; + +static const u32 gcc_sm4450_critical_cbcrs[] = { + 0x36004, /* GCC_CAMERA_AHB_CLK */ + 0x36018, /* GCC_CAMERA_SLEEP_CLK */ + 0x3601c, /* GCC_CAMERA_XO_CLK */ + 0x37004, /* GCC_DISP_AHB_CLK */ + 0x37014, /* GCC_DISP_XO_CLK */ + 0x81004, /* GCC_GPU_CFG_AHB_CLK */ + 0x42004, /* GCC_VIDEO_AHB_CLK */ + 0x42018, /* GCC_VIDEO_XO_CLK */ +}; + +static void gcc_sm4450_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* FORCE_MEM_CORE_ON for the UFS PHY ICE core clock */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); + + regmap_update_bits(regmap, 0x4201c, BIT(21), BIT(21)); +} + +static const struct qcom_cc_driver_data gcc_sm4450_driver_data = { + .alpha_plls = gcc_sm4450_plls, + .num_alpha_plls = ARRAY_SIZE(gcc_sm4450_plls), + .clk_cbcrs = gcc_sm4450_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sm4450_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_sm4450_regs_configure, +}; + static const struct qcom_cc_desc gcc_sm4450_desc = { + .driver_data = &gcc_sm4450_driver_data, .config = &gcc_sm4450_regmap_config, .clks = gcc_sm4450_clocks, .num_clks = ARRAY_SIZE(gcc_sm4450_clocks), @@ -2823,6 +2858,7 @@ static const struct qcom_cc_desc gcc_sm4450_desc = { .num_resets = ARRAY_SIZE(gcc_sm4450_resets), .gdscs = gcc_sm4450_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sm4450_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_sm4450_match_table[] = { @@ -2833,34 +2869,7 @@ MODULE_DEVICE_TABLE(of, gcc_sm4450_match_table); static int gcc_sm4450_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sm4450_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - clk_lucid_evo_pll_configure(&gcc_gpll3, regmap, &gcc_gpll3_config); - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x36004); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x36018); /* GCC_CAMERA_SLEEP_CLK */ - qcom_branch_set_clk_en(regmap, 0x3601c); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x37004); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x37014); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x81004); /* GCC_GPU_CFG_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x42004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x42018); /* GCC_VIDEO_XO_CLK */ - - regmap_update_bits(regmap, 0x4201c, BIT(21), BIT(21)); - - return qcom_cc_really_probe(&pdev->dev, &gcc_sm4450_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sm4450_desc); } static struct platform_driver gcc_sm4450_driver = { @@ -2871,17 +2880,7 @@ static struct platform_driver gcc_sm4450_driver = { }, }; -static int __init gcc_sm4450_init(void) -{ - return platform_driver_register(&gcc_sm4450_driver); -} -subsys_initcall(gcc_sm4450_init); - -static void __exit gcc_sm4450_exit(void) -{ - platform_driver_unregister(&gcc_sm4450_driver); -} -module_exit(gcc_sm4450_exit); +subsys_platform_driver(gcc_sm4450_driver); MODULE_DESCRIPTION("QTI GCC SM4450 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-sm6115.c b/drivers/clk/qcom/gcc-sm6115.c index a3c9dbe3a48a..5736e59d76ce 100644 --- a/drivers/clk/qcom/gcc-sm6115.c +++ b/drivers/clk/qcom/gcc-sm6115.c @@ -3525,17 +3525,7 @@ static struct platform_driver gcc_sm6115_driver = { }, }; -static int __init gcc_sm6115_init(void) -{ - return platform_driver_register(&gcc_sm6115_driver); -} -subsys_initcall(gcc_sm6115_init); - -static void __exit gcc_sm6115_exit(void) -{ - platform_driver_unregister(&gcc_sm6115_driver); -} -module_exit(gcc_sm6115_exit); +subsys_platform_driver(gcc_sm6115_driver); MODULE_DESCRIPTION("QTI GCC SM6115 and SM4250 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-sm6125.c b/drivers/clk/qcom/gcc-sm6125.c index 07bb1e5c4a30..ee3cd0b00fc5 100644 --- a/drivers/clk/qcom/gcc-sm6125.c +++ b/drivers/clk/qcom/gcc-sm6125.c @@ -4172,17 +4172,7 @@ static struct platform_driver gcc_sm6125_driver = { }, }; -static int __init gcc_sm6125_init(void) -{ - return platform_driver_register(&gcc_sm6125_driver); -} -subsys_initcall(gcc_sm6125_init); - -static void __exit gcc_sm6125_exit(void) -{ - platform_driver_unregister(&gcc_sm6125_driver); -} -module_exit(gcc_sm6125_exit); +subsys_platform_driver(gcc_sm6125_driver); MODULE_DESCRIPTION("QTI GCC SM6125 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-sm6375.c b/drivers/clk/qcom/gcc-sm6375.c index f47dc2808095..9c2acf8dc4b7 100644 --- a/drivers/clk/qcom/gcc-sm6375.c +++ b/drivers/clk/qcom/gcc-sm6375.c @@ -3903,17 +3903,7 @@ static struct platform_driver gcc_sm6375_driver = { }, }; -static int __init gcc_sm6375_init(void) -{ - return platform_driver_register(&gcc_sm6375_driver); -} -subsys_initcall(gcc_sm6375_init); - -static void __exit gcc_sm6375_exit(void) -{ - platform_driver_unregister(&gcc_sm6375_driver); -} -module_exit(gcc_sm6375_exit); +subsys_platform_driver(gcc_sm6375_driver); MODULE_DESCRIPTION("QTI GCC SM6375 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-sm7150.c b/drivers/clk/qcom/gcc-sm7150.c index dcb5d82a1a31..169aef61e749 100644 --- a/drivers/clk/qcom/gcc-sm7150.c +++ b/drivers/clk/qcom/gcc-sm7150.c @@ -2966,7 +2966,35 @@ static const struct regmap_config gcc_sm7150_regmap_config = { .fast_io = true, }; +static const u32 gcc_sm7150_critical_cbcrs[] = { + 0x48004, /* GCC_CPUSS_GNOC_CLK */ + 0x0b004, /* GCC_VIDEO_AHB_CLK */ + 0x0b008, /* GCC_CAMERA_AHB_CLK */ + 0x0b00c, /* GCC_DISP_AHB_CLK */ + 0x0b02c, /* GCC_CAMERA_XO_CLK */ + 0x0b028, /* GCC_VIDEO_XO_CLK */ + 0x0b030, /* GCC_DISP_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ +}; + +static void gcc_sm7150_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Disable the GPLL0 active input to MM blocks, NPU and GPU via MISC registers. */ + regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); + regmap_update_bits(regmap, 0x4d110, 0x3, 0x3); + regmap_update_bits(regmap, 0x71028, 0x3, 0x3); +} + +static const struct qcom_cc_driver_data gcc_sm7150_driver_data = { + .clk_cbcrs = gcc_sm7150_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sm7150_critical_cbcrs), + .dfs_rcgs = gcc_sm7150_dfs_desc, + .num_dfs_rcgs = ARRAY_SIZE(gcc_sm7150_dfs_desc), + .clk_regs_configure = gcc_sm7150_regs_configure, +}; + static const struct qcom_cc_desc gcc_sm7150_desc = { + .driver_data = &gcc_sm7150_driver_data, .config = &gcc_sm7150_regmap_config, .clk_hws = gcc_sm7150_hws, .num_clk_hws = ARRAY_SIZE(gcc_sm7150_hws), @@ -2986,37 +3014,7 @@ MODULE_DEVICE_TABLE(of, gcc_sm7150_match_table); static int gcc_sm7150_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sm7150_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - /* - * Disable the GPLL0 active input to MM blocks, NPU - * and GPU via MISC registers. - */ - regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); - regmap_update_bits(regmap, 0x4d110, 0x3, 0x3); - regmap_update_bits(regmap, 0x71028, 0x3, 0x3); - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x48004); /* GCC_CPUSS_GNOC_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b008); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b00c); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b02c); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b028); /* GCC_VIDEO_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b030); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */ - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_sm7150_dfs_desc, - ARRAY_SIZE(gcc_sm7150_dfs_desc)); - if (ret) - return ret; - - return qcom_cc_really_probe(&pdev->dev, &gcc_sm7150_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sm7150_desc); } static struct platform_driver gcc_sm7150_driver = { @@ -3027,17 +3025,7 @@ static struct platform_driver gcc_sm7150_driver = { }, }; -static int __init gcc_sm7150_init(void) -{ - return platform_driver_register(&gcc_sm7150_driver); -} -subsys_initcall(gcc_sm7150_init); - -static void __exit gcc_sm7150_exit(void) -{ - platform_driver_unregister(&gcc_sm7150_driver); -} -module_exit(gcc_sm7150_exit); +subsys_platform_driver(gcc_sm7150_driver); MODULE_DESCRIPTION("Qualcomm SM7150 Global Clock Controller"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c index a93d1f412a7b..b38a44842686 100644 --- a/drivers/clk/qcom/gcc-sm8150.c +++ b/drivers/clk/qcom/gcc-sm8150.c @@ -3808,17 +3808,7 @@ static struct platform_driver gcc_sm8150_driver = { }, }; -static int __init gcc_sm8150_init(void) -{ - return platform_driver_register(&gcc_sm8150_driver); -} -subsys_initcall(gcc_sm8150_init); - -static void __exit gcc_sm8150_exit(void) -{ - platform_driver_unregister(&gcc_sm8150_driver); -} -module_exit(gcc_sm8150_exit); +subsys_platform_driver(gcc_sm8150_driver); MODULE_DESCRIPTION("QTI GCC SM8150 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-sm8250.c b/drivers/clk/qcom/gcc-sm8250.c index 1c59d70e0f96..7ed7876577d1 100644 --- a/drivers/clk/qcom/gcc-sm8250.c +++ b/drivers/clk/qcom/gcc-sm8250.c @@ -3603,6 +3603,15 @@ static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { DEFINE_RCG_DFS(gcc_qupv3_wrap2_s5_clk_src), }; +static const u32 gcc_sm8250_critical_cbcrs[] = { + 0x0b004, /* GCC_VIDEO_AHB_CLK */ + 0x0b008, /* GCC_CAMERA_AHB_CLK */ + 0x0b00c, /* GCC_DISP_AHB_CLK */ + 0x4818c, /* GCC_CPUSS_DVM_BUS_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0x52000, /* GCC_SYS_NOC_CPUSS_AHB_CLK */ +}; + static const struct regmap_config gcc_sm8250_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -3611,6 +3620,24 @@ static const struct regmap_config gcc_sm8250_regmap_config = { .fast_io = true, }; +static void gcc_sm8250_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* + * Disable the GPLL0 active input to NPU and GPU + * via MISC registers. + */ + regmap_set_bits(regmap, 0x4d110, 0x3); + regmap_set_bits(regmap, 0x71028, 0x3); +} + +static const struct qcom_cc_driver_data gcc_sm8250_driver_data = { + .clk_cbcrs = gcc_sm8250_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sm8250_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_sm8250_regs_configure, +}; + static const struct qcom_cc_desc gcc_sm8250_desc = { .config = &gcc_sm8250_regmap_config, .clks = gcc_sm8250_clocks, @@ -3619,6 +3646,7 @@ static const struct qcom_cc_desc gcc_sm8250_desc = { .num_resets = ARRAY_SIZE(gcc_sm8250_resets), .gdscs = gcc_sm8250_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sm8250_gdscs), + .driver_data = &gcc_sm8250_driver_data, }; static const struct of_device_id gcc_sm8250_match_table[] = { @@ -3629,34 +3657,7 @@ MODULE_DEVICE_TABLE(of, gcc_sm8250_match_table); static int gcc_sm8250_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sm8250_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - /* - * Disable the GPLL0 active input to NPU and GPU - * via MISC registers. - */ - regmap_update_bits(regmap, 0x4d110, 0x3, 0x3); - regmap_update_bits(regmap, 0x71028, 0x3, 0x3); - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x0b004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b008); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x0b00c); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x4818c); /* GCC_CPUSS_DVM_BUS_CLK */ - qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x52000); /* GCC_SYS_NOC_CPUSS_AHB_CLK */ - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - return qcom_cc_really_probe(&pdev->dev, &gcc_sm8250_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sm8250_desc); } static struct platform_driver gcc_sm8250_driver = { @@ -3667,17 +3668,7 @@ static struct platform_driver gcc_sm8250_driver = { }, }; -static int __init gcc_sm8250_init(void) -{ - return platform_driver_register(&gcc_sm8250_driver); -} -subsys_initcall(gcc_sm8250_init); - -static void __exit gcc_sm8250_exit(void) -{ - platform_driver_unregister(&gcc_sm8250_driver); -} -module_exit(gcc_sm8250_exit); +subsys_platform_driver(gcc_sm8250_driver); MODULE_DESCRIPTION("QTI GCC SM8250 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-sm8350.c b/drivers/clk/qcom/gcc-sm8350.c index 2d94f3046b71..3b7aef50cfe3 100644 --- a/drivers/clk/qcom/gcc-sm8350.c +++ b/drivers/clk/qcom/gcc-sm8350.c @@ -3779,7 +3779,32 @@ static const struct regmap_config gcc_sm8350_regmap_config = { .fast_io = true, }; +static const u32 gcc_sm8350_critical_cbcrs[] = { + 0x26004, /* GCC_CAMERA_AHB_CLK */ + 0x26018, /* GCC_CAMERA_XO_CLK */ + 0x27004, /* GCC_DISP_AHB_CLK */ + 0x2701c, /* GCC_DISP_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0x28004, /* GCC_VIDEO_AHB_CLK */ + 0x28020, /* GCC_VIDEO_XO_CLK */ +}; + +static void gcc_sm8350_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + regmap_update_bits(regmap, gcc_ufs_phy_ice_core_clk.halt_reg, BIT(14), BIT(14)); +} + +static const struct qcom_cc_driver_data gcc_sm8350_driver_data = { + .clk_cbcrs = gcc_sm8350_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sm8350_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_sm8350_regs_configure, +}; + static const struct qcom_cc_desc gcc_sm8350_desc = { + .driver_data = &gcc_sm8350_driver_data, .config = &gcc_sm8350_regmap_config, .clks = gcc_sm8350_clocks, .num_clks = ARRAY_SIZE(gcc_sm8350_clocks), @@ -3787,6 +3812,7 @@ static const struct qcom_cc_desc gcc_sm8350_desc = { .num_resets = ARRAY_SIZE(gcc_sm8350_resets), .gdscs = gcc_sm8350_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sm8350_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_sm8350_match_table[] = { @@ -3797,32 +3823,7 @@ MODULE_DEVICE_TABLE(of, gcc_sm8350_match_table); static int gcc_sm8350_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sm8350_desc); - if (IS_ERR(regmap)) { - dev_err(&pdev->dev, "Failed to map gcc registers\n"); - return PTR_ERR(regmap); - } - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x26004); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x26018); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x27004); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x2701c); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x28004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x28020); /* GCC_VIDEO_XO_CLK */ - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ - regmap_update_bits(regmap, gcc_ufs_phy_ice_core_clk.halt_reg, BIT(14), BIT(14)); - - return qcom_cc_really_probe(&pdev->dev, &gcc_sm8350_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sm8350_desc); } static struct platform_driver gcc_sm8350_driver = { @@ -3833,17 +3834,7 @@ static struct platform_driver gcc_sm8350_driver = { }, }; -static int __init gcc_sm8350_init(void) -{ - return platform_driver_register(&gcc_sm8350_driver); -} -subsys_initcall(gcc_sm8350_init); - -static void __exit gcc_sm8350_exit(void) -{ - platform_driver_unregister(&gcc_sm8350_driver); -} -module_exit(gcc_sm8350_exit); +subsys_platform_driver(gcc_sm8350_driver); MODULE_DESCRIPTION("QTI GCC SM8350 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-sm8450.c b/drivers/clk/qcom/gcc-sm8450.c index b18bb34889ab..cdae5d9c8aec 100644 --- a/drivers/clk/qcom/gcc-sm8450.c +++ b/drivers/clk/qcom/gcc-sm8450.c @@ -3392,7 +3392,32 @@ static const struct regmap_config gcc_sm8450_regmap_config = { .fast_io = true, }; +static const u32 gcc_sm8450_critical_cbcrs[] = { + 0x36004, /* GCC_CAMERA_AHB_CLK */ + 0x36020, /* GCC_CAMERA_XO_CLK */ + 0x37004, /* GCC_DISP_AHB_CLK */ + 0x3701c, /* GCC_DISP_XO_CLK */ + 0x81004, /* GCC_GPU_CFG_AHB_CLK */ + 0x42004, /* GCC_VIDEO_AHB_CLK */ + 0x42028, /* GCC_VIDEO_XO_CLK */ +}; + +static void gcc_sm8450_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + regmap_update_bits(regmap, gcc_ufs_phy_ice_core_clk.halt_reg, BIT(14), BIT(14)); +} + +static const struct qcom_cc_driver_data gcc_sm8450_driver_data = { + .clk_cbcrs = gcc_sm8450_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sm8450_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_sm8450_regs_configure, +}; + static const struct qcom_cc_desc gcc_sm8450_desc = { + .driver_data = &gcc_sm8450_driver_data, .config = &gcc_sm8450_regmap_config, .clks = gcc_sm8450_clocks, .num_clks = ARRAY_SIZE(gcc_sm8450_clocks), @@ -3400,6 +3425,7 @@ static const struct qcom_cc_desc gcc_sm8450_desc = { .num_resets = ARRAY_SIZE(gcc_sm8450_resets), .gdscs = gcc_sm8450_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sm8450_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_sm8450_match_table[] = { @@ -3411,18 +3437,6 @@ MODULE_DEVICE_TABLE(of, gcc_sm8450_match_table); static int gcc_sm8450_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sm8450_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - if (of_device_is_compatible(pdev->dev.of_node, "qcom,sm8475-gcc")) { /* Update GCC PLL0 */ gcc_gpll0.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE]; @@ -3456,19 +3470,7 @@ static int gcc_sm8450_probe(struct platform_device *pdev) gcc_sm8450_desc.clks[SM8475_GCC_GPLL3] = &sm8475_gcc_gpll3.clkr; } - /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ - regmap_update_bits(regmap, gcc_ufs_phy_ice_core_clk.halt_reg, BIT(14), BIT(14)); - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x36004); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x36020); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x37004); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x3701c); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x81004); /* GCC_GPU_CFG_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x42004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x42028); /* GCC_VIDEO_XO_CLK */ - - return qcom_cc_really_probe(&pdev->dev, &gcc_sm8450_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sm8450_desc); } static struct platform_driver gcc_sm8450_driver = { @@ -3479,17 +3481,7 @@ static struct platform_driver gcc_sm8450_driver = { }, }; -static int __init gcc_sm8450_init(void) -{ - return platform_driver_register(&gcc_sm8450_driver); -} -subsys_initcall(gcc_sm8450_init); - -static void __exit gcc_sm8450_exit(void) -{ - platform_driver_unregister(&gcc_sm8450_driver); -} -module_exit(gcc_sm8450_exit); +subsys_platform_driver(gcc_sm8450_driver); MODULE_DESCRIPTION("QTI GCC SM8450 / SM8475 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c index 36a5b7de5b55..80a44ff7d211 100644 --- a/drivers/clk/qcom/gcc-sm8550.c +++ b/drivers/clk/qcom/gcc-sm8550.c @@ -3319,7 +3319,35 @@ static const struct regmap_config gcc_sm8550_regmap_config = { .fast_io = true, }; +static const u32 gcc_sm8550_critical_cbcrs[] = { + 0x26004, /* GCC_CAMERA_AHB_CLK */ + 0x26028, /* GCC_CAMERA_XO_CLK */ + 0x27004, /* GCC_DISP_AHB_CLK */ + 0x27018, /* GCC_DISP_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0x32004, /* GCC_VIDEO_AHB_CLK */ + 0x32030, /* GCC_VIDEO_XO_CLK */ +}; + +static void gcc_sm8550_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + regmap_update_bits(regmap, gcc_ufs_phy_ice_core_clk.halt_reg, BIT(14), BIT(14)); + + /* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */ + regmap_write(regmap, 0x52024, 0x0); +} + +static const struct qcom_cc_driver_data gcc_sm8550_driver_data = { + .clk_cbcrs = gcc_sm8550_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sm8550_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_sm8550_regs_configure, +}; + static const struct qcom_cc_desc gcc_sm8550_desc = { + .driver_data = &gcc_sm8550_driver_data, .config = &gcc_sm8550_regmap_config, .clks = gcc_sm8550_clocks, .num_clks = ARRAY_SIZE(gcc_sm8550_clocks), @@ -3327,6 +3355,7 @@ static const struct qcom_cc_desc gcc_sm8550_desc = { .num_resets = ARRAY_SIZE(gcc_sm8550_resets), .gdscs = gcc_sm8550_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sm8550_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_sm8550_match_table[] = { @@ -3337,34 +3366,7 @@ MODULE_DEVICE_TABLE(of, gcc_sm8550_match_table); static int gcc_sm8550_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sm8550_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ - regmap_update_bits(regmap, gcc_ufs_phy_ice_core_clk.halt_reg, BIT(14), BIT(14)); - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x26004); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x26028); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x27004); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x27018); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x32004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x32030); /* GCC_VIDEO_XO_CLK */ - - /* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */ - regmap_write(regmap, 0x52024, 0x0); - - return qcom_cc_really_probe(&pdev->dev, &gcc_sm8550_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sm8550_desc); } static struct platform_driver gcc_sm8550_driver = { @@ -3375,17 +3377,7 @@ static struct platform_driver gcc_sm8550_driver = { }, }; -static int __init gcc_sm8550_init(void) -{ - return platform_driver_register(&gcc_sm8550_driver); -} -subsys_initcall(gcc_sm8550_init); - -static void __exit gcc_sm8550_exit(void) -{ - platform_driver_unregister(&gcc_sm8550_driver); -} -module_exit(gcc_sm8550_exit); +subsys_platform_driver(gcc_sm8550_driver); MODULE_DESCRIPTION("QTI GCC SM8550 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-sm8650.c b/drivers/clk/qcom/gcc-sm8650.c index f7e2d7ec60c9..e439c958ae16 100644 --- a/drivers/clk/qcom/gcc-sm8650.c +++ b/drivers/clk/qcom/gcc-sm8650.c @@ -3777,7 +3777,36 @@ static const struct regmap_config gcc_sm8650_regmap_config = { .fast_io = true, }; +static const u32 gcc_sm8650_critical_cbcrs[] = { + 0x26004, /* GCC_CAMERA_AHB_CLK */ + 0x26028, /* GCC_CAMERA_XO_CLK */ + 0x27004, /* GCC_DISP_AHB_CLK */ + 0x27018, /* GCC_DISP_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0x32004, /* GCC_VIDEO_AHB_CLK */ + 0x32030, /* GCC_VIDEO_XO_CLK */ +}; + +static void gcc_sm8650_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true); + + /* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */ + regmap_write(regmap, 0x52150, 0x0); +} + +static const struct qcom_cc_driver_data gcc_sm8650_driver_data = { + .clk_cbcrs = gcc_sm8650_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sm8650_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_sm8650_regs_configure, +}; + static const struct qcom_cc_desc gcc_sm8650_desc = { + .driver_data = &gcc_sm8650_driver_data, .config = &gcc_sm8650_regmap_config, .clks = gcc_sm8650_clocks, .num_clks = ARRAY_SIZE(gcc_sm8650_clocks), @@ -3785,6 +3814,7 @@ static const struct qcom_cc_desc gcc_sm8650_desc = { .num_resets = ARRAY_SIZE(gcc_sm8650_resets), .gdscs = gcc_sm8650_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sm8650_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_sm8650_match_table[] = { @@ -3795,35 +3825,7 @@ MODULE_DEVICE_TABLE(of, gcc_sm8650_match_table); static int gcc_sm8650_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sm8650_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x26004); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x26028); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x27004); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x27018); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x32004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x32030); /* GCC_VIDEO_XO_CLK */ - - /* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks */ - qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); - qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true); - - /* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */ - regmap_write(regmap, 0x52150, 0x0); - - return qcom_cc_really_probe(&pdev->dev, &gcc_sm8650_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sm8650_desc); } static struct platform_driver gcc_sm8650_driver = { @@ -3834,17 +3836,7 @@ static struct platform_driver gcc_sm8650_driver = { }, }; -static int __init gcc_sm8650_init(void) -{ - return platform_driver_register(&gcc_sm8650_driver); -} -subsys_initcall(gcc_sm8650_init); - -static void __exit gcc_sm8650_exit(void) -{ - platform_driver_unregister(&gcc_sm8650_driver); -} -module_exit(gcc_sm8650_exit); +subsys_platform_driver(gcc_sm8650_driver); MODULE_DESCRIPTION("QTI GCC SM8650 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-sm8750.c b/drivers/clk/qcom/gcc-sm8750.c index 6cfe90122268..80b8ec119c55 100644 --- a/drivers/clk/qcom/gcc-sm8750.c +++ b/drivers/clk/qcom/gcc-sm8750.c @@ -3188,7 +3188,39 @@ static const struct regmap_config gcc_sm8750_regmap_config = { .fast_io = true, }; +static const u32 gcc_sm8750_critical_cbcrs[] = { + 0xa0004, /* GCC_CAM_BIST_MCLK_AHB_CLK */ + 0x26004, /* GCC_CAMERA_AHB_CLK */ + 0x26034, /* GCC_CAMERA_XO_CLK */ + 0x27004, /* GCC_DISP_AHB_CLK */ + 0x9f004, /* GCC_EVA_AHB_CLK */ + 0x9f01c, /* GCC_EVA_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0x32004, /* GCC_VIDEO_AHB_CLK */ + 0x32038, /* GCC_VIDEO_XO_CLK */ +}; + +static void gcc_sm8750_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Keep GCC_PCIE_RSCC_CFG_AHB_CLK and GCC_PCIE_RSCC_XO_CLK enabled. */ + regmap_update_bits(regmap, 0x52010, BIT(20), BIT(20)); + regmap_update_bits(regmap, 0x52010, BIT(21), BIT(21)); + + /* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true); +} + +static const struct qcom_cc_driver_data gcc_sm8750_driver_data = { + .clk_cbcrs = gcc_sm8750_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_sm8750_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_sm8750_regs_configure, +}; + static const struct qcom_cc_desc gcc_sm8750_desc = { + .driver_data = &gcc_sm8750_driver_data, .config = &gcc_sm8750_regmap_config, .clks = gcc_sm8750_clocks, .num_clks = ARRAY_SIZE(gcc_sm8750_clocks), @@ -3196,6 +3228,7 @@ static const struct qcom_cc_desc gcc_sm8750_desc = { .num_resets = ARRAY_SIZE(gcc_sm8750_resets), .gdscs = gcc_sm8750_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sm8750_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_sm8750_match_table[] = { @@ -3206,49 +3239,7 @@ MODULE_DEVICE_TABLE(of, gcc_sm8750_match_table); static int gcc_sm8750_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_sm8750_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - /* - * Keep clocks always enabled: - * gcc_cam_bist_mclk_ahb_clk - * gcc_camera_ahb_clk - * gcc_camera_xo_clk - * gcc_disp_ahb_clk - * gcc_eva_ahb_clk - * gcc_eva_xo_clk - * gcc_gpu_cfg_ahb_clk - * gcc_video_ahb_clk - * gcc_video_xo_clk - * gcc_pcie_rscc_cfg_ahb_clk - * gcc_pcie_rscc_xo_clk - */ - qcom_branch_set_clk_en(regmap, 0xa0004); - qcom_branch_set_clk_en(regmap, 0x26004); - qcom_branch_set_clk_en(regmap, 0x26034); - qcom_branch_set_clk_en(regmap, 0x27004); - qcom_branch_set_clk_en(regmap, 0x9f004); - qcom_branch_set_clk_en(regmap, 0x9f01c); - qcom_branch_set_clk_en(regmap, 0x71004); - qcom_branch_set_clk_en(regmap, 0x32004); - qcom_branch_set_clk_en(regmap, 0x32038); - regmap_update_bits(regmap, 0x52010, BIT(20), BIT(20)); - regmap_update_bits(regmap, 0x52010, BIT(21), BIT(21)); - - /* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks */ - qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); - qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true); - - return qcom_cc_really_probe(&pdev->dev, &gcc_sm8750_desc, regmap); + return qcom_cc_probe(pdev, &gcc_sm8750_desc); } static struct platform_driver gcc_sm8750_driver = { @@ -3259,17 +3250,7 @@ static struct platform_driver gcc_sm8750_driver = { }, }; -static int __init gcc_sm8750_init(void) -{ - return platform_driver_register(&gcc_sm8750_driver); -} -subsys_initcall(gcc_sm8750_init); - -static void __exit gcc_sm8750_exit(void) -{ - platform_driver_unregister(&gcc_sm8750_driver); -} -module_exit(gcc_sm8750_exit); +subsys_platform_driver(gcc_sm8750_driver); MODULE_DESCRIPTION("QTI GCC SM8750 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index 8c146d62c077..3411ecb0225c 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -6049,7 +6049,7 @@ static struct clk_branch gcc_usb4_0_sb_if_clk = { static struct clk_branch gcc_usb4_0_sys_clk = { .halt_reg = 0x9f054, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9f054, .enable_mask = BIT(0), @@ -6266,7 +6266,7 @@ static struct clk_branch gcc_usb4_1_sb_if_clk = { static struct clk_branch gcc_usb4_1_sys_clk = { .halt_reg = 0x2b054, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b054, .enable_mask = BIT(0), @@ -6483,7 +6483,7 @@ static struct clk_branch gcc_usb4_2_sb_if_clk = { static struct clk_branch gcc_usb4_2_sys_clk = { .halt_reg = 0x11054, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x11054, .enable_mask = BIT(0), @@ -7441,7 +7441,37 @@ static const struct regmap_config gcc_x1e80100_regmap_config = { .fast_io = true, }; +static const u32 gcc_x1e80100_critical_cbcrs[] = { + 0x26004, /* GCC_CAMERA_AHB_CLK */ + 0x26028, /* GCC_CAMERA_XO_CLK */ + 0x27004, /* GCC_DISP_AHB_CLK */ + 0x27018, /* GCC_DISP_XO_CLK */ + 0x32004, /* GCC_VIDEO_AHB_CLK */ + 0x32030, /* GCC_VIDEO_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0x7d01c, /* GCC_HLOS1_VOTE_AGGRE_NOC_MMU_USB_QTB_CLK */ +}; + +static void gcc_x1e80100_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */ + regmap_write(regmap, 0x52224, 0x0); + + /* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true); +} + +static const struct qcom_cc_driver_data gcc_x1e80100_driver_data = { + .clk_cbcrs = gcc_x1e80100_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_x1e80100_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = gcc_x1e80100_regs_configure, +}; + static const struct qcom_cc_desc gcc_x1e80100_desc = { + .driver_data = &gcc_x1e80100_driver_data, .config = &gcc_x1e80100_regmap_config, .clks = gcc_x1e80100_clocks, .num_clks = ARRAY_SIZE(gcc_x1e80100_clocks), @@ -7449,6 +7479,7 @@ static const struct qcom_cc_desc gcc_x1e80100_desc = { .num_resets = ARRAY_SIZE(gcc_x1e80100_resets), .gdscs = gcc_x1e80100_gdscs, .num_gdscs = ARRAY_SIZE(gcc_x1e80100_gdscs), + .use_rpm = true, }; static const struct of_device_id gcc_x1e80100_match_table[] = { @@ -7459,36 +7490,7 @@ MODULE_DEVICE_TABLE(of, gcc_x1e80100_match_table); static int gcc_x1e80100_probe(struct platform_device *pdev) { - struct regmap *regmap; - int ret; - - regmap = qcom_cc_map(pdev, &gcc_x1e80100_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, - ARRAY_SIZE(gcc_dfs_clocks)); - if (ret) - return ret; - - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x26004); /* GCC_CAMERA_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x26028); /* GCC_CAMERA_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x27004); /* GCC_DISP_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x27018); /* GCC_DISP_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x32004); /* GCC_VIDEO_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x32030); /* GCC_VIDEO_XO_CLK */ - qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x7d01c); /* GCC_HLOS1_VOTE_AGGRE_NOC_MMU_USB_QTB_CLK */ - - /* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */ - regmap_write(regmap, 0x52224, 0x0); - - /* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks */ - qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); - qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true); - - return qcom_cc_really_probe(&pdev->dev, &gcc_x1e80100_desc, regmap); + return qcom_cc_probe(pdev, &gcc_x1e80100_desc); } static struct platform_driver gcc_x1e80100_driver = { @@ -7499,17 +7501,7 @@ static struct platform_driver gcc_x1e80100_driver = { }, }; -static int __init gcc_x1e80100_init(void) -{ - return platform_driver_register(&gcc_x1e80100_driver); -} -subsys_initcall(gcc_x1e80100_init); - -static void __exit gcc_x1e80100_exit(void) -{ - platform_driver_unregister(&gcc_x1e80100_driver); -} -module_exit(gcc_x1e80100_exit); +subsys_platform_driver(gcc_x1e80100_driver); MODULE_DESCRIPTION("QTI GCC X1E80100 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gpucc-eliza.c b/drivers/clk/qcom/gpucc-eliza.c new file mode 100644 index 000000000000..57a28502f325 --- /dev/null +++ b/drivers/clk/qcom/gpucc-eliza.c @@ -0,0 +1,606 @@ +// 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_BI_TCXO_AO, + 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 }, +}; + +/* 518.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x1a, + .alpha = 0xfaaa, + .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 = 0x00000005, +}; + +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, + }, + }, +}; + +/* 440.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x16, + .alpha = 0xeaaa, + .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 = 0x00000005, +}; + +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 parent_map gpu_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, +}; + +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 = 0x94b8, + .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(220000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(550000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x935c, + .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 struct clk_rcg2 gpu_cc_hub_clk_src = { + .cmd_rcgr = 0x9430, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_2, + .freq_tbl = ftbl_gpu_cc_ff_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 const struct freq_tbl ftbl_gpu_cc_xo_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_xo_clk_src = { + .cmd_rcgr = 0x9010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_3, + .freq_tbl = ftbl_gpu_cc_xo_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_xo_clk_src", + .parent_data = gpu_cc_parent_data_3, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_3), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div gpu_cc_xo_div_clk_src = { + .reg = 0x9050, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_xo_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gpu_cc_ahb_clk = { + .halt_reg = 0x914c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x914c, + .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_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 = 0x9150, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9150, + .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_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 = 0x9480, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9480, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_accu_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .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", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .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", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_xo_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_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_hlos1_vote_gpu_smmu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_aon_clk = { + .halt_reg = 0x942c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x942c, + .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_0_gfx3d_clk = { + .halt_reg = 0x92cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x92cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_mnd1x_0_gfx3d_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_mnd1x_1_gfx3d_clk = { + .halt_reg = 0x92d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x92d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_mnd1x_1_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 = 0x9110, + .gds_hw_ctrl = 0x9124, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x8, + .pd = { + .name = "gpu_cc_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE, +}; + +static struct gdsc gpu_cc_gx_gdsc = { + .gdscr = 0x905c, + .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 = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gpu_cc_eliza_clocks[] = { + [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_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_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_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_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr, + [GPU_CC_MND1X_0_GFX3D_CLK] = &gpu_cc_mnd1x_0_gfx3d_clk.clkr, + [GPU_CC_MND1X_1_GFX3D_CLK] = &gpu_cc_mnd1x_1_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, + [GPU_CC_XO_CLK_SRC] = &gpu_cc_xo_clk_src.clkr, + [GPU_CC_XO_DIV_CLK_SRC] = &gpu_cc_xo_div_clk_src.clkr, +}; + +static struct gdsc *gpu_cc_eliza_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_eliza_resets[] = { + [GPU_CC_ACD_BCR] = { 0x939c }, + [GPU_CC_CB_BCR] = { 0x93e4 }, + [GPU_CC_CX_BCR] = { 0x910c }, + [GPU_CC_FAST_HUB_BCR] = { 0x9428 }, + [GPU_CC_FF_BCR] = { 0x94b4 }, + [GPU_CC_GFX3D_AON_BCR] = { 0x91dc }, + [GPU_CC_GMU_BCR] = { 0x9358 }, + [GPU_CC_GX_BCR] = { 0x9058 }, + [GPU_CC_RBCPR_BCR] = { 0x9224 }, + [GPU_CC_XO_BCR] = { 0x9000 }, +}; + +static struct clk_alpha_pll *gpu_cc_eliza_plls[] = { + &gpu_cc_pll0, + &gpu_cc_pll1, +}; + +static const u32 gpu_cc_eliza_critical_cbcrs[] = { + 0x9004, /* GPU_CC_CXO_AON_CLK */ + 0x900c, /* GPU_CC_DEMET_CLK */ +}; + +static const struct regmap_config gpu_cc_eliza_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9988, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data gpu_cc_eliza_driver_data = { + .alpha_plls = gpu_cc_eliza_plls, + .num_alpha_plls = ARRAY_SIZE(gpu_cc_eliza_plls), + .clk_cbcrs = gpu_cc_eliza_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_eliza_critical_cbcrs), +}; + +static const struct qcom_cc_desc gpu_cc_eliza_desc = { + .config = &gpu_cc_eliza_regmap_config, + .clks = gpu_cc_eliza_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_eliza_clocks), + .resets = gpu_cc_eliza_resets, + .num_resets = ARRAY_SIZE(gpu_cc_eliza_resets), + .gdscs = gpu_cc_eliza_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_eliza_gdscs), + .use_rpm = true, + .driver_data = &gpu_cc_eliza_driver_data, +}; + +static const struct of_device_id gpu_cc_eliza_match_table[] = { + { .compatible = "qcom,eliza-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_eliza_match_table); + +static int gpu_cc_eliza_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gpu_cc_eliza_desc); +} + +static struct platform_driver gpu_cc_eliza_driver = { + .probe = gpu_cc_eliza_probe, + .driver = { + .name = "gpucc-eliza", + .of_match_table = gpu_cc_eliza_match_table, + }, +}; + +module_platform_driver(gpu_cc_eliza_driver); + +MODULE_DESCRIPTION("QTI GPUCC Eliza Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gpucc-hawi.c b/drivers/clk/qcom/gpucc-hawi.c new file mode 100644 index 000000000000..3deb7edf7810 --- /dev/null +++ b/drivers/clk/qcom/gpucc-hawi.c @@ -0,0 +1,477 @@ +// 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_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_EVEN, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL0_OUT_ODD, +}; + +static const struct pll_vco taycan_eha_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 788.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x29, + .alpha = 0xaaa, + .config_ctl_val = 0xa5c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +/* 788.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll0_config_maili = { + .l = 0x29, + .cal_l = 0x42, + .alpha = 0xaaa, + .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 gpu_cc_pll0 = { + .offset = 0x0, + .config = &gpu_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 = "gpu_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 parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL0_OUT_EVEN, 2 }, + { P_GPU_CC_PLL0_OUT_ODD, 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_pll0.clkr.hw }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(788000000, P_GPU_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(825000000, P_GPU_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(880000000, P_GPU_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(917000000, P_GPU_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x9318, + .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(150000000, P_GPLL0_OUT_MAIN_DIV, 2, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_hub_clk_src = { + .cmd_rcgr = 0x93f0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_1, + .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_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div gpu_cc_hub_div_clk_src = { + .reg = 0x9430, + .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_ahb_clk = { + .halt_reg = 0x90bc, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x90bc, + .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_cx_accu_shift_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_cc_cx_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gmu_clk = { + .halt_reg = 0x90d4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x90d4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x90d4, + .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_demet_clk = { + .halt_reg = 0x9010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_demet_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_dpm_clk = { + .halt_reg = 0x9108, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9108, + .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 = 0x900c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x900c, + .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_gx_accu_shift_clk = { + .halt_reg = 0x9070, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_aon_clk = { + .halt_reg = 0x93ec, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x93ec, + .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 = 0x90e8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x90e8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x90e8, + .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 = 0x90ec, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x90ec, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x90ec, + .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_mxg_ahb_clk = { + .halt_reg = 0x9744, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9744, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_mxg_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 gdsc gpu_cc_cx_gdsc = { + .gdscr = 0x9080, + .gds_hw_ctrl = 0x9094, + .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 | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gpu_cc_mxg_gdsc = { + .gdscr = 0x961c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gpu_cc_mxg_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gpu_cc_hawi_clocks[] = { + [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, + [GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr, + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_DEMET_CLK] = &gpu_cc_demet_clk.clkr, + [GPU_CC_DPM_CLK] = &gpu_cc_dpm_clk.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_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_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_MXG_AHB_CLK] = &gpu_cc_mxg_ahb_clk.clkr, + [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, +}; + +static struct gdsc *gpu_cc_hawi_gdscs[] = { + [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc, + [GPU_CC_MXG_GDSC] = &gpu_cc_mxg_gdsc, +}; + +static const struct qcom_reset_map gpu_cc_hawi_resets[] = { + [GPU_CC_CB_BCR] = { 0x93a0 }, + [GPU_CC_CX_BCR] = { 0x907c }, + [GPU_CC_FAST_HUB_BCR] = { 0x93e4 }, + [GPU_CC_GMU_BCR] = { 0x9314 }, + [GPU_CC_GX_BCR] = { 0x905c }, + [GPU_CC_MXG_BCR] = { 0x9618 }, + [GPU_CC_XO_BCR] = { 0x9000 }, +}; + +static struct clk_alpha_pll *gpu_cc_hawi_plls[] = { + &gpu_cc_pll0, +}; + +static u32 gpu_cc_hawi_critical_cbcrs[] = { + 0x93a4, /* GPU_CC_CB_CLK */ + 0x9704, /* GPU_CC_MXG_XO_CLK */ + 0x90e4, /* GPU_CC_CXO_CLK */ + 0x9008, /* GPU_CC_CXO_AON_CLK */ + 0x93e8, /* GPU_CC_RSCC_HUB_AON_CLK */ + 0x9004, /* GPU_CC_RSCC_XO_AON_CLK */ + 0x90cc, /* GPU_CC_SLEEP_CLK */ +}; + +static const struct regmap_config gpu_cc_hawi_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9744, + .fast_io = true, +}; + +static struct qcom_cc_driver_data gpu_cc_hawi_driver_data = { + .alpha_plls = gpu_cc_hawi_plls, + .num_alpha_plls = ARRAY_SIZE(gpu_cc_hawi_plls), + .clk_cbcrs = gpu_cc_hawi_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_hawi_critical_cbcrs), +}; + +static const struct qcom_cc_desc gpu_cc_hawi_desc = { + .config = &gpu_cc_hawi_regmap_config, + .clks = gpu_cc_hawi_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_hawi_clocks), + .resets = gpu_cc_hawi_resets, + .num_resets = ARRAY_SIZE(gpu_cc_hawi_resets), + .gdscs = gpu_cc_hawi_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_hawi_gdscs), + .use_rpm = true, + .driver_data = &gpu_cc_hawi_driver_data, +}; + +static const struct of_device_id gpu_cc_hawi_match_table[] = { + { .compatible = "qcom,hawi-gpucc" }, + { .compatible = "qcom,maili-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_hawi_match_table); + +static int gpu_cc_hawi_probe(struct platform_device *pdev) +{ + if (device_is_compatible(&pdev->dev, "qcom,maili-gpucc")) + gpu_cc_pll0.config = &gpu_cc_pll0_config_maili; + + return qcom_cc_probe(pdev, &gpu_cc_hawi_desc); +} + +static struct platform_driver gpu_cc_hawi_driver = { + .probe = gpu_cc_hawi_probe, + .driver = { + .name = "gpucc-hawi", + .of_match_table = gpu_cc_hawi_match_table, + }, +}; + +module_platform_driver(gpu_cc_hawi_driver); + +MODULE_DESCRIPTION("QTI GPUCC HAWI Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gpucc-sar2130p.c b/drivers/clk/qcom/gpucc-sar2130p.c index dd72b2a48c42..fa261664c1bf 100644 --- a/drivers/clk/qcom/gpucc-sar2130p.c +++ b/drivers/clk/qcom/gpucc-sar2130p.c @@ -455,7 +455,17 @@ static const struct regmap_config gpu_cc_sar2130p_regmap_config = { .fast_io = true, }; +static const u32 gpu_cc_sar2130p_critical_cbcrs[] = { + 0x900c, /* GPU_CC_DEMET_CLK */ +}; + +static const struct qcom_cc_driver_data gpu_cc_sar2130p_driver_data = { + .clk_cbcrs = gpu_cc_sar2130p_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_sar2130p_critical_cbcrs), +}; + static const struct qcom_cc_desc gpu_cc_sar2130p_desc = { + .driver_data = &gpu_cc_sar2130p_driver_data, .config = &gpu_cc_sar2130p_regmap_config, .clks = gpu_cc_sar2130p_clocks, .num_clks = ARRAY_SIZE(gpu_cc_sar2130p_clocks), @@ -483,9 +493,6 @@ static int gpu_cc_sar2130p_probe(struct platform_device *pdev) clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x900c); /* GPU_CC_DEMET_CLK */ - return qcom_cc_really_probe(dev, &gpu_cc_sar2130p_desc, regmap); } diff --git a/drivers/clk/qcom/gpucc-sc7280.c b/drivers/clk/qcom/gpucc-sc7280.c index bd699a624517..9b267276eac7 100644 --- a/drivers/clk/qcom/gpucc-sc7280.c +++ b/drivers/clk/qcom/gpucc-sc7280.c @@ -440,7 +440,24 @@ static const struct regmap_config gpu_cc_sc7280_regmap_config = { .fast_io = true, }; +static const u32 gpu_cc_sc7280_critical_cbcrs[] = { + 0x1170, /* GPU_CC_CB_CLK */ + 0x1098, /* GPUCC_CX_GMU_CLK */ +}; + +static void gpu_cc_sc7280_regs_configure(struct device *dev, struct regmap *regmap) +{ + regmap_update_bits(regmap, 0x1098, BIT(13), BIT(13)); +} + +static const struct qcom_cc_driver_data gpu_cc_sc7280_driver_data = { + .clk_cbcrs = gpu_cc_sc7280_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_sc7280_critical_cbcrs), + .clk_regs_configure = gpu_cc_sc7280_regs_configure, +}; + static const struct qcom_cc_desc gpu_cc_sc7280_desc = { + .driver_data = &gpu_cc_sc7280_driver_data, .config = &gpu_cc_sc7280_regmap_config, .clks = gpu_cc_sc7280_clocks, .num_clks = ARRAY_SIZE(gpu_cc_sc7280_clocks), @@ -464,11 +481,6 @@ static int gpu_cc_sc7280_probe(struct platform_device *pdev) clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x1170); /* GPU_CC_CB_CLK */ - qcom_branch_set_clk_en(regmap, 0x1098); /* GPUCC_CX_GMU_CLK */ - regmap_update_bits(regmap, 0x1098, BIT(13), BIT(13)); - return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sc7280_desc, regmap); } diff --git a/drivers/clk/qcom/gpucc-sc8280xp.c b/drivers/clk/qcom/gpucc-sc8280xp.c index 5dd90b854afb..2ccc083a4f98 100644 --- a/drivers/clk/qcom/gpucc-sc8280xp.c +++ b/drivers/clk/qcom/gpucc-sc8280xp.c @@ -415,7 +415,18 @@ static const struct regmap_config gpu_cc_sc8280xp_regmap_config = { .fast_io = true, }; +static const u32 gpu_cc_sc8280xp_critical_cbcrs[] = { + 0x1170, /* GPU_CC_CB_CLK */ + 0x109c, /* GPU_CC_CXO_CLK */ +}; + +static const struct qcom_cc_driver_data gpu_cc_sc8280xp_driver_data = { + .clk_cbcrs = gpu_cc_sc8280xp_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_sc8280xp_critical_cbcrs), +}; + static const struct qcom_cc_desc gpu_cc_sc8280xp_desc = { + .driver_data = &gpu_cc_sc8280xp_driver_data, .config = &gpu_cc_sc8280xp_regmap_config, .clks = gpu_cc_sc8280xp_clocks, .num_clks = ARRAY_SIZE(gpu_cc_sc8280xp_clocks), @@ -445,10 +456,6 @@ static int gpu_cc_sc8280xp_probe(struct platform_device *pdev) clk_lucid_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x1170); /* GPU_CC_CB_CLK */ - qcom_branch_set_clk_en(regmap, 0x109c); /* GPU_CC_CXO_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &gpu_cc_sc8280xp_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/gpucc-sm4450.c b/drivers/clk/qcom/gpucc-sm4450.c index 808b1eaa59d1..bd0f3fc2b726 100644 --- a/drivers/clk/qcom/gpucc-sm4450.c +++ b/drivers/clk/qcom/gpucc-sm4450.c @@ -754,7 +754,19 @@ static const struct regmap_config gpu_cc_sm4450_regmap_config = { .fast_io = true, }; +static const u32 gpu_cc_sm4450_critical_cbcrs[] = { + 0x93a4, /* GPU_CC_CB_CLK */ + 0x9004, /* GPU_CC_CXO_AON_CLK */ + 0x900c, /* GPU_CC_DEMET_CLK */ +}; + +static const struct qcom_cc_driver_data gpu_cc_sm4450_driver_data = { + .clk_cbcrs = gpu_cc_sm4450_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_sm4450_critical_cbcrs), +}; + static const struct qcom_cc_desc gpu_cc_sm4450_desc = { + .driver_data = &gpu_cc_sm4450_driver_data, .config = &gpu_cc_sm4450_regmap_config, .clks = gpu_cc_sm4450_clocks, .num_clks = ARRAY_SIZE(gpu_cc_sm4450_clocks), @@ -781,11 +793,6 @@ static int gpu_cc_sm4450_probe(struct platform_device *pdev) clk_lucid_evo_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - /* Keep some clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0x93a4); /* GPU_CC_CB_CLK */ - qcom_branch_set_clk_en(regmap, 0x9004); /* GPU_CC_CXO_AON_CLK */ - qcom_branch_set_clk_en(regmap, 0x900c); /* GPU_CC_DEMET_CLK */ - return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm4450_desc, regmap); } diff --git a/drivers/clk/qcom/gpucc-sm8550.c b/drivers/clk/qcom/gpucc-sm8550.c index 53614e980b26..f8dd1727c080 100644 --- a/drivers/clk/qcom/gpucc-sm8550.c +++ b/drivers/clk/qcom/gpucc-sm8550.c @@ -547,7 +547,18 @@ static const struct regmap_config gpu_cc_sm8550_regmap_config = { .fast_io = true, }; +static const u32 gpu_cc_sm8550_critical_cbcrs[] = { + 0x9004, /* GPU_CC_CXO_AON_CLK */ + 0x900c, /* GPU_CC_DEMET_CLK */ +}; + +static const struct qcom_cc_driver_data gpu_cc_sm8550_driver_data = { + .clk_cbcrs = gpu_cc_sm8550_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_sm8550_critical_cbcrs), +}; + static const struct qcom_cc_desc gpu_cc_sm8550_desc = { + .driver_data = &gpu_cc_sm8550_driver_data, .config = &gpu_cc_sm8550_regmap_config, .clks = gpu_cc_sm8550_clocks, .num_clks = ARRAY_SIZE(gpu_cc_sm8550_clocks), @@ -574,10 +585,6 @@ static int gpu_cc_sm8550_probe(struct platform_device *pdev) clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x9004); /* GPU_CC_CXO_AON_CLK */ - qcom_branch_set_clk_en(regmap, 0x900c); /* GPU_CC_DEMET_CLK */ - return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8550_desc, regmap); } diff --git a/drivers/clk/qcom/gpucc-x1e80100.c b/drivers/clk/qcom/gpucc-x1e80100.c index f9161dbaedd7..10a0b11927e3 100644 --- a/drivers/clk/qcom/gpucc-x1e80100.c +++ b/drivers/clk/qcom/gpucc-x1e80100.c @@ -609,7 +609,17 @@ static const struct regmap_config gpu_cc_x1e80100_regmap_config = { .fast_io = true, }; +static const u32 gpu_cc_x1e80100_critical_cbcrs[] = { + 0x93a4, /* GPU_CC_CB_CLK */ +}; + +static const struct qcom_cc_driver_data gpu_cc_x1e80100_driver_data = { + .clk_cbcrs = gpu_cc_x1e80100_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_x1e80100_critical_cbcrs), +}; + static const struct qcom_cc_desc gpu_cc_x1e80100_desc = { + .driver_data = &gpu_cc_x1e80100_driver_data, .config = &gpu_cc_x1e80100_regmap_config, .clks = gpu_cc_x1e80100_clocks, .num_clks = ARRAY_SIZE(gpu_cc_x1e80100_clocks), @@ -636,9 +646,6 @@ static int gpu_cc_x1e80100_probe(struct platform_device *pdev) clk_zonda_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - /* Keep clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0x93a4); /* GPU_CC_CB_CLK */ - return qcom_cc_really_probe(&pdev->dev, &gpu_cc_x1e80100_desc, regmap); } diff --git a/drivers/clk/qcom/gpucc-x1p42100.c b/drivers/clk/qcom/gpucc-x1p42100.c index cfc34e0fd290..3f3fec257f2d 100644 --- a/drivers/clk/qcom/gpucc-x1p42100.c +++ b/drivers/clk/qcom/gpucc-x1p42100.c @@ -522,7 +522,19 @@ static const struct regmap_config gpu_cc_x1p42100_regmap_config = { .fast_io = true, }; +static const u32 gpu_cc_x1p42100_critical_cbcrs[] = { + 0x93a4, /* GPU_CC_CB_CLK */ + 0x9004, /* GPU_CC_CXO_AON_CLK */ + 0x900c, /* GPU_CC_DEMET_CLK */ +}; + +static const struct qcom_cc_driver_data gpu_cc_x1p42100_driver_data = { + .clk_cbcrs = gpu_cc_x1p42100_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_x1p42100_critical_cbcrs), +}; + static const struct qcom_cc_desc gpu_cc_x1p42100_desc = { + .driver_data = &gpu_cc_x1p42100_driver_data, .config = &gpu_cc_x1p42100_regmap_config, .clks = gpu_cc_x1p42100_clocks, .num_clks = ARRAY_SIZE(gpu_cc_x1p42100_clocks), @@ -560,11 +572,6 @@ static int gpu_cc_x1p42100_probe(struct platform_device *pdev) clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - /* Keep some clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0x93a4); /* GPU_CC_CB_CLK */ - qcom_branch_set_clk_en(regmap, 0x9004); /* GPU_CC_CXO_AON_CLK */ - qcom_branch_set_clk_en(regmap, 0x900c); /* GPU_CC_DEMET_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &gpu_cc_x1p42100_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/ipq-cmn-pll.c b/drivers/clk/qcom/ipq-cmn-pll.c index dafe8c1738df..74a2043632b7 100644 --- a/drivers/clk/qcom/ipq-cmn-pll.c +++ b/drivers/clk/qcom/ipq-cmn-pll.c @@ -44,6 +44,7 @@ */ #include +#include #include #include #include @@ -55,17 +56,31 @@ #include #include +#include #include #include #include #include +#include "clk-regmap.h" +#include "clk-regmap-divider.h" + #define CMN_PLL_REFCLK_SRC_SELECTION 0x28 #define CMN_PLL_REFCLK_SRC_DIV GENMASK(9, 8) #define CMN_PLL_LOCKED 0x64 #define CMN_PLL_CLKS_LOCKED BIT(8) +#define CMN_PLL_NSS_PPE_FREQ_CTRL 0x98 +#define CMN_PLL_NSS_CLK_SEL GENMASK(13, 8) +#define CMN_PLL_PPE_CLK_SEL GENMASK(5, 0) + +#define CMN_PLL_PON_CONFIG 0x42c +#define CMN_PLL_PON_MODE_SEL BIT(9) +#define CMN_PLL_PON_EN BIT(8) +#define CMN_PLL_PON_DIV_CTRL GENMASK(7, 0) +#define CMN_PLL_GEPHY_312P5M_125M_SEL BIT(10) + #define CMN_PLL_POWER_ON_AND_RESET 0x780 #define CMN_ANA_EN_SW_RSTN BIT(6) @@ -80,36 +95,110 @@ #define CMN_PLL_DIVIDER_CTRL 0x794 #define CMN_PLL_DIVIDER_CTRL_FACTOR GENMASK(9, 0) +/* Clock gate enable bits. */ +#define CMN_PLL_OUTPUT_RELATED_1 0x79c +#define CLK25M_EN_BIT 15 +#define CLK50M_EN_BIT3 14 +/* Documented as CLK250M_EN in the register description; gates ephy-50mhz. */ +#define CLK250M_EN_BIT 13 +#define CLK31P25M_EN_BIT 12 +#define CLK50M_EN_BIT1 11 +#define CLK50M_EN_BIT2 10 + +/** + * enum cmn_pll_clk_type - CMN PLL output clock registration type + * @CMN_PLL_CLK_FIXED_RATE: plain fixed rate clock + * @CMN_PLL_CLK_FIXED_GATE: fixed rate clock with a hardware gate + * @CMN_PLL_CLK_NSS: NSS clock with configurable divider + * @CMN_PLL_CLK_PPE: PPE clock with configurable divider + * @CMN_PLL_CLK_PON: PON reference clock + * @CMN_PLL_CLK_EPHY_RAW: EPHY-RAW clock + */ +enum cmn_pll_clk_type { + CMN_PLL_CLK_FIXED_RATE, + CMN_PLL_CLK_FIXED_GATE, + CMN_PLL_CLK_NSS, + CMN_PLL_CLK_PPE, + CMN_PLL_CLK_PON, + CMN_PLL_CLK_EPHY_RAW, +}; + /** * struct cmn_pll_fixed_output_clk - CMN PLL output clocks information * @id: Clock specifier to be supplied * @name: Clock name to be registered + * @type: Clock registration type * @rate: Clock rate + * @enable_bit: Enable bit in CMN_PLL_OUTPUT_RELATED_1 for gate clock, + * -1 for non-gated clocks. */ struct cmn_pll_fixed_output_clk { unsigned int id; const char *name; + enum cmn_pll_clk_type type; unsigned long rate; + int enable_bit; }; /** * struct clk_cmn_pll - CMN PLL hardware specific data * @regmap: hardware regmap. * @hw: handle between common and hardware-specific interfaces + * @div2_hw: fixed /2 clock derived from the CMN PLL output; present on + * every supported SoC. */ struct clk_cmn_pll { struct regmap *regmap; struct clk_hw hw; + struct clk_hw *div2_hw; }; -#define CLK_PLL_OUTPUT(_id, _name, _rate) { \ - .id = _id, \ - .name = _name, \ - .rate = _rate, \ +/** + * struct clk_fixed_gate - fixed rate clock with a hardware gate + * @clkr: handle between common and hardware-specific interfaces; its + * enable_reg/enable_mask are set to CMN_PLL_OUTPUT_RELATED_1 and + * this clock's gate bit, and reused via clk_enable_regmap() and + * friends. That register is shared across multiple gate clocks, + * but regmap already serializes read-modify-write access to a + * given register, so no additional locking is needed here. + * @rate: fixed clock rate. + */ +struct clk_fixed_gate { + struct clk_regmap clkr; + unsigned long rate; +}; + +#define CLK_PLL_OUTPUT_RAW(_id, _name, _type, _rate, _bit) { \ + .id = _id, \ + .name = _name, \ + .type = _type, \ + .rate = _rate, \ + .enable_bit = _bit, \ } +#define CLK_PLL_OUTPUT(_id, _name, _rate) \ + CLK_PLL_OUTPUT_RAW(_id, _name, CMN_PLL_CLK_FIXED_RATE, _rate, -1) + +#define CLK_PLL_GATE(_id, _name, _rate, _bit) \ + CLK_PLL_OUTPUT_RAW(_id, _name, CMN_PLL_CLK_FIXED_GATE, _rate, _bit) + +#define CLK_PLL_NSS(_id, _name) \ + CLK_PLL_OUTPUT_RAW(_id, _name, CMN_PLL_CLK_NSS, 0, -1) + +#define CLK_PLL_PPE(_id, _name) \ + CLK_PLL_OUTPUT_RAW(_id, _name, CMN_PLL_CLK_PPE, 0, -1) + +#define CLK_PLL_PON(_id, _name) \ + CLK_PLL_OUTPUT_RAW(_id, _name, CMN_PLL_CLK_PON, 0, -1) + +#define CLK_PLL_EPHY_RAW(_id, _name) \ + CLK_PLL_OUTPUT_RAW(_id, _name, CMN_PLL_CLK_EPHY_RAW, 0, -1) + #define to_clk_cmn_pll(_hw) container_of(_hw, struct clk_cmn_pll, hw) +#define to_clk_fixed_gate(_hw) \ + container_of(to_clk_regmap(_hw), struct clk_fixed_gate, clkr) + static const struct regmap_config ipq_cmn_pll_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -124,6 +213,22 @@ static const struct cmn_pll_fixed_output_clk ipq5018_output_clks[] = { { /* Sentinel */ } }; +static const struct cmn_pll_fixed_output_clk ipq5210_output_clks[] = { + CLK_PLL_OUTPUT(IPQ5210_XO_24MHZ_CLK, "xo-24mhz", 24000000UL), + CLK_PLL_OUTPUT(IPQ5210_SLEEP_32KHZ_CLK, "sleep-32khz", 32000UL), + CLK_PLL_GATE(IPQ5210_PCS_31P25MHZ_CLK, "pcs-31p25mhz", 31250000UL, CLK31P25M_EN_BIT), + CLK_PLL_GATE(IPQ5210_ETH0_50MHZ_CLK, "eth0-50mhz", 50000000UL, CLK50M_EN_BIT1), + CLK_PLL_GATE(IPQ5210_ETH1_50MHZ_CLK, "eth1-50mhz", 50000000UL, CLK50M_EN_BIT2), + CLK_PLL_GATE(IPQ5210_ETH2_50MHZ_CLK, "eth2-50mhz", 50000000UL, CLK50M_EN_BIT3), + CLK_PLL_GATE(IPQ5210_EPHY_50MHZ_CLK, "ephy-50mhz", 50000000UL, CLK250M_EN_BIT), + CLK_PLL_GATE(IPQ5210_ETH_25MHZ_CLK, "eth-25mhz", 25000000UL, CLK25M_EN_BIT), + CLK_PLL_NSS(IPQ5210_NSS_CLK, "nss"), + CLK_PLL_PPE(IPQ5210_PPE_CLK, "ppe"), + CLK_PLL_PON(IPQ5210_PON_CLK, "pon"), + CLK_PLL_EPHY_RAW(IPQ5210_EPHY_RAW_CLK, "ephy-raw"), + { /* Sentinel */ } +}; + static const struct cmn_pll_fixed_output_clk ipq6018_output_clks[] = { CLK_PLL_OUTPUT(IPQ6018_BIAS_PLL_CC_CLK, "bias_pll_cc_clk", 300000000UL), CLK_PLL_OUTPUT(IPQ6018_BIAS_PLL_NSS_NOC_CLK, "bias_pll_nss_noc_clk", 416500000UL), @@ -357,11 +462,350 @@ static struct clk_hw *ipq_cmn_pll_clk_hw_register(struct platform_device *pdev) return &cmn_pll->hw; } +static struct clk_hw *ipq_cmn_pll_regmap_div_register(struct device *dev, + const char *name, + struct clk_hw *parent_hw, + u32 field_mask) +{ + struct clk_parent_data pdata = { .hw = parent_hw }; + struct clk_regmap_div *div_clk; + int ret; + + div_clk = devm_kzalloc(dev, sizeof(*div_clk), GFP_KERNEL); + if (!div_clk) + return ERR_PTR(-ENOMEM); + + div_clk->reg = CMN_PLL_NSS_PPE_FREQ_CTRL; + div_clk->shift = __ffs(field_mask); + div_clk->width = hweight32(field_mask); + /* + * CMN_PLL_NSS_CLK_SEL / CMN_PLL_PPE_CLK_SEL reset to a valid, non-zero + * divider in hardware. CLK_DIVIDER_ALLOW_ZERO is deliberately not set: + * a divider field read back as 0 is genuinely invalid and should trip + * the core clk-divider's zero-divisor WARN rather than be silently + * tolerated. + */ + div_clk->flags = CLK_DIVIDER_ONE_BASED; + div_clk->clkr.hw.init = &(struct clk_init_data){ + .name = name, + .parent_data = &pdata, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }; + + ret = devm_clk_register_regmap(dev, &div_clk->clkr); + if (ret) + return ERR_PTR(ret); + + return &div_clk->clkr.hw; +} + +/* + * PON (Passive Optical Network) reference clock operations. + * The PON refclk's parent is cmn_pll_div2 (CMN PLL rate / 2); it is + * then divided by a configurable 8-bit divider (1-255). + */ +static unsigned long clk_pon_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_regmap *pon_clk = to_clk_regmap(hw); + u32 val, div; + int ret; + + ret = regmap_read(pon_clk->regmap, CMN_PLL_PON_CONFIG, &val); + if (ret) + return 0; + + /* Check if in UNIPHY mode (bit 9 = 0) - fixed 31.25 MHz */ + if (!(val & CMN_PLL_PON_MODE_SEL)) + return 31250000UL; + + /* PON mode: calculate from divider */ + div = FIELD_GET(CMN_PLL_PON_DIV_CTRL, val); + if (!div) + return 0; + + return DIV_ROUND_CLOSEST_ULL((u64)parent_rate, div); +} + +static int clk_pon_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + unsigned long div, pon_rate, uniphy_rate = 31250000UL; + bool uniphy_rate_valid, pon_rate_valid; + + if (!req->rate || !req->best_parent_rate) + return -EINVAL; + + div = DIV64_U64_ROUND_CLOSEST((u64)req->best_parent_rate, req->rate); + + /* Clamp to valid range (1-255) */ + div = clamp_t(unsigned long, div, 1, 255); + + pon_rate = DIV_ROUND_CLOSEST_ULL((u64)req->best_parent_rate, div); + + uniphy_rate_valid = uniphy_rate >= req->min_rate && + uniphy_rate <= req->max_rate; + pon_rate_valid = pon_rate >= req->min_rate && + pon_rate <= req->max_rate; + + if (!uniphy_rate_valid && !pon_rate_valid) + return -EINVAL; + + /* Pick whichever mode gets closer to the requested rate */ + if (uniphy_rate_valid && pon_rate_valid) { + unsigned long diff_uniphy, diff_pon; + + diff_uniphy = abs_diff(req->rate, uniphy_rate); + diff_pon = abs_diff(req->rate, pon_rate); + req->rate = diff_uniphy < diff_pon ? uniphy_rate : pon_rate; + } else { + req->rate = uniphy_rate_valid ? uniphy_rate : pon_rate; + } + + return 0; +} + +static int clk_pon_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_regmap *pon_clk = to_clk_regmap(hw); + unsigned long div; + + if (rate == 0) + return -EINVAL; + + /* + * An exact request for 31.25 MHz is always satisfiable by UNIPHY + * mode, even though PON mode with a suitable divider can produce + * the same frequency for some parent rates. Preferring UNIPHY here + * is safe: this function is only ever called with a rate produced + * by clk_pon_clk_determine_rate() through the standard + * clk_set_rate() path, and either mode yields the identical output + * rate for this value. + */ + if (rate == 31250000UL) + return regmap_clear_bits(pon_clk->regmap, CMN_PLL_PON_CONFIG, + CMN_PLL_PON_MODE_SEL); + + div = DIV64_U64_ROUND_CLOSEST((u64)parent_rate, rate); + if (div == 0 || div > 255) + return -EINVAL; + + /* Switch to PON mode and program the divider in a single write */ + return regmap_update_bits(pon_clk->regmap, CMN_PLL_PON_CONFIG, + CMN_PLL_PON_MODE_SEL | CMN_PLL_PON_DIV_CTRL, + CMN_PLL_PON_MODE_SEL | + FIELD_PREP(CMN_PLL_PON_DIV_CTRL, div)); +} + +static const struct clk_ops clk_pon_clk_ops = { + .enable = clk_enable_regmap, + .disable = clk_disable_regmap, + .is_enabled = clk_is_enabled_regmap, + .recalc_rate = clk_pon_clk_recalc_rate, + .determine_rate = clk_pon_clk_determine_rate, + .set_rate = clk_pon_clk_set_rate, +}; + +static struct clk_hw *ipq_cmn_pll_pon_clk_register(struct device *dev, + const char *name, + struct clk_hw *parent_hw) +{ + struct clk_parent_data pdata = { .hw = parent_hw }; + struct clk_init_data init = {}; + struct clk_regmap *pon_clk; + int ret; + + pon_clk = devm_kzalloc(dev, sizeof(*pon_clk), GFP_KERNEL); + if (!pon_clk) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.parent_data = &pdata; + init.num_parents = 1; + init.ops = &clk_pon_clk_ops; + /* + * The PON reference clock may already be enabled by bootloader + * or consumed by hardware without an in-kernel client driver. + * Add CLK_IGNORE_UNUSED so the clock framework does not disable + * it when no consumer has claimed it. + */ + init.flags = CLK_IGNORE_UNUSED; + + pon_clk->hw.init = &init; + pon_clk->enable_reg = CMN_PLL_PON_CONFIG; + pon_clk->enable_mask = CMN_PLL_PON_EN; + + ret = devm_clk_register_regmap(dev, pon_clk); + if (ret) + return ERR_PTR(ret); + + return &pon_clk->hw; +} + +/* + * EPHY-RAW clock operations for IPQ5210. + * The output clock rate is selected via bit 10 of CMN_PLL_PON_CONFIG: + * 0: 125 MHz (for 1G link speed) + * 1: 312.5 MHz (for 2.5G link speed) + */ +static unsigned long clk_ephy_raw_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_regmap *ephy_raw_clk = to_clk_regmap(hw); + u32 val; + int ret; + + ret = regmap_read(ephy_raw_clk->regmap, CMN_PLL_PON_CONFIG, &val); + if (WARN_ON_ONCE(ret)) + return 0; + + if (val & CMN_PLL_GEPHY_312P5M_125M_SEL) + return 312500000UL; + + return 125000000UL; +} + +static int clk_ephy_raw_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + unsigned long rate_125m = 125000000UL, rate_312p5m = 312500000UL; + bool rate_125m_valid, rate_312p5m_valid; + + rate_125m_valid = rate_125m >= req->min_rate && + rate_125m <= req->max_rate; + rate_312p5m_valid = rate_312p5m >= req->min_rate && + rate_312p5m <= req->max_rate; + + if (!rate_125m_valid && !rate_312p5m_valid) + return -EINVAL; + + /* Pick whichever of the two supported rates is closer to the request */ + if (rate_125m_valid && rate_312p5m_valid) { + unsigned long diff_125m, diff_312p5m; + + diff_125m = abs_diff(req->rate, rate_125m); + diff_312p5m = abs_diff(req->rate, rate_312p5m); + req->rate = diff_125m < diff_312p5m ? rate_125m : rate_312p5m; + } else { + req->rate = rate_125m_valid ? rate_125m : rate_312p5m; + } + + return 0; +} + +static int clk_ephy_raw_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_regmap *ephy_raw_clk = to_clk_regmap(hw); + + if (rate == 125000000UL) + return regmap_clear_bits(ephy_raw_clk->regmap, + CMN_PLL_PON_CONFIG, + CMN_PLL_GEPHY_312P5M_125M_SEL); + + if (rate == 312500000UL) + return regmap_set_bits(ephy_raw_clk->regmap, + CMN_PLL_PON_CONFIG, + CMN_PLL_GEPHY_312P5M_125M_SEL); + + return -EINVAL; +} + +static const struct clk_ops clk_ephy_raw_ops = { + .recalc_rate = clk_ephy_raw_recalc_rate, + .determine_rate = clk_ephy_raw_determine_rate, + .set_rate = clk_ephy_raw_set_rate, +}; + +static struct clk_hw *ipq_cmn_pll_ephy_raw_register(struct device *dev, + const char *name, + struct clk_hw *parent_hw) +{ + struct clk_parent_data pdata = { .hw = parent_hw }; + struct clk_regmap *ephy_raw_clk; + struct clk_init_data init = {}; + int ret; + + ephy_raw_clk = devm_kzalloc(dev, sizeof(*ephy_raw_clk), GFP_KERNEL); + if (!ephy_raw_clk) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.parent_data = &pdata; + init.num_parents = 1; + init.ops = &clk_ephy_raw_ops; + + ephy_raw_clk->hw.init = &init; + + ret = devm_clk_register_regmap(dev, ephy_raw_clk); + if (ret) + return ERR_PTR(ret); + + return &ephy_raw_clk->hw; +} + +static unsigned long clk_fixed_gate_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_fixed_gate *gate_clk = to_clk_fixed_gate(hw); + + return gate_clk->rate; +} + +static const struct clk_ops clk_fixed_gate_ops = { + .enable = clk_enable_regmap, + .disable = clk_disable_regmap, + .is_enabled = clk_is_enabled_regmap, + .recalc_rate = clk_fixed_gate_recalc_rate, +}; + +static struct clk_hw *ipq_cmn_pll_register_fixed_gate(struct device *dev, + const char *name, + struct clk_hw *parent_hw, + int enable_bit, + unsigned long rate) +{ + struct clk_parent_data pdata = { .hw = parent_hw }; + struct clk_fixed_gate *gate_clk; + struct clk_init_data init = {}; + int ret; + + gate_clk = devm_kzalloc(dev, sizeof(*gate_clk), GFP_KERNEL); + if (!gate_clk) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.parent_data = &pdata; + init.num_parents = 1; + init.ops = &clk_fixed_gate_ops; + /* + * These gated clocks may be relied on by external hardware or + * bootloader-enabled paths without an in-kernel client driver. + * Add CLK_IGNORE_UNUSED so the clock framework does not disable + * them when no consumer has claimed them. + */ + init.flags = CLK_IGNORE_UNUSED; + + gate_clk->clkr.hw.init = &init; + gate_clk->clkr.enable_reg = CMN_PLL_OUTPUT_RELATED_1; + gate_clk->clkr.enable_mask = BIT(enable_bit); + gate_clk->rate = rate; + + ret = devm_clk_register_regmap(dev, &gate_clk->clkr); + if (ret) + return ERR_PTR(ret); + + return &gate_clk->clkr.hw; +} + static int ipq_cmn_pll_register_clks(struct platform_device *pdev) { const struct cmn_pll_fixed_output_clk *p, *fixed_clk; struct clk_hw_onecell_data *hw_data; struct device *dev = &pdev->dev; + struct clk_cmn_pll *cmn_pll; struct clk_hw *cmn_pll_hw; unsigned int num_clks; struct clk_hw *hw; @@ -380,6 +824,8 @@ static int ipq_cmn_pll_register_clks(struct platform_device *pdev) if (!hw_data) return -ENOMEM; + hw_data->num = num_clks + 1; + /* * Register the CMN PLL clock, which is the parent clock of * the fixed rate output clocks. @@ -388,15 +834,61 @@ static int ipq_cmn_pll_register_clks(struct platform_device *pdev) if (IS_ERR(cmn_pll_hw)) return PTR_ERR(cmn_pll_hw); + cmn_pll = to_clk_cmn_pll(cmn_pll_hw); + cmn_pll->div2_hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, + "cmn_pll_div2", + cmn_pll_hw, + 0, 1, 2); + if (IS_ERR(cmn_pll->div2_hw)) + return PTR_ERR(cmn_pll->div2_hw); + /* Register the fixed rate output clocks. */ for (i = 0; i < num_clks; i++) { - hw = clk_hw_register_fixed_rate_parent_hw(dev, fixed_clk[i].name, - cmn_pll_hw, 0, - fixed_clk[i].rate); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto unregister_fixed_clk; + hw = ERR_PTR(-EINVAL); + + switch (fixed_clk[i].type) { + case CMN_PLL_CLK_FIXED_RATE: { + struct clk_parent_data pdata = { .hw = cmn_pll_hw }; + + hw = devm_clk_hw_register_fixed_rate_parent_data(dev, + fixed_clk[i].name, + &pdata, 0, + fixed_clk[i].rate); + break; } + case CMN_PLL_CLK_FIXED_GATE: + hw = ipq_cmn_pll_register_fixed_gate(dev, + fixed_clk[i].name, + cmn_pll->div2_hw, + fixed_clk[i].enable_bit, + fixed_clk[i].rate); + break; + case CMN_PLL_CLK_NSS: + hw = ipq_cmn_pll_regmap_div_register(dev, + fixed_clk[i].name, + cmn_pll->div2_hw, + CMN_PLL_NSS_CLK_SEL); + break; + case CMN_PLL_CLK_PPE: + hw = ipq_cmn_pll_regmap_div_register(dev, + fixed_clk[i].name, + cmn_pll->div2_hw, + CMN_PLL_PPE_CLK_SEL); + break; + case CMN_PLL_CLK_PON: + hw = ipq_cmn_pll_pon_clk_register(dev, + fixed_clk[i].name, + cmn_pll->div2_hw); + break; + case CMN_PLL_CLK_EPHY_RAW: + hw = ipq_cmn_pll_ephy_raw_register(dev, + fixed_clk[i].name, + cmn_pll->div2_hw); + break; + } + + if (IS_ERR(hw)) + return PTR_ERR(hw); hw_data->hws[fixed_clk[i].id] = hw; } @@ -406,21 +898,14 @@ static int ipq_cmn_pll_register_clks(struct platform_device *pdev) * is configured to 12 GHZ by DT property assigned-clock-rates-u64. */ hw_data->hws[CMN_PLL_CLK] = cmn_pll_hw; - hw_data->num = num_clks + 1; ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data); if (ret) - goto unregister_fixed_clk; + return ret; platform_set_drvdata(pdev, hw_data); return 0; - -unregister_fixed_clk: - while (i > 0) - clk_hw_unregister(hw_data->hws[fixed_clk[--i].id]); - - return ret; } static int ipq_cmn_pll_clk_probe(struct platform_device *pdev) @@ -462,27 +947,13 @@ static int ipq_cmn_pll_clk_probe(struct platform_device *pdev) return 0; } -static void ipq_cmn_pll_clk_remove(struct platform_device *pdev) -{ - struct clk_hw_onecell_data *hw_data = platform_get_drvdata(pdev); - int i; - - /* - * The clock with index CMN_PLL_CLK is unregistered by - * device management. - */ - for (i = 0; i < hw_data->num; i++) { - if (i != CMN_PLL_CLK) - clk_hw_unregister(hw_data->hws[i]); - } -} - static const struct dev_pm_ops ipq_cmn_pll_pm_ops = { SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) }; static const struct of_device_id ipq_cmn_pll_clk_ids[] = { { .compatible = "qcom,ipq5018-cmn-pll", .data = &ipq5018_output_clks }, + { .compatible = "qcom,ipq5210-cmn-pll", .data = &ipq5210_output_clks }, { .compatible = "qcom,ipq5332-cmn-pll", .data = &ipq5332_output_clks }, { .compatible = "qcom,ipq5424-cmn-pll", .data = &ipq5424_output_clks }, { .compatible = "qcom,ipq6018-cmn-pll", .data = &ipq6018_output_clks }, @@ -494,7 +965,6 @@ MODULE_DEVICE_TABLE(of, ipq_cmn_pll_clk_ids); static struct platform_driver ipq_cmn_pll_clk_driver = { .probe = ipq_cmn_pll_clk_probe, - .remove = ipq_cmn_pll_clk_remove, .driver = { .name = "ipq_cmn_pll", .of_match_table = ipq_cmn_pll_clk_ids, diff --git a/drivers/clk/qcom/lpasscc-sc7280.c b/drivers/clk/qcom/lpasscc-sc7280.c index e6b815aec46a..3789a7b37bdd 100644 --- a/drivers/clk/qcom/lpasscc-sc7280.c +++ b/drivers/clk/qcom/lpasscc-sc7280.c @@ -169,17 +169,7 @@ static struct platform_driver lpass_cc_sc7280_driver = { }, }; -static int __init lpass_cc_sc7280_init(void) -{ - return platform_driver_register(&lpass_cc_sc7280_driver); -} -subsys_initcall(lpass_cc_sc7280_init); - -static void __exit lpass_cc_sc7280_exit(void) -{ - platform_driver_unregister(&lpass_cc_sc7280_driver); -} -module_exit(lpass_cc_sc7280_exit); +subsys_platform_driver(lpass_cc_sc7280_driver); MODULE_DESCRIPTION("QTI LPASS_CC SC7280 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/lpasscc-sdm845.c b/drivers/clk/qcom/lpasscc-sdm845.c index 5c1ea75f9ba8..1d7e78dd6015 100644 --- a/drivers/clk/qcom/lpasscc-sdm845.c +++ b/drivers/clk/qcom/lpasscc-sdm845.c @@ -144,17 +144,7 @@ static struct platform_driver lpass_cc_sdm845_driver = { }, }; -static int __init lpass_cc_sdm845_init(void) -{ - return platform_driver_register(&lpass_cc_sdm845_driver); -} -subsys_initcall(lpass_cc_sdm845_init); - -static void __exit lpass_cc_sdm845_exit(void) -{ - platform_driver_unregister(&lpass_cc_sdm845_driver); -} -module_exit(lpass_cc_sdm845_exit); +subsys_platform_driver(lpass_cc_sdm845_driver); MODULE_DESCRIPTION("QTI LPASS_CC SDM845 Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/lpasscc-sm6115.c b/drivers/clk/qcom/lpasscc-sm6115.c index 226dc02fc42d..fcc1512d4a99 100644 --- a/drivers/clk/qcom/lpasscc-sm6115.c +++ b/drivers/clk/qcom/lpasscc-sm6115.c @@ -34,7 +34,7 @@ static const struct qcom_cc_desc lpass_audiocc_sm6115_reset_desc = { }; static const struct qcom_reset_map lpasscc_sm6115_resets[] = { - [LPASS_SWR_TX_CONFIG_CGCR] = { .reg = 0x100, .bit = 1, .udelay = 500 }, + [LPASS_SWR_TX_CONFIG_CGCR] = { .reg = 0xc100, .bit = 1, .udelay = 500 }, }; static struct regmap_config lpasscc_sm6115_regmap_config = { @@ -42,7 +42,7 @@ static struct regmap_config lpasscc_sm6115_regmap_config = { .reg_stride = 4, .val_bits = 32, .name = "lpass-tcsr", - .max_register = 0x1000, + .max_register = 0x12000, }; static const struct qcom_cc_desc lpasscc_sm6115_reset_desc = { diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c index 5174bd3dcdc5..af28da5f04b3 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7180.c +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -343,7 +343,28 @@ static const struct qcom_cc_desc lpass_core_hm_sc7180_desc = { .num_gdscs = ARRAY_SIZE(lpass_core_hm_sc7180_gdscs), }; +static const u32 lpass_core_cc_sc7180_critical_cbcrs[] = { + 0x24000, /* LPASS_AUDIO_CORE_SYSNOC_SWAY_CORE_CLK */ +}; + +static void lpass_core_cc_sc7180_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* PLL settings */ + regmap_write(regmap, 0x1008, 0x20); + regmap_update_bits(regmap, 0x1014, BIT(0), BIT(0)); + + clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap, + &lpass_lpaaudio_dig_pll_config); +} + +static const struct qcom_cc_driver_data lpass_core_cc_sc7180_driver_data = { + .clk_cbcrs = lpass_core_cc_sc7180_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(lpass_core_cc_sc7180_critical_cbcrs), + .clk_regs_configure = lpass_core_cc_sc7180_regs_configure, +}; + static const struct qcom_cc_desc lpass_core_cc_sc7180_desc = { + .driver_data = &lpass_core_cc_sc7180_driver_data, .config = &lpass_core_cc_sc7180_regmap_config, .clks = lpass_core_cc_sc7180_clocks, .num_clks = ARRAY_SIZE(lpass_core_cc_sc7180_clocks), @@ -400,16 +421,6 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) goto exit; } - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x24000); /* LPASS_AUDIO_CORE_SYSNOC_SWAY_CORE_CLK */ - - /* PLL settings */ - regmap_write(regmap, 0x1008, 0x20); - regmap_update_bits(regmap, 0x1014, BIT(0), BIT(0)); - - clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap, - &lpass_lpaaudio_dig_pll_config); - ret = qcom_cc_really_probe(&pdev->dev, &lpass_core_cc_sc7180_desc, regmap); exit: diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c index a23440e13b71..a67df833592a 100644 --- a/drivers/clk/qcom/mmcc-msm8960.c +++ b/drivers/clk/qcom/mmcc-msm8960.c @@ -3170,7 +3170,8 @@ static int mmcc_msm8960_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); - clk_pll_configure_sr(&pll15, regmap, &pll15_config, false); + if (desc == &mmcc_apq8064_desc) + clk_pll_configure_sr(&pll15, regmap, &pll15_config, false); return qcom_cc_really_probe(&pdev->dev, desc, regmap); } diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c index 3426e3dde924..ef7bde361fc3 100644 --- a/drivers/clk/qcom/mmcc-msm8996.c +++ b/drivers/clk/qcom/mmcc-msm8996.c @@ -3133,9 +3133,9 @@ static struct clk_branch fd_core_uar_clk = { }; static struct clk_branch fd_ahb_clk = { - .halt_reg = 0x3ba74, + .halt_reg = 0x3b74, .clkr = { - .enable_reg = 0x3ba74, + .enable_reg = 0x3b74, .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "fd_ahb_clk", diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index 200f986de965..9f8b8e29fa0f 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -2017,7 +2017,7 @@ static struct clk_branch csiphy_ahb2crif_clk = { static struct clk_branch mdss_ahb_clk = { .halt_reg = 0x2308, .halt_check = BRANCH_HALT, - .hwcg_reg = 0x8a004, + .hwcg_reg = 0x2308, .hwcg_bit = 1, .clkr = { .enable_reg = 0x2308, diff --git a/drivers/clk/qcom/negcc-nord.c b/drivers/clk/qcom/negcc-nord.c index 0db284edc4e4..68ce4d6278ba 100644 --- a/drivers/clk/qcom/negcc-nord.c +++ b/drivers/clk/qcom/negcc-nord.c @@ -46,7 +46,7 @@ static struct clk_alpha_pll ne_gcc_gpll0 = { .offset = 0x0, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], .clkr = { - .enable_reg = 0x0, + .enable_reg = 0x57010, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "ne_gcc_gpll0", @@ -85,7 +85,7 @@ static struct clk_alpha_pll ne_gcc_gpll2 = { .offset = 0x2000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], .clkr = { - .enable_reg = 0x0, + .enable_reg = 0x57010, .enable_mask = BIT(2), .hw.init = &(const struct clk_init_data) { .name = "ne_gcc_gpll2", @@ -1877,6 +1877,7 @@ static const struct qcom_reset_map ne_gcc_nord_resets[] = { [NE_GCC_USB3PHY_PHY_PRIM_BCR] = { 0x2b004 }, [NE_GCC_USB3PHY_PHY_SEC_BCR] = { 0x2d004 }, [NE_GCC_QUSB2PHY_PRIM_BCR] = { 0x2e000 }, + [NE_GCC_QUSB2PHY_SEC_BCR] = { 0x2f000 }, }; static const struct clk_rcg_dfs_data ne_gcc_nord_dfs_clocks[] = { diff --git a/drivers/clk/qcom/nwgcc-nord.c b/drivers/clk/qcom/nwgcc-nord.c index e061c0623e9a..1eb8e5313912 100644 --- a/drivers/clk/qcom/nwgcc-nord.c +++ b/drivers/clk/qcom/nwgcc-nord.c @@ -36,7 +36,7 @@ static struct clk_alpha_pll nw_gcc_gpll0 = { .offset = 0x0, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], .clkr = { - .enable_reg = 0x0, + .enable_reg = 0x76008, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "nw_gcc_gpll0", @@ -623,6 +623,9 @@ static const struct qcom_reset_map nw_gcc_nord_resets[] = { [NW_GCC_GPU_2_BCR] = { 0x24000 }, [NW_GCC_GPU_BCR] = { 0x23000 }, [NW_GCC_VIDEO_BCR] = { 0x1a000 }, + [NW_GCC_VIDEO_AXI0_CLK_ARES] = { 0x1a008, 2 }, + [NW_GCC_VIDEO_AXI0C_CLK_ARES] = { 0x1a01c, 2 }, + [NW_GCC_VIDEO_AXI1_CLK_ARES] = { 0x1a030, 2 }, }; static const u32 nw_gcc_nord_critical_cbcrs[] = { diff --git a/drivers/clk/qcom/segcc-nord.c b/drivers/clk/qcom/segcc-nord.c index 51d7f83e21b6..ef97da3852e3 100644 --- a/drivers/clk/qcom/segcc-nord.c +++ b/drivers/clk/qcom/segcc-nord.c @@ -39,7 +39,7 @@ static struct clk_alpha_pll se_gcc_gpll0 = { .offset = 0x0, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], .clkr = { - .enable_reg = 0x0, + .enable_reg = 0x57010, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "se_gcc_gpll0", @@ -78,7 +78,7 @@ static struct clk_alpha_pll se_gcc_gpll2 = { .offset = 0x2000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], .clkr = { - .enable_reg = 0x0, + .enable_reg = 0x57010, .enable_mask = BIT(2), .hw.init = &(const struct clk_init_data) { .name = "se_gcc_gpll2", @@ -95,7 +95,7 @@ static struct clk_alpha_pll se_gcc_gpll4 = { .offset = 0x4000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], .clkr = { - .enable_reg = 0x0, + .enable_reg = 0x57010, .enable_mask = BIT(4), .hw.init = &(const struct clk_init_data) { .name = "se_gcc_gpll4", @@ -112,7 +112,7 @@ static struct clk_alpha_pll se_gcc_gpll5 = { .offset = 0x5000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], .clkr = { - .enable_reg = 0x0, + .enable_reg = 0x57010, .enable_mask = BIT(5), .hw.init = &(const struct clk_init_data) { .name = "se_gcc_gpll5", @@ -747,6 +747,21 @@ static struct clk_branch se_gcc_emac0_cc_sgmiiphy_tx_clk = { }, }; +static struct clk_branch se_gcc_emac0_cnoc_apb_clk = { + .halt_reg = 0x24018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x24018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x24018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "se_gcc_emac0_cnoc_apb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch se_gcc_emac0_phy_aux_clk = { .halt_reg = 0x2402c, .halt_check = BRANCH_HALT, @@ -894,6 +909,21 @@ static struct clk_branch se_gcc_emac1_cc_sgmiiphy_tx_clk = { }, }; +static struct clk_branch se_gcc_emac1_cnoc_apb_clk = { + .halt_reg = 0x25018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x25018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x25018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "se_gcc_emac1_cnoc_apb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch se_gcc_emac1_phy_aux_clk = { .halt_reg = 0x2502c, .halt_check = BRANCH_HALT, @@ -1458,6 +1488,7 @@ static struct clk_regmap *se_gcc_nord_clocks[] = { [SE_GCC_EMAC0_AXI_CLK] = &se_gcc_emac0_axi_clk.clkr, [SE_GCC_EMAC0_CC_SGMIIPHY_RX_CLK] = &se_gcc_emac0_cc_sgmiiphy_rx_clk.clkr, [SE_GCC_EMAC0_CC_SGMIIPHY_TX_CLK] = &se_gcc_emac0_cc_sgmiiphy_tx_clk.clkr, + [SE_GCC_EMAC0_CNOC_APB_CLK] = &se_gcc_emac0_cnoc_apb_clk.clkr, [SE_GCC_EMAC0_PHY_AUX_CLK] = &se_gcc_emac0_phy_aux_clk.clkr, [SE_GCC_EMAC0_PHY_AUX_CLK_SRC] = &se_gcc_emac0_phy_aux_clk_src.clkr, [SE_GCC_EMAC0_PTP_CLK] = &se_gcc_emac0_ptp_clk.clkr, @@ -1471,6 +1502,7 @@ static struct clk_regmap *se_gcc_nord_clocks[] = { [SE_GCC_EMAC1_AXI_CLK] = &se_gcc_emac1_axi_clk.clkr, [SE_GCC_EMAC1_CC_SGMIIPHY_RX_CLK] = &se_gcc_emac1_cc_sgmiiphy_rx_clk.clkr, [SE_GCC_EMAC1_CC_SGMIIPHY_TX_CLK] = &se_gcc_emac1_cc_sgmiiphy_tx_clk.clkr, + [SE_GCC_EMAC1_CNOC_APB_CLK] = &se_gcc_emac1_cnoc_apb_clk.clkr, [SE_GCC_EMAC1_PHY_AUX_CLK] = &se_gcc_emac1_phy_aux_clk.clkr, [SE_GCC_EMAC1_PHY_AUX_CLK_SRC] = &se_gcc_emac1_phy_aux_clk_src.clkr, [SE_GCC_EMAC1_PTP_CLK] = &se_gcc_emac1_ptp_clk.clkr, diff --git a/drivers/clk/qcom/tcsrcc-eliza.c b/drivers/clk/qcom/tcsrcc-eliza.c index 127d1f0a1442..daab9a620490 100644 --- a/drivers/clk/qcom/tcsrcc-eliza.c +++ b/drivers/clk/qcom/tcsrcc-eliza.c @@ -162,17 +162,7 @@ static struct platform_driver tcsr_cc_eliza_driver = { }, }; -static int __init tcsr_cc_eliza_init(void) -{ - return platform_driver_register(&tcsr_cc_eliza_driver); -} -subsys_initcall(tcsr_cc_eliza_init); - -static void __exit tcsr_cc_eliza_exit(void) -{ - platform_driver_unregister(&tcsr_cc_eliza_driver); -} -module_exit(tcsr_cc_eliza_exit); +subsys_platform_driver(tcsr_cc_eliza_driver); MODULE_DESCRIPTION("QTI TCSR_CC Eliza Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/tcsrcc-glymur.c b/drivers/clk/qcom/tcsrcc-glymur.c index 1791e23739ed..8ac60052fb14 100644 --- a/drivers/clk/qcom/tcsrcc-glymur.c +++ b/drivers/clk/qcom/tcsrcc-glymur.c @@ -296,17 +296,7 @@ static struct platform_driver tcsr_cc_glymur_driver = { }, }; -static int __init tcsr_cc_glymur_init(void) -{ - return platform_driver_register(&tcsr_cc_glymur_driver); -} -subsys_initcall(tcsr_cc_glymur_init); - -static void __exit tcsr_cc_glymur_exit(void) -{ - platform_driver_unregister(&tcsr_cc_glymur_driver); -} -module_exit(tcsr_cc_glymur_exit); +subsys_platform_driver(tcsr_cc_glymur_driver); MODULE_DESCRIPTION("QTI TCSRCC Glymur Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/tcsrcc-kaanapali.c b/drivers/clk/qcom/tcsrcc-kaanapali.c index db46d639edb8..78b77e7cd396 100644 --- a/drivers/clk/qcom/tcsrcc-kaanapali.c +++ b/drivers/clk/qcom/tcsrcc-kaanapali.c @@ -124,17 +124,7 @@ static struct platform_driver tcsr_cc_kaanapali_driver = { }, }; -static int __init tcsr_cc_kaanapali_init(void) -{ - return platform_driver_register(&tcsr_cc_kaanapali_driver); -} -subsys_initcall(tcsr_cc_kaanapali_init); - -static void __exit tcsr_cc_kaanapali_exit(void) -{ - platform_driver_unregister(&tcsr_cc_kaanapali_driver); -} -module_exit(tcsr_cc_kaanapali_exit); +subsys_platform_driver(tcsr_cc_kaanapali_driver); MODULE_DESCRIPTION("QTI TCSR_CC Kaanapali Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/tcsrcc-sm8550.c b/drivers/clk/qcom/tcsrcc-sm8550.c index 41d73f92a000..6cac619dd959 100644 --- a/drivers/clk/qcom/tcsrcc-sm8550.c +++ b/drivers/clk/qcom/tcsrcc-sm8550.c @@ -191,17 +191,7 @@ static struct platform_driver tcsr_cc_sm8550_driver = { }, }; -static int __init tcsr_cc_sm8550_init(void) -{ - return platform_driver_register(&tcsr_cc_sm8550_driver); -} -subsys_initcall(tcsr_cc_sm8550_init); - -static void __exit tcsr_cc_sm8550_exit(void) -{ - platform_driver_unregister(&tcsr_cc_sm8550_driver); -} -module_exit(tcsr_cc_sm8550_exit); +subsys_platform_driver(tcsr_cc_sm8550_driver); MODULE_DESCRIPTION("QTI TCSRCC SM8550 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/tcsrcc-sm8650.c b/drivers/clk/qcom/tcsrcc-sm8650.c index 651e28067954..194aea6ec43a 100644 --- a/drivers/clk/qcom/tcsrcc-sm8650.c +++ b/drivers/clk/qcom/tcsrcc-sm8650.c @@ -173,17 +173,7 @@ static struct platform_driver tcsr_cc_sm8650_driver = { }, }; -static int __init tcsr_cc_sm8650_init(void) -{ - return platform_driver_register(&tcsr_cc_sm8650_driver); -} -subsys_initcall(tcsr_cc_sm8650_init); - -static void __exit tcsr_cc_sm8650_exit(void) -{ - platform_driver_unregister(&tcsr_cc_sm8650_driver); -} -module_exit(tcsr_cc_sm8650_exit); +subsys_platform_driver(tcsr_cc_sm8650_driver); MODULE_DESCRIPTION("QTI TCSRCC SM8650 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/tcsrcc-sm8750.c b/drivers/clk/qcom/tcsrcc-sm8750.c index 9fe840a448bf..b11ec403bb32 100644 --- a/drivers/clk/qcom/tcsrcc-sm8750.c +++ b/drivers/clk/qcom/tcsrcc-sm8750.c @@ -124,17 +124,7 @@ static struct platform_driver tcsr_cc_sm8750_driver = { }, }; -static int __init tcsr_cc_sm8750_init(void) -{ - return platform_driver_register(&tcsr_cc_sm8750_driver); -} -subsys_initcall(tcsr_cc_sm8750_init); - -static void __exit tcsr_cc_sm8750_exit(void) -{ - platform_driver_unregister(&tcsr_cc_sm8750_driver); -} -module_exit(tcsr_cc_sm8750_exit); +subsys_platform_driver(tcsr_cc_sm8750_driver); MODULE_DESCRIPTION("QTI TCSR_CC SM8750 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/tcsrcc-x1e80100.c b/drivers/clk/qcom/tcsrcc-x1e80100.c index 0b05c27b619b..7dbeff419f99 100644 --- a/drivers/clk/qcom/tcsrcc-x1e80100.c +++ b/drivers/clk/qcom/tcsrcc-x1e80100.c @@ -5,238 +5,58 @@ */ #include +#include #include +#include #include #include #include -#include "clk-branch.h" -#include "clk-regmap.h" -#include "common.h" -#include "reset.h" - -enum { - DT_BI_TCXO_PAD, +static const char * const x1e80100_tcsr_tx1_rpt0_rx0_regulators[] = { + "vdda-refgen0-0p9", + "vdda-refgen0-1p2", + "vdda-qreftx1-0p9", + "vdda-qreftx1-1p2", + "vdda-qrefrpt0-0p9", + "vdda-qrefrx0-0p9", }; -static struct clk_branch tcsr_edp_clkref_en = { - .halt_reg = 0x15130, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x15130, - .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 x1e80100_tcsr_tx1_rpt1_rx1_regulators[] = { + "vdda-refgen0-0p9", + "vdda-refgen0-1p2", + "vdda-qreftx1-0p9", + "vdda-qreftx1-1p2", + "vdda-qrefrpt1-0p9", + "vdda-qrefrx1-0p9", }; -static struct clk_branch tcsr_pcie_2l_4_clkref_en = { - .halt_reg = 0x15100, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x15100, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "tcsr_pcie_2l_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 x1e80100_tcsr_tx1_rpt12_rx2_regulators[] = { + "vdda-refgen0-0p9", + "vdda-refgen0-1p2", + "vdda-qreftx1-0p9", + "vdda-qreftx1-1p2", + "vdda-qrefrpt1-0p9", + "vdda-qrefrpt2-0p9", + "vdda-qrefrx2-0p9", }; -static struct clk_branch tcsr_pcie_2l_5_clkref_en = { - .halt_reg = 0x15104, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x15104, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "tcsr_pcie_2l_5_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 x1e80100_tcsr_tx0_rpt3_rx3_regulators[] = { + "vdda-refgen2-0p9", + "vdda-refgen2-1p2", + "vdda-qreftx0-0p9", + "vdda-qreftx0-1p2", + "vdda-qrefrpt3-0p9", + "vdda-qrefrx3-0p9", }; -static struct clk_branch tcsr_pcie_8l_clkref_en = { - .halt_reg = 0x15108, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x15108, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "tcsr_pcie_8l_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_mp0_clkref_en = { - .halt_reg = 0x1510c, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x1510c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "tcsr_usb3_mp0_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_mp1_clkref_en = { - .halt_reg = 0x15110, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x15110, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "tcsr_usb3_mp1_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_usb2_1_clkref_en = { - .halt_reg = 0x15114, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x15114, - .enable_mask = BIT(0), - .hw.init = &(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 struct clk_branch tcsr_ufs_phy_clkref_en = { - .halt_reg = 0x15118, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x15118, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "tcsr_ufs_phy_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 = 0x15120, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x15120, - .enable_mask = BIT(0), - .hw.init = &(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 = 0x15124, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x15124, - .enable_mask = BIT(0), - .hw.init = &(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_branch tcsr_usb2_2_clkref_en = { - .halt_reg = 0x15128, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x15128, - .enable_mask = BIT(0), - .hw.init = &(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 struct clk_branch tcsr_pcie_4l_clkref_en = { - .halt_reg = 0x1512c, - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x1512c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "tcsr_pcie_4l_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_x1e80100_clocks[] = { - [TCSR_EDP_CLKREF_EN] = &tcsr_edp_clkref_en.clkr, - [TCSR_PCIE_2L_4_CLKREF_EN] = &tcsr_pcie_2l_4_clkref_en.clkr, - [TCSR_PCIE_2L_5_CLKREF_EN] = &tcsr_pcie_2l_5_clkref_en.clkr, - [TCSR_PCIE_8L_CLKREF_EN] = &tcsr_pcie_8l_clkref_en.clkr, - [TCSR_USB3_MP0_CLKREF_EN] = &tcsr_usb3_mp0_clkref_en.clkr, - [TCSR_USB3_MP1_CLKREF_EN] = &tcsr_usb3_mp1_clkref_en.clkr, - [TCSR_USB2_1_CLKREF_EN] = &tcsr_usb2_1_clkref_en.clkr, - [TCSR_UFS_PHY_CLKREF_EN] = &tcsr_ufs_phy_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, - [TCSR_USB2_2_CLKREF_EN] = &tcsr_usb2_2_clkref_en.clkr, - [TCSR_PCIE_4L_CLKREF_EN] = &tcsr_pcie_4l_clkref_en.clkr, +static const char * const x1e80100_tcsr_tx0_rpt4_rx4_regulators[] = { + "vdda-refgen2-0p9", + "vdda-refgen2-1p2", + "vdda-qreftx0-0p9", + "vdda-qreftx0-1p2", + "vdda-qrefrpt4-0p9", + "vdda-qrefrx4-0p9", }; static const struct regmap_config tcsr_cc_x1e80100_regmap_config = { @@ -247,10 +67,79 @@ static const struct regmap_config tcsr_cc_x1e80100_regmap_config = { .fast_io = true, }; -static const struct qcom_cc_desc tcsr_cc_x1e80100_desc = { - .config = &tcsr_cc_x1e80100_regmap_config, - .clks = tcsr_cc_x1e80100_clocks, - .num_clks = ARRAY_SIZE(tcsr_cc_x1e80100_clocks), +static const struct qcom_clk_ref_desc * const tcsr_cc_x1e80100_clk_descs[] = { + [TCSR_EDP_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_edp_clkref_en", + .offset = 0x15130, + .regulator_names = x1e80100_tcsr_tx0_rpt3_rx3_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx0_rpt3_rx3_regulators), + }, + [TCSR_PCIE_2L_4_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_pcie_2l_4_clkref_en", + .offset = 0x15100, + .regulator_names = x1e80100_tcsr_tx1_rpt1_rx1_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx1_rpt1_rx1_regulators), + }, + [TCSR_PCIE_2L_5_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_pcie_2l_5_clkref_en", + .offset = 0x15104, + .regulator_names = x1e80100_tcsr_tx1_rpt12_rx2_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx1_rpt12_rx2_regulators), + }, + [TCSR_PCIE_8L_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_pcie_8l_clkref_en", + .offset = 0x15108, + .regulator_names = x1e80100_tcsr_tx1_rpt0_rx0_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx1_rpt0_rx0_regulators), + }, + [TCSR_USB3_MP0_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb3_mp0_clkref_en", + .offset = 0x1510c, + .regulator_names = x1e80100_tcsr_tx1_rpt0_rx0_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx1_rpt0_rx0_regulators), + }, + [TCSR_USB3_MP1_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb3_mp1_clkref_en", + .offset = 0x15110, + .regulator_names = x1e80100_tcsr_tx1_rpt0_rx0_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx1_rpt0_rx0_regulators), + }, + [TCSR_USB2_1_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb2_1_clkref_en", + .offset = 0x15114, + .regulator_names = x1e80100_tcsr_tx0_rpt3_rx3_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx0_rpt3_rx3_regulators), + }, + [TCSR_UFS_PHY_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_ufs_phy_clkref_en", + .offset = 0x15118, + .regulator_names = x1e80100_tcsr_tx1_rpt12_rx2_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx1_rpt12_rx2_regulators), + }, + [TCSR_USB4_1_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb4_1_clkref_en", + .offset = 0x15120, + .regulator_names = x1e80100_tcsr_tx0_rpt4_rx4_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx0_rpt4_rx4_regulators), + }, + [TCSR_USB4_2_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb4_2_clkref_en", + .offset = 0x15124, + .regulator_names = x1e80100_tcsr_tx0_rpt3_rx3_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx0_rpt3_rx3_regulators), + }, + [TCSR_USB2_2_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_usb2_2_clkref_en", + .offset = 0x15128, + .regulator_names = x1e80100_tcsr_tx0_rpt3_rx3_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx0_rpt3_rx3_regulators), + }, + [TCSR_PCIE_4L_CLKREF_EN] = &(const struct qcom_clk_ref_desc) { + .name = "tcsr_pcie_4l_clkref_en", + .offset = 0x1512c, + .regulator_names = x1e80100_tcsr_tx0_rpt4_rx4_regulators, + .num_regulators = ARRAY_SIZE(x1e80100_tcsr_tx0_rpt4_rx4_regulators), + }, }; static const struct of_device_id tcsr_cc_x1e80100_match_table[] = { @@ -261,7 +150,9 @@ MODULE_DEVICE_TABLE(of, tcsr_cc_x1e80100_match_table); static int tcsr_cc_x1e80100_probe(struct platform_device *pdev) { - return qcom_cc_probe(pdev, &tcsr_cc_x1e80100_desc); + return qcom_clk_ref_probe(pdev, &tcsr_cc_x1e80100_regmap_config, + tcsr_cc_x1e80100_clk_descs, + ARRAY_SIZE(tcsr_cc_x1e80100_clk_descs)); } static struct platform_driver tcsr_cc_x1e80100_driver = { @@ -272,17 +163,7 @@ static struct platform_driver tcsr_cc_x1e80100_driver = { }, }; -static int __init tcsr_cc_x1e80100_init(void) -{ - return platform_driver_register(&tcsr_cc_x1e80100_driver); -} -subsys_initcall(tcsr_cc_x1e80100_init); - -static void __exit tcsr_cc_x1e80100_exit(void) -{ - platform_driver_unregister(&tcsr_cc_x1e80100_driver); -} -module_exit(tcsr_cc_x1e80100_exit); +subsys_platform_driver(tcsr_cc_x1e80100_driver); MODULE_DESCRIPTION("QTI TCSR Clock Controller X1E80100 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/videocc-eliza.c b/drivers/clk/qcom/videocc-eliza.c new file mode 100644 index 000000000000..9112ded781c2 --- /dev/null +++ b/drivers/clk/qcom/videocc-eliza.c @@ -0,0 +1,404 @@ +// 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_SLEEP_CLK, + DT_AHB_CLK, +}; + +enum { + P_BI_TCXO, + P_SLEEP_CLK, + P_VIDEO_CC_PLL0_OUT_MAIN, +}; + +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + +/* 576.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll0_config = { + .l = 0x1e, + .alpha = 0x0, + .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 = 0x00000005, +}; + +static struct clk_alpha_pll video_cc_pll0 = { + .offset = 0x0, + .config = &video_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 = "video_cc_pll0", + .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 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_PLL0_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll0.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_2[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2[] = { + { .index = DT_SLEEP_CLK }, +}; + +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 = 0x8018, + .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(576000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(633000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1098000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1113000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0_clk_src = { + .cmd_rcgr = 0x8000, + .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_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_sleep_clk_src = { + .cmd_rcgr = 0x8110, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_2, + .freq_tbl = ftbl_video_cc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_sleep_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 struct clk_rcg2 video_cc_xo_clk_src = { + .cmd_rcgr = 0x80f4, + .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_shared_ops, + }, +}; + +static struct clk_regmap_div video_cc_mvs0_div_clk_src = { + .reg = 0x80ac, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_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 video_cc_mvs0c_div2_div_clk_src = { + .reg = 0x8058, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_div2_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch video_cc_mvs0_clk = { + .halt_reg = 0x80a0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80a0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80a0, + .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_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_shift_clk = { + .halt_reg = 0x8144, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8144, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8144, + .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_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 = "video_cc_mvs0c_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_div2_div_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 = 0x8148, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8148, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8148, + .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 = 0x8034, + .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 = 0x808c, + .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_mvs0c_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +static struct clk_regmap *video_cc_eliza_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_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr, + [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, + [VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr, + [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr, + [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, + [VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr, + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, +}; + +static struct gdsc *video_cc_eliza_gdscs[] = { + [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, + [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, +}; + +static const struct qcom_reset_map video_cc_eliza_resets[] = { + [VIDEO_CC_INTERFACE_BCR] = { 0x80d8 }, + [VIDEO_CC_MVS0_CLK_ARES] = { 0x80a0, 2 }, + [VIDEO_CC_MVS0_BCR] = { 0x8088 }, + [VIDEO_CC_MVS0C_CLK_ARES] = { 0x804c, 2 }, + [VIDEO_CC_MVS0C_BCR] = { 0x8030 }, + [VIDEO_CC_XO_CLK_ARES] = { 0x810c, 2 }, +}; + +static struct clk_alpha_pll *video_cc_eliza_plls[] = { + &video_cc_pll0, +}; + +static const u32 video_cc_eliza_critical_cbcrs[] = { + 0x80dc, /* VIDEO_CC_AHB_CLK */ + 0x8128, /* VIDEO_CC_SLEEP_CLK */ + 0x810c, /* VIDEO_CC_XO_CLK */ +}; + +static const struct regmap_config video_cc_eliza_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9f50, + .fast_io = true, +}; + +static const struct qcom_cc_driver_data video_cc_eliza_driver_data = { + .alpha_plls = video_cc_eliza_plls, + .num_alpha_plls = ARRAY_SIZE(video_cc_eliza_plls), + .clk_cbcrs = video_cc_eliza_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_eliza_critical_cbcrs), +}; + +static const struct qcom_cc_desc video_cc_eliza_desc = { + .config = &video_cc_eliza_regmap_config, + .clks = video_cc_eliza_clocks, + .num_clks = ARRAY_SIZE(video_cc_eliza_clocks), + .resets = video_cc_eliza_resets, + .num_resets = ARRAY_SIZE(video_cc_eliza_resets), + .gdscs = video_cc_eliza_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_eliza_gdscs), + .use_rpm = true, + .driver_data = &video_cc_eliza_driver_data, +}; + +static const struct of_device_id video_cc_eliza_match_table[] = { + { .compatible = "qcom,eliza-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_eliza_match_table); + +static int video_cc_eliza_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &video_cc_eliza_desc); +} + +static struct platform_driver video_cc_eliza_driver = { + .probe = video_cc_eliza_probe, + .driver = { + .name = "videocc-eliza", + .of_match_table = video_cc_eliza_match_table, + }, +}; + +module_platform_driver(video_cc_eliza_driver); + +MODULE_DESCRIPTION("QTI VIDEOCC Eliza Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/videocc-glymur.c b/drivers/clk/qcom/videocc-glymur.c index 18313a65e78d..2776140de355 100644 --- a/drivers/clk/qcom/videocc-glymur.c +++ b/drivers/clk/qcom/videocc-glymur.c @@ -37,6 +37,10 @@ static const struct pll_vco taycan_eko_t_vco[] = { { 249600000, 2500000000, 0 }, }; +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + /* 720.0 MHz Configuration */ static const struct alpha_pll_config video_cc_pll0_config = { .l = 0x25, @@ -48,6 +52,21 @@ static const struct alpha_pll_config video_cc_pll0_config = { .user_ctl_hi_val = 0x00000002, }; +/* 720.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll0_config_nord = { + .l = 0x25, + .alpha = 0x8000, + .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 video_cc_pll0 = { .offset = 0x0, .config = &video_cc_pll0_config, @@ -112,6 +131,15 @@ static struct clk_rcg2 video_cc_ahb_clk_src = { }, }; +static const struct freq_tbl ftbl_video_cc_mvs0_clk_src_nord[] = { + F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1305000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1440000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1680000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), @@ -508,12 +536,22 @@ static const struct qcom_cc_desc video_cc_glymur_desc = { static const struct of_device_id video_cc_glymur_match_table[] = { { .compatible = "qcom,glymur-videocc" }, + { .compatible = "qcom,nord-videocc" }, { } }; MODULE_DEVICE_TABLE(of, video_cc_glymur_match_table); static int video_cc_glymur_probe(struct platform_device *pdev) { + if (of_device_is_compatible(pdev->dev.of_node, "qcom,nord-videocc")) { + video_cc_pll0.vco_table = lucid_ole_vco; + video_cc_pll0.num_vco = ARRAY_SIZE(lucid_ole_vco); + video_cc_pll0.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE]; + video_cc_pll0.config = &video_cc_pll0_config_nord; + + video_cc_mvs0_clk_src.freq_tbl = ftbl_video_cc_mvs0_clk_src_nord; + } + return qcom_cc_probe(pdev, &video_cc_glymur_desc); } diff --git a/drivers/clk/qcom/videocc-sa8775p.c b/drivers/clk/qcom/videocc-sa8775p.c index 65a2d5bafea6..2ca78af8c20c 100644 --- a/drivers/clk/qcom/videocc-sa8775p.c +++ b/drivers/clk/qcom/videocc-sa8775p.c @@ -511,7 +511,19 @@ static const struct regmap_config video_cc_sa8775p_regmap_config = { .fast_io = true, }; +static const u32 video_cc_sa8775p_critical_cbcrs[] = { + 0x80ec, /* VIDEO_CC_AHB_CLK */ + 0x8144, /* VIDEO_CC_SLEEP_CLK */ + 0x8128, /* VIDEO_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data video_cc_sa8775p_driver_data = { + .clk_cbcrs = video_cc_sa8775p_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_sa8775p_critical_cbcrs), +}; + static const struct qcom_cc_desc video_cc_sa8775p_desc = { + .driver_data = &video_cc_sa8775p_driver_data, .config = &video_cc_sa8775p_regmap_config, .clks = video_cc_sa8775p_clocks, .num_clks = ARRAY_SIZE(video_cc_sa8775p_clocks), @@ -557,11 +569,6 @@ static int video_cc_sa8775p_probe(struct platform_device *pdev) if (of_device_is_compatible(pdev->dev.of_node, "qcom,qcs8300-videocc")) regmap_write(regmap, video_cc_mvs0c_div2_div_clk_src.reg, 2); - /* Keep some clocks always enabled */ - qcom_branch_set_clk_en(regmap, 0x80ec); /* VIDEO_CC_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x8144); /* VIDEO_CC_SLEEP_CLK */ - qcom_branch_set_clk_en(regmap, 0x8128); /* VIDEO_CC_XO_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sa8775p_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/videocc-sm6350.c b/drivers/clk/qcom/videocc-sm6350.c index 34bdc5aa865a..d3926f87497c 100644 --- a/drivers/clk/qcom/videocc-sm6350.c +++ b/drivers/clk/qcom/videocc-sm6350.c @@ -311,7 +311,17 @@ static const struct regmap_config video_cc_sm6350_regmap_config = { .fast_io = true, }; +static const u32 video_cc_sm6350_critical_cbcrs[] = { + 0x7018, /* VIDEO_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data video_cc_sm6350_driver_data = { + .clk_cbcrs = video_cc_sm6350_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_sm6350_critical_cbcrs), +}; + static const struct qcom_cc_desc video_cc_sm6350_desc = { + .driver_data = &video_cc_sm6350_driver_data, .config = &video_cc_sm6350_regmap_config, .clks = video_cc_sm6350_clocks, .num_clks = ARRAY_SIZE(video_cc_sm6350_clocks), @@ -335,9 +345,6 @@ static int video_cc_sm6350_probe(struct platform_device *pdev) clk_fabia_pll_configure(&video_pll0, regmap, &video_pll0_config); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x7018); /* VIDEO_CC_XO_CLK */ - return qcom_cc_really_probe(&pdev->dev, &video_cc_sm6350_desc, regmap); } diff --git a/drivers/clk/qcom/videocc-sm7150.c b/drivers/clk/qcom/videocc-sm7150.c index 8d2e00799f96..32bad5e09056 100644 --- a/drivers/clk/qcom/videocc-sm7150.c +++ b/drivers/clk/qcom/videocc-sm7150.c @@ -313,7 +313,17 @@ static const struct regmap_config videocc_sm7150_regmap_config = { .fast_io = true, }; +static const u32 videocc_sm7150_critical_cbcrs[] = { + 0x984, /* VIDEOCC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data videocc_sm7150_driver_data = { + .clk_cbcrs = videocc_sm7150_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(videocc_sm7150_critical_cbcrs), +}; + static const struct qcom_cc_desc videocc_sm7150_desc = { + .driver_data = &videocc_sm7150_driver_data, .config = &videocc_sm7150_regmap_config, .clks = videocc_sm7150_clocks, .num_clks = ARRAY_SIZE(videocc_sm7150_clocks), @@ -337,9 +347,6 @@ static int videocc_sm7150_probe(struct platform_device *pdev) clk_fabia_pll_configure(&videocc_pll0, regmap, &videocc_pll0_config); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0x984); /* VIDEOCC_XO_CLK */ - return qcom_cc_really_probe(&pdev->dev, &videocc_sm7150_desc, regmap); } diff --git a/drivers/clk/qcom/videocc-sm8250.c b/drivers/clk/qcom/videocc-sm8250.c index df479a69cddd..d29d64138508 100644 --- a/drivers/clk/qcom/videocc-sm8250.c +++ b/drivers/clk/qcom/videocc-sm8250.c @@ -345,7 +345,18 @@ static const struct regmap_config video_cc_sm8250_regmap_config = { .fast_io = true, }; +static const u32 video_cc_sm8250_critical_cbcrs[] = { + 0xe58, /* VIDEO_CC_AHB_CLK */ + 0xeec, /* VIDEO_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data video_cc_sm8250_driver_data = { + .clk_cbcrs = video_cc_sm8250_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_sm8250_critical_cbcrs), +}; + static const struct qcom_cc_desc video_cc_sm8250_desc = { + .driver_data = &video_cc_sm8250_driver_data, .config = &video_cc_sm8250_regmap_config, .clks = video_cc_sm8250_clocks, .num_clks = ARRAY_SIZE(video_cc_sm8250_clocks), @@ -383,10 +394,6 @@ static int video_cc_sm8250_probe(struct platform_device *pdev) clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config); clk_lucid_pll_configure(&video_pll1, regmap, &video_pll1_config); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0xe58); /* VIDEO_CC_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0xeec); /* VIDEO_CC_XO_CLK */ - ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8250_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/videocc-sm8350.c b/drivers/clk/qcom/videocc-sm8350.c index 057a9474894a..8528aeb3a342 100644 --- a/drivers/clk/qcom/videocc-sm8350.c +++ b/drivers/clk/qcom/videocc-sm8350.c @@ -510,7 +510,28 @@ static const struct regmap_config video_cc_sm8350_regmap_config = { .fast_io = true, }; +static const u32 video_cc_sm8350_critical_cbcrs[] = { + 0xe58, /* VIDEO_CC_AHB_CLK */ + 0xeec, /* VIDEO_CC_XO_CLK */ +}; + +static const u32 video_cc_sc8280xp_critical_cbcrs[] = { + 0xe58, /* VIDEO_CC_AHB_CLK */ + 0xf34, /* VIDEO_CC_XO_CLK */ +}; + +static const struct qcom_cc_driver_data video_cc_sm8350_driver_data = { + .clk_cbcrs = video_cc_sm8350_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_sm8350_critical_cbcrs), +}; + +static const struct qcom_cc_driver_data video_cc_sc8280xp_driver_data = { + .clk_cbcrs = video_cc_sc8280xp_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_sc8280xp_critical_cbcrs), +}; + static const struct qcom_cc_desc video_cc_sm8350_desc = { + .driver_data = &video_cc_sm8350_driver_data, .config = &video_cc_sm8350_regmap_config, .clks = video_cc_sm8350_clocks, .num_clks = ARRAY_SIZE(video_cc_sm8350_clocks), @@ -522,7 +543,7 @@ static const struct qcom_cc_desc video_cc_sm8350_desc = { static int video_cc_sm8350_probe(struct platform_device *pdev) { - u32 video_cc_xo_clk_cbcr = 0xeec; + struct qcom_cc_desc desc = video_cc_sm8350_desc; struct regmap *regmap; int ret; @@ -539,7 +560,7 @@ static int video_cc_sm8350_probe(struct platform_device *pdev) video_cc_sleep_clk.halt_reg = 0xf58; video_cc_sleep_clk.clkr.enable_reg = 0xf58; video_cc_xo_clk_src.cmd_rcgr = 0xf14; - video_cc_xo_clk_cbcr = 0xf34; + desc.driver_data = &video_cc_sc8280xp_driver_data; video_pll0.vco_table = video_pll1.vco_table = lucid_5lpe_vco_8280xp; /* No change, but assign it for completeness */ @@ -558,11 +579,7 @@ static int video_cc_sm8350_probe(struct platform_device *pdev) clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config); clk_lucid_pll_configure(&video_pll1, regmap, &video_pll1_config); - /* Keep some clocks always-on */ - qcom_branch_set_clk_en(regmap, 0xe58); /* VIDEO_CC_AHB_CLK */ - qcom_branch_set_clk_en(regmap, video_cc_xo_clk_cbcr); /* VIDEO_CC_XO_CLK */ - - ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8350_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &desc, regmap); pm_runtime_put(&pdev->dev); return ret; diff --git a/drivers/clk/qcom/videocc-sm8750.c b/drivers/clk/qcom/videocc-sm8750.c index b62271a7dac6..91d18a90b84f 100644 --- a/drivers/clk/qcom/videocc-sm8750.c +++ b/drivers/clk/qcom/videocc-sm8750.c @@ -445,17 +445,7 @@ static struct platform_driver video_cc_sm8750_driver = { }, }; -static int __init video_cc_sm8750_init(void) -{ - return platform_driver_register(&video_cc_sm8750_driver); -} -subsys_initcall(video_cc_sm8750_init); - -static void __exit video_cc_sm8750_exit(void) -{ - platform_driver_unregister(&video_cc_sm8750_driver); -} -module_exit(video_cc_sm8750_exit); +subsys_platform_driver(video_cc_sm8750_driver); MODULE_DESCRIPTION("QTI VIDEO_CC SM8750 Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 17b95a2e96fb..a02ca6b096c0 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -13,6 +13,7 @@ config CLK_RENESAS select CLK_R8A7745 if ARCH_R8A7745 select CLK_R8A77470 if ARCH_R8A77470 select CLK_R8A774A1 if ARCH_R8A774A1 + select CLK_R8A774A3 if ARCH_R8A774A3 select CLK_R8A774B1 if ARCH_R8A774B1 select CLK_R8A774C0 if ARCH_R8A774C0 select CLK_R8A774E1 if ARCH_R8A774E1 @@ -93,6 +94,10 @@ config CLK_R8A774A1 bool "RZ/G2M clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG +config CLK_R8A774A3 + bool "RZ/G2M v3.0 clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A774B1 bool "RZ/G2N clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG @@ -223,11 +228,13 @@ config CLK_R9A09G077 bool "RZ/T2H clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSSR select CLK_RZV2H_CPG_LIB + select MFD_SYSCON config CLK_R9A09G087 bool "RZ/N2H clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSSR select CLK_RZV2H_CPG_LIB + select MFD_SYSCON config CLK_SH73A0 bool "SH-Mobile AG5 clock support" if COMPILE_TEST diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 658f8aac5127..5c1b798118db 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o obj-$(CONFIG_CLK_R8A7745) += r8a7745-cpg-mssr.o obj-$(CONFIG_CLK_R8A77470) += r8a77470-cpg-mssr.o obj-$(CONFIG_CLK_R8A774A1) += r8a774a1-cpg-mssr.o +obj-$(CONFIG_CLK_R8A774A3) += r8a774a3-cpg-mssr.o obj-$(CONFIG_CLK_R8A774B1) += r8a774b1-cpg-mssr.o obj-$(CONFIG_CLK_R8A774C0) += r8a774c0-cpg-mssr.o obj-$(CONFIG_CLK_R8A774E1) += r8a774e1-cpg-mssr.o diff --git a/drivers/clk/renesas/r8a774a3-cpg-mssr.c b/drivers/clk/renesas/r8a774a3-cpg-mssr.c new file mode 100644 index 000000000000..64c5106a9a54 --- /dev/null +++ b/drivers/clk/renesas/r8a774a3-cpg-mssr.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a774a3 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2026 Renesas Electronics Corp. + * + * Based on r8a7796-cpg-mssr.c + * + * Copyright (C) 2016 Glider bvba + */ + +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A774A3_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL2, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a774a3_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + + /* Core Clock Outputs */ + DEF_GEN3_Z("z", R8A774A3_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8), + DEF_GEN3_Z("z2", R8A774A3_CLK_Z2, CLK_TYPE_GEN3_Z, CLK_PLL2, 2, 0), + DEF_FIXED("s0d3", R8A774A3_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s3d1", R8A774A3_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d4", R8A774A3_CLK_S3D4, CLK_S3, 4, 1), +}; + +static const struct mssr_mod_clk r8a774a3_mod_clks[] __initconst = { + DEF_MOD("scif2", 310, R8A774A3_CLK_S3D4), + DEF_MOD("intc-ap", 408, R8A774A3_CLK_S0D3), +}; + +static const unsigned int r8a774a3_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 OSC + * 14 13 19 17 (MHz) + *------------------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 /16 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 /19 + * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 /19 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 /19 + * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 /24 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 /32 + * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 /32 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 /32 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 192, 1, 128, 1, 16, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 160, 1, 106, 1, 19, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 128, 1, 128, 1, 24, }, + { 1, 128, 1, 84, 1, 24, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, 24, }, + { 2, 192, 1, 192, 1, 32, }, + { 2, 192, 1, 128, 1, 32, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, 32, }, +}; + +static int __init r8a774a3_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + if (!cpg_pll_config->extal_div) { + dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); + return -EINVAL; + } + + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); +} + +const struct cpg_mssr_info r8a774a3_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a774a3_core_clks, + .num_core_clks = ARRAY_SIZE(r8a774a3_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a774a3_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a774a3_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a774a3_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a774a3_crit_mod_clks), + + /* Callbacks */ + .init = r8a774a3_cpg_mssr_init, + .cpg_clk_register = rcar_gen3_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c index d67dff05d9f4..a18a51dab64f 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -99,9 +99,9 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN4_RPCSRC, CLK_PLL5), /* Core Clock Outputs */ - DEF_GEN4_Z("z0", R8A779A0_CLK_Z0, CLK_TYPE_GEN4_Z, CLK_PLL20, 2, 0), - DEF_GEN4_Z("z1", R8A779A0_CLK_Z1, CLK_TYPE_GEN4_Z, CLK_PLL21, 2, 8), - DEF_GEN4_Z("zg", R8A779A0_CLK_ZG, CLK_TYPE_GEN4_Z, CLK_PLL4, 2, 88), + DEF_GEN4_Z("z0", R8A779A0_CLK_Z0, CLK_PLL20, 2, CPG_FRQCRC0, 0), + DEF_GEN4_Z("z1", R8A779A0_CLK_Z1, CLK_PLL21, 2, CPG_FRQCRC0, 8), + DEF_GEN4_Z("zg", R8A779A0_CLK_ZG, CLK_PLL4, 2, CPG_FRQCRB, 24), DEF_FIXED("zx", R8A779A0_CLK_ZX, CLK_PLL20_DIV2, 2, 1), DEF_FIXED("s1d1", R8A779A0_CLK_S1D1, CLK_S1, 1, 1), DEF_FIXED("s1d2", R8A779A0_CLK_S1D2, CLK_S1, 2, 1), diff --git a/drivers/clk/renesas/r8a779f0-cpg-mssr.c b/drivers/clk/renesas/r8a779f0-cpg-mssr.c index f33342314b2e..1264c3fc50aa 100644 --- a/drivers/clk/renesas/r8a779f0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779f0-cpg-mssr.c @@ -79,8 +79,8 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = { DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN4_RPCSRC, CLK_PLL5), /* Core Clock Outputs */ - DEF_GEN4_Z("z0", R8A779F0_CLK_Z0, CLK_TYPE_GEN4_Z, CLK_PLL2, 2, 0), - DEF_GEN4_Z("z1", R8A779F0_CLK_Z1, CLK_TYPE_GEN4_Z, CLK_PLL2, 2, 8), + DEF_GEN4_Z("z0", R8A779F0_CLK_Z0, CLK_PLL2, 2, CPG_FRQCRC0, 0), + DEF_GEN4_Z("z1", R8A779F0_CLK_Z1, CLK_PLL2, 2, CPG_FRQCRC0, 8), DEF_FIXED("s0d2", R8A779F0_CLK_S0D2, CLK_S0, 2, 1), DEF_FIXED("s0d3", R8A779F0_CLK_S0D3, CLK_S0, 3, 1), DEF_FIXED("s0d4", R8A779F0_CLK_S0D4, CLK_S0, 4, 1), diff --git a/drivers/clk/renesas/r8a779g0-cpg-mssr.c b/drivers/clk/renesas/r8a779g0-cpg-mssr.c index 54ba76ff5ab0..9a649f2524d9 100644 --- a/drivers/clk/renesas/r8a779g0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779g0-cpg-mssr.c @@ -96,7 +96,8 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = { DEF_FIXED(".vc", CLK_VC, CLK_PLL5_DIV2, 3, 1), /* Core Clock Outputs */ - DEF_GEN4_Z("z0", R8A779G0_CLK_Z0, CLK_TYPE_GEN4_Z, CLK_PLL2, 2, 0), + DEF_GEN4_Z("z0", R8A779G0_CLK_Z0, CLK_PLL2, 2, CPG_FRQCRC0, 0), + DEF_GEN4_Z("zg", R8A779G0_CLK_ZG, CLK_PLL4, 2, CPG_FRQCRB, 24), DEF_FIXED("s0d2", R8A779G0_CLK_S0D2, CLK_S0, 2, 1), DEF_FIXED("s0d3", R8A779G0_CLK_S0D3, CLK_S0, 3, 1), DEF_FIXED("s0d4", R8A779G0_CLK_S0D4, CLK_S0, 4, 1), @@ -163,6 +164,7 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = { }; static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = { + DEF_MOD("rgx", 0, R8A779G0_CLK_ZG), DEF_MOD("isp0", 16, R8A779G0_CLK_S0D2_VIO), DEF_MOD("isp1", 17, R8A779G0_CLK_S0D2_VIO), DEF_MOD("avb0", 211, R8A779G0_CLK_S0D4_HSC), diff --git a/drivers/clk/renesas/r8a779h0-cpg-mssr.c b/drivers/clk/renesas/r8a779h0-cpg-mssr.c index ffea06d77d5e..cde59cd35295 100644 --- a/drivers/clk/renesas/r8a779h0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779h0-cpg-mssr.c @@ -99,10 +99,10 @@ static const struct cpg_core_clk r8a779h0_core_clks[] __initconst = { DEF_RATE(".oco", CLK_OCO, 32768), /* Core Clock Outputs */ - DEF_GEN4_Z("zc0", R8A779H0_CLK_ZC0, CLK_TYPE_GEN4_Z, CLK_PLL2, 4, 0), - DEF_GEN4_Z("zc1", R8A779H0_CLK_ZC1, CLK_TYPE_GEN4_Z, CLK_PLL2, 4, 8), - DEF_GEN4_Z("zc2", R8A779H0_CLK_ZC2, CLK_TYPE_GEN4_Z, CLK_PLL2, 4, 32), - DEF_GEN4_Z("zc3", R8A779H0_CLK_ZC3, CLK_TYPE_GEN4_Z, CLK_PLL2, 4, 40), + DEF_GEN4_Z("zc0", R8A779H0_CLK_ZC0, CLK_PLL2, 4, CPG_FRQCRC0, 0), + DEF_GEN4_Z("zc1", R8A779H0_CLK_ZC1, CLK_PLL2, 4, CPG_FRQCRC0, 8), + DEF_GEN4_Z("zc2", R8A779H0_CLK_ZC2, CLK_PLL2, 4, CPG_FRQCRC1, 0), + DEF_GEN4_Z("zc3", R8A779H0_CLK_ZC3, CLK_PLL2, 4, CPG_FRQCRC1, 8), DEF_FIXED("s0d2", R8A779H0_CLK_S0D2, CLK_S0, 2, 1), DEF_FIXED("s0d3", R8A779H0_CLK_S0D3, CLK_S0, 3, 1), DEF_FIXED("s0d4", R8A779H0_CLK_S0D4, CLK_S0, 4, 1), diff --git a/drivers/clk/renesas/r8a78000-cpg.c b/drivers/clk/renesas/r8a78000-cpg.c index 7946f9d0b423..b8024e76743e 100644 --- a/drivers/clk/renesas/r8a78000-cpg.c +++ b/drivers/clk/renesas/r8a78000-cpg.c @@ -23,12 +23,14 @@ struct clk_map { enum fixed_clk { FIXED_CLK_66M, + FIXED_CLK_133M, FIXED_CLK_266M, NUM_FIXED_CLKS }; static const unsigned long fixed_clk_rates[NUM_FIXED_CLKS] = { [FIXED_CLK_66M] = 66666000, + [FIXED_CLK_133M] = 133330000, [FIXED_CLK_266M] = 266660000, }; @@ -140,6 +142,7 @@ static int r8a78000_cpg_probe(struct platform_device *pdev) static const struct clk_map r8a78000_cpg_default[] = { { R8A78000_CPG_SGASYNCD4_PERW_BUS, FIXED_CLK(266M) }, + { R8A78000_CPG_SGASYNCD8_PERW_BUS, FIXED_CLK(133M) }, { R8A78000_CPG_SGASYNCD16_PERW_BUS, FIXED_CLK(66M) }, { -1 } }; diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index 076f587dfd39..3df3f2b2c6de 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -1014,7 +1014,7 @@ r9a06g032_div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) if (clk->index == R9A06G032_DIV_UART || clk->index == R9A06G032_DIV_P2_PG) { pr_devel("%s div uart hack!\n", __func__); - req->rate = clk_get_rate(hw->clk); + req->rate = clk_hw_get_rate(hw); return 0; } req->rate = DIV_ROUND_UP(req->best_parent_rate, div); @@ -1419,10 +1419,4 @@ static struct platform_driver r9a06g032_clock_driver = { }, }; -static int __init r9a06g032_clocks_init(void) -{ - return platform_driver_probe(&r9a06g032_clock_driver, - r9a06g032_clocks_probe); -} - -subsys_initcall(r9a06g032_clocks_init); +subsys_platform_driver_probe(r9a06g032_clock_driver, r9a06g032_clocks_probe); diff --git a/drivers/clk/renesas/r9a07g043-cpg.c b/drivers/clk/renesas/r9a07g043-cpg.c index 59d6ee2e888f..f7e32abc5d0b 100644 --- a/drivers/clk/renesas/r9a07g043-cpg.c +++ b/drivers/clk/renesas/r9a07g043-cpg.c @@ -119,7 +119,7 @@ static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = { DEF_FIXED(".pll3_400", CLK_PLL3_400, CLK_PLL3, 1, 4), DEF_FIXED(".pll3_533", CLK_PLL3_533, CLK_PLL3, 1, 3), DEF_MUX_RO(".sel_pll3_3", CLK_SEL_PLL3_3, SEL_PLL3_3, sel_pll3_3), - DEF_DIV("divpl3c", CLK_DIV_PLL3_C, CLK_SEL_PLL3_3, DIVPL3C, dtable_1_32), + DEF_DIV(".divpl3c", CLK_DIV_PLL3_C, CLK_SEL_PLL3_3, DIVPL3C, dtable_1_32), #ifdef CONFIG_ARM64 DEF_FIXED(".pll5", CLK_PLL5, CLK_EXTAL, 125, 1), DEF_FIXED(".pll5_500", CLK_PLL5_500, CLK_PLL5, 1, 6), @@ -135,7 +135,7 @@ static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = { DEF_FIXED("P0_DIV2", R9A07G043_CLK_P0_DIV2, R9A07G043_CLK_P0, 1, 2), DEF_FIXED("TSU", R9A07G043_CLK_TSU, CLK_PLL2_DIV2_10, 1, 1), DEF_DIV("P1", R9A07G043_CLK_P1, CLK_PLL3_DIV2_4, DIVPL3B, dtable_1_32), - DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G043_CLK_P1, 1, 2), + DEF_FIXED(".p1_div2", CLK_P1_DIV2, R9A07G043_CLK_P1, 1, 2), DEF_DIV("P2", R9A07G043_CLK_P2, CLK_PLL3_DIV2_4_2, DIVPL3A, dtable_1_32), DEF_FIXED("M0", R9A07G043_CLK_M0, CLK_PLL3_DIV2_4, 1, 1), DEF_FIXED("ZT", R9A07G043_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1), @@ -151,12 +151,12 @@ static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = { mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier), DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, SEL_SDHI1_STS, sel_sdhi, mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier), - DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G043_CLK_SD0, 1, 4), - DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G043_CLK_SD1, 1, 4), + DEF_FIXED(".sd0_div4", CLK_SD0_DIV4, R9A07G043_CLK_SD0, 1, 4), + DEF_FIXED(".sd1_div4", CLK_SD1_DIV4, R9A07G043_CLK_SD1, 1, 4), #ifdef CONFIG_ARM64 DEF_FIXED("M2", R9A07G043_CLK_M2, CLK_PLL3_533, 1, 2), - DEF_FIXED("M2_DIV2", CLK_M2_DIV2, R9A07G043_CLK_M2, 1, 2), - DEF_DSI_DIV("DSI_DIV", CLK_DSI_DIV, CLK_PLL5_FOUTPOSTDIV, CLK_SET_RATE_PARENT), + DEF_FIXED(".m2_div2", CLK_M2_DIV2, R9A07G043_CLK_M2, 1, 2), + DEF_DSI_DIV(".dsi_div", CLK_DSI_DIV, CLK_PLL5_FOUTPOSTDIV, CLK_SET_RATE_PARENT), DEF_FIXED("M3", R9A07G043_CLK_M3, CLK_DSI_DIV, 1, 1), #endif }; diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 913cca6dd46f..3b6d0bd1ec13 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -187,7 +187,7 @@ static const struct { DEF_FIXED(".pll3_div2_4", CLK_PLL3_DIV2_4, CLK_PLL3_DIV2, 1, 4), DEF_FIXED(".pll3_div2_4_2", CLK_PLL3_DIV2_4_2, CLK_PLL3_DIV2_4, 1, 2), DEF_MUX_RO(".sel_pll3_3", CLK_SEL_PLL3_3, SEL_PLL3_3, sel_pll3_3), - DEF_DIV("divpl3c", CLK_DIV_PLL3_C, CLK_SEL_PLL3_3, DIVPL3C, dtable_1_32), + DEF_DIV(".divpl3c", CLK_DIV_PLL3_C, CLK_SEL_PLL3_3, DIVPL3C, dtable_1_32), DEF_FIXED(".pll5_250", CLK_PLL5_250, CLK_PLL5_FOUT3, 1, 2), DEF_FIXED(".pll6_250", CLK_PLL6_250, CLK_PLL6, 1, 2), @@ -204,7 +204,7 @@ static const struct { DEF_FIXED("P0_DIV2", R9A07G044_CLK_P0_DIV2, R9A07G044_CLK_P0, 1, 2), DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV2_10, 1, 1), DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4, DIVPL3B, dtable_1_32), - DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2), + DEF_FIXED(".p1_div2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2), DEF_DIV("P2", R9A07G044_CLK_P2, CLK_PLL3_DIV2_4_2, DIVPL3A, dtable_1_32), DEF_FIXED("M0", R9A07G044_CLK_M0, CLK_PLL3_DIV2_4, 1, 1), DEF_FIXED("ZT", R9A07G044_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1), @@ -215,13 +215,13 @@ static const struct { mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier), DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, SEL_SDHI1_STS, sel_sdhi, mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier), - DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4), - DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4), + DEF_FIXED(".sd0_div4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4), + DEF_FIXED(".sd1_div4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4), DEF_DIV("G", R9A07G044_CLK_G, CLK_SEL_GPU2, DIVGPU, dtable_1_8), DEF_FIXED("M1", R9A07G044_CLK_M1, CLK_PLL5_FOUTPOSTDIV, 1, 1), DEF_FIXED("M2", R9A07G044_CLK_M2, CLK_PLL3_533, 1, 2), - DEF_FIXED("M2_DIV2", CLK_M2_DIV2, R9A07G044_CLK_M2, 1, 2), - DEF_DSI_DIV("DSI_DIV", CLK_DSI_DIV, CLK_SEL_PLL5_4, CLK_SET_RATE_PARENT), + DEF_FIXED(".m2_div2", CLK_M2_DIV2, R9A07G044_CLK_M2, 1, 2), + DEF_DSI_DIV(".dsi_div", CLK_DSI_DIV, CLK_SEL_PLL5_4, CLK_SET_RATE_PARENT), DEF_FIXED("M3", R9A07G044_CLK_M3, CLK_DSI_DIV, 1, 1), DEF_FIXED("M4", R9A07G044_CLK_M4, CLK_DIV_DSI_LPCLK, 1, 1), }, diff --git a/drivers/clk/renesas/r9a08g045-cpg.c b/drivers/clk/renesas/r9a08g045-cpg.c index ea2a6a71aebd..4e1cd3177ecd 100644 --- a/drivers/clk/renesas/r9a08g045-cpg.c +++ b/drivers/clk/renesas/r9a08g045-cpg.c @@ -167,14 +167,14 @@ static const struct cpg_core_clk r9a08g045_core_clks[] __initconst = { DEF_FIXED("M0", R9A08G045_CLK_M0, CLK_PLL3_DIV2_4, 1, 1), DEF_G3S_DIV("P1", R9A08G045_CLK_P1, CLK_PLL3_DIV2_4, DIVPL3A, G3S_DIVPL3A_STS, dtable_1_32, 0, 0, 0, NULL), - DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A08G045_CLK_P1, 1, 2), + DEF_FIXED(".p1_div2", CLK_P1_DIV2, R9A08G045_CLK_P1, 1, 2), DEF_G3S_DIV("P2", R9A08G045_CLK_P2, CLK_PLL3_DIV2_8, DIVPL3B, G3S_DIVPL3B_STS, dtable_1_32, 0, 0, 0, NULL), 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(".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(".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), diff --git a/drivers/clk/renesas/r9a08g046-cpg.c b/drivers/clk/renesas/r9a08g046-cpg.c index 4488bd1988e8..b58057db9c4d 100644 --- a/drivers/clk/renesas/r9a08g046-cpg.c +++ b/drivers/clk/renesas/r9a08g046-cpg.c @@ -19,30 +19,32 @@ #define G3L_CPG_PL3_DDIV (0x208) #define G3L_CPG_SDHI_DDIV (0x218) #define G3L_CPG_GE3D_DDIV (0x224) +#define G3L_CPG_DSI_DDIV (0x228) #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_DSI_SSEL (0x408) #define G3L_CPG_GE3D_SSEL (0x40c) #define G3L_CPG_ETH_SSEL (0x410) #define G3L_CPG_RSCI_SSEL (0x414) #define G3L_CPG_RSPI_SSEL (0x418) +#define G3L_CPG_DSI_SDIV (0x430) #define G3L_CPG_ETH_SDIV (0x434) /* RZ/G3L Specific division configuration. */ #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_DIVPL3B DDIV_PACK(G3L_CPG_PL3_DDIV, 4, 2) #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) #define G3L_DIV_CA55_CORE3 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 12, 3) +#define G3L_DIV_DSI DDIV_PACK(G3L_CPG_DSI_DDIV, 0, 2) +#define G3L_DIV_GE3D DDIV_PACK(G3L_CPG_GE3D_DDIV, 0, 3) #define G3L_DIV_RSCI0 DDIV_PACK(G3L_CPG_RSCI_DDIV, 0, 2) #define G3L_DIV_RSCI1 DDIV_PACK(G3L_CPG_RSCI_DDIV, 2, 2) #define G3L_DIV_RSCI2 DDIV_PACK(G3L_CPG_RSCI_DDIV, 4, 2) @@ -50,6 +52,10 @@ #define G3L_DIV_RSPI0 DDIV_PACK(G3L_CPG_RSPI_DDIV, 0, 2) #define G3L_DIV_RSPI1 DDIV_PACK(G3L_CPG_RSPI_DDIV, 2, 2) #define G3L_DIV_RSPI2 DDIV_PACK(G3L_CPG_RSPI_DDIV, 4, 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_SDIV_DSI_C_SET DDIV_PACK(G3L_CPG_DSI_SDIV, 8, 1) #define G3L_SDIV_ETH_A DDIV_PACK(G3L_CPG_ETH_SDIV, 0, 2) #define G3L_SDIV_ETH_B DDIV_PACK(G3L_CPG_ETH_SDIV, 4, 1) #define G3L_SDIV_ETH_C DDIV_PACK(G3L_CPG_ETH_SDIV, 8, 2) @@ -59,6 +65,7 @@ #define G3L_DIVPL2A_STS DDIV_PACK(G3L_CLKDIVSTATUS, 4, 1) #define G3L_DIVPL2B_STS DDIV_PACK(G3L_CLKDIVSTATUS, 5, 1) #define G3L_DIVPL3A_STS DDIV_PACK(G3L_CLKDIVSTATUS, 8, 1) +#define G3L_DIVPL3B_STS DDIV_PACK(G3L_CLKDIVSTATUS, 9, 1) #define G3L_DIV_CA55_CORE0_STS DDIV_PACK(G3L_CLKDIVSTATUS, 12, 1) #define G3L_DIV_CA55_CORE1_STS DDIV_PACK(G3L_CLKDIVSTATUS, 13, 1) #define G3L_DIV_CA55_CORE2_STS DDIV_PACK(G3L_CLKDIVSTATUS, 14, 1) @@ -73,16 +80,15 @@ #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_DIV_GE3D_STS DDIV_PACK(G3L_CLKDIVSTATUS, 27, 1) +#define G3L_DIV_DSI_STS DDIV_PACK(G3L_CLKDIVSTATUS, 28, 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_DSI SEL_PLL_PACK(G3L_CPG_DSI_SSEL, 0, 1) #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) @@ -101,6 +107,9 @@ #define G3L_SEL_RSPI0 SEL_PLL_PACK(G3L_CPG_RSPI_SSEL, 0, 2) #define G3L_SEL_RSPI1 SEL_PLL_PACK(G3L_CPG_RSPI_SSEL, 2, 2) #define G3L_SEL_RSPI2 SEL_PLL_PACK(G3L_CPG_RSPI_SSEL, 4, 2) +#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) enum clk_ids { /* Core Clock Outputs exported to DT */ @@ -126,8 +135,11 @@ enum clk_ids { CLK_PLL3_DIV2, CLK_PLL3_DIV2_2, CLK_PLL3_DIV3, + CLK_PLL3_DIV6, CLK_PLL6, CLK_PLL6_DIV10, + CLK_PLL7, + CLK_PLL7_DSI_SDIV, CLK_SEL_ETH0_TX, CLK_SEL_ETH0_RX, CLK_SEL_ETH0_RM, @@ -149,6 +161,8 @@ enum clk_ids { CLK_ETH0_RM, CLK_ETH1_TR, CLK_ETH1_RM, + CLK_M2_DIV7, + CLK_P4_DIV2, CLK_SD0_DIV2, CLK_SD1_DIV2, CLK_SD2_DIV2, @@ -165,6 +179,12 @@ static const struct clk_div_table dtable_1_4[] = { { 0, 0 }, }; +static const struct clk_div_table dtable_1_2[] = { + { 0, 1 }, + { 1, 2 }, + { 0, 0 }, +}; + static const struct clk_div_table dtable_1_8[] = { { 0, 1 }, { 1, 2 }, @@ -220,7 +240,16 @@ static const struct clk_div_table dtable_8_256[] = { { 0, 0 }, }; +static const struct clk_div_table dtable_16_128[] = { + { 0, 16 }, + { 1, 32 }, + { 2, 64 }, + { 3, 128 }, + { 0, 0 }, +}; + /* Mux clock names tables. */ +static const char * const sel_dsi[] = { ".m2_div7", ".pll7_dsi_div"}; static const char * const sel_eth0_tx[] = { ".div_eth0_tr", "eth0_txc_tx_clk" }; static const char * const sel_eth0_rx[] = { ".div_eth0_tr", "eth0_rxc_rx_clk" }; static const char * const sel_eth0_rm[] = { ".pll6_div10", "eth0_rxc_rx_clk" }; @@ -254,6 +283,7 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { 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_G3L_PLLDSI(".pll7", CLK_PLL7, CLK_EXTAL, CPG_PLL_CONF(0x80, 0)), 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), @@ -262,6 +292,7 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { 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(".pll3_div6", CLK_PLL3_DIV6, CLK_PLL3, 1, 6), 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), @@ -277,10 +308,12 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { DEF_MUX(".sel_rspi0", CLK_SEL_RSPI0, G3L_SEL_RSPI0, sel_rsci_rspi), DEF_MUX(".sel_rspi1", CLK_SEL_RSPI1, G3L_SEL_RSPI1, sel_rsci_rspi), DEF_MUX(".sel_rspi2", CLK_SEL_RSPI2, G3L_SEL_RSPI2, sel_rsci_rspi), - DEF_MUX(".sel_eth0_tx", CLK_SEL_ETH0_TX, G3L_SEL_ETH0_TX, sel_eth0_tx), + DEF_MUX_FLAGS(".sel_eth0_tx", CLK_SEL_ETH0_TX, G3L_SEL_ETH0_TX, sel_eth0_tx, + CLK_SET_RATE_PARENT), DEF_MUX(".sel_eth0_rx", CLK_SEL_ETH0_RX, G3L_SEL_ETH0_RX, sel_eth0_rx), DEF_MUX(".sel_eth0_rm", CLK_SEL_ETH0_RM, G3L_SEL_ETH0_RM, sel_eth0_rm), - DEF_MUX(".sel_eth1_tx", CLK_SEL_ETH1_TX, G3L_SEL_ETH1_TX, sel_eth1_tx), + DEF_MUX_FLAGS(".sel_eth1_tx", CLK_SEL_ETH1_TX, G3L_SEL_ETH1_TX, sel_eth1_tx, + CLK_SET_RATE_PARENT), DEF_MUX(".sel_eth1_rx", CLK_SEL_ETH1_RX, G3L_SEL_ETH1_RX, sel_eth1_rx), DEF_MUX(".sel_eth1_rm", CLK_SEL_ETH1_RM, G3L_SEL_ETH1_RM, sel_eth1_rm), DEF_DIV(".div_eth0_tr", CLK_ETH0_TR, CLK_PLL6, G3L_SDIV_ETH_A, dtable_4_200), @@ -301,8 +334,13 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { dtable_8_256, 0, 0, 0, NULL), DEF_G3S_DIV("P1", R9A08G046_CLK_P1, CLK_PLL3_DIV2, G3L_DIVPL3A, G3L_DIVPL3A_STS, dtable_4_128, 0, 0, 0, NULL), + DEF_G3S_DIV("P2", R9A08G046_CLK_P2, CLK_PLL3_DIV2, G3L_DIVPL3B, G3L_DIVPL3B_STS, + dtable_8_256, 0, 0, 0, NULL), DEF_G3S_DIV("P3", R9A08G046_CLK_P3, CLK_PLL2_DIV2, G3L_DIVPL2A, G3L_DIVPL2A_STS, dtable_4_128, 0, 0, 0, NULL), + DEF_FIXED("P4", R9A08G046_CLK_P4, CLK_PLL2_DIV2, 1, 5), + DEF_FIXED(".p4_div2", CLK_P4_DIV2, R9A08G046_CLK_P4, 1, 2), + DEF_FIXED("P8", R9A08G046_CLK_P8, CLK_PLL3_DIV2, 1, 8), DEF_G3S_DIV("P13", R9A08G046_CLK_P13, CLK_SEL_RSCI0, G3L_DIV_RSCI0, G3L_DIV_RSCI0_STS, dtable_2_16, 0, 100000000UL, 0, NULL), DEF_G3S_DIV("P14", R9A08G046_CLK_P14, CLK_SEL_RSCI1, G3L_DIV_RSCI1, G3L_DIV_RSCI1_STS, @@ -317,6 +355,7 @@ 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_FIXED("P20", R9A08G046_CLK_P20, CLK_PLL2_DIV2, 1, 8), 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), @@ -329,6 +368,15 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { 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_G3S_DIV("M1", R9A08G046_CLK_M1, CLK_PLL2_DIV6, G3L_DIV_DSI, G3L_DIV_DSI_STS, + dtable_16_128, 0, 0, 0, NULL), + DEF_DIV_FLAGS("M2", R9A08G046_CLK_M2, CLK_PLL7, G3L_SDIV_DSI_C_SET, dtable_1_2, + CLK_SET_RATE_PARENT, CLK_DIVIDER_ROUND_CLOSEST), + DEF_G3L_LVDS_DIV(".m2_div7", CLK_M2_DIV7, R9A08G046_CLK_M2, 7), + DEF_G3L_DSI_DIV(".pll7_dsi_div", CLK_PLL7_DSI_SDIV, CLK_PLL7, G3L_CPG_DSI_SDIV), + DEF_G3L_SEL_DSI_MUX("M3", R9A08G046_CLK_M3, G3L_SEL_DSI, sel_dsi), + DEF_FIXED("M4", R9A08G046_CLK_M4, CLK_PLL7, 1, 1), + DEF_FIXED("M5", R9A08G046_CLK_M5, CLK_PLL3_DIV6, 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), @@ -347,6 +395,7 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = { 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), + DEF_FIXED("mipi_dsi_pllclk", R9A08G046_MIPI_DSI_PLLCLK, R9A08G046_CLK_M4, 1, 1), }; static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = { @@ -400,6 +449,22 @@ static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = { 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("mipi_dsi_sysclk", R9A08G046_MIPI_DSI_SYSCLK, R9A08G046_CLK_M5, 0x568, 1, + MSTOP(BUS_PERI_VIDEO, BIT(5) | BIT(6))), + DEF_MOD("mipi_dsi_aclk", R9A08G046_MIPI_DSI_ACLK, R9A08G046_CLK_P1, 0x568, 2, + MSTOP(BUS_PERI_VIDEO, BIT(5) | BIT(6))), + DEF_MOD("mipi_dsi_pclk", R9A08G046_MIPI_DSI_PCLK, R9A08G046_CLK_P2, 0x568, 3, + MSTOP(BUS_PERI_VIDEO, BIT(5) | BIT(6))), + DEF_MOD("mipi_dsi_vclk", R9A08G046_MIPI_DSI_VCLK, R9A08G046_CLK_M3, 0x568, 4, + MSTOP(BUS_PERI_VIDEO, BIT(5) | BIT(6))), + DEF_MOD("mipi_dsi_lpclk", R9A08G046_MIPI_DSI_LPCLK, R9A08G046_CLK_M1, 0x568, 5, + MSTOP(BUS_PERI_VIDEO, BIT(5) | BIT(6))), + DEF_MOD("lcdc_clk_a", R9A08G046_LCDC_CLK_A, R9A08G046_CLK_P1, 0x56c, 0, + MSTOP(BUS_PERI_VIDEO, BIT(7) | BIT(8) | BIT(9))), + DEF_MOD("lcdc_clk_d", R9A08G046_LCDC_CLK_D, R9A08G046_CLK_M3, 0x56c, 1, + MSTOP(BUS_PERI_VIDEO, BIT(7) | BIT(8) | BIT(9))), + DEF_MOD("lcdc_clk_p", R9A08G046_LCDC_CLK_P, R9A08G046_CLK_P2, 0x56c, 2, + MSTOP(BUS_PERI_VIDEO, BIT(7) | BIT(8) | BIT(9))), 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, @@ -498,8 +563,24 @@ static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = { MSTOP(BUS_MCPU1, BIT(15))), DEF_MOD("rspi2_tclk", R9A08G046_RSPI2_TCLK, R9A08G046_CLK_P19, 0x590, 10, MSTOP(BUS_MCPU2, BIT(0))), + DEF_MOD("canfd_pclk", R9A08G046_CANFD_PCLK, CLK_P4_DIV2, 0x594, 0, + MSTOP(BUS_MCPU2, BIT(9))), + DEF_MOD("canfd_clk_ram", R9A08G046_CANFD_CLK_RAM, R9A08G046_CLK_P4, 0x594, 1, + MSTOP(BUS_MCPU2, BIT(9))), DEF_MOD("gpio_hclk", R9A08G046_GPIO_HCLK, R9A08G046_OSCCLK, 0x598, 0, MSTOP(BUS_PERI_CPU, BIT(6))), + DEF_MOD("adc1_adclk", R9A08G046_ADC1_ADCLK, R9A08G046_CLK_P20, 0x5a8, 2, + MSTOP(BUS_PERI_VIDEO, BIT(14))), + DEF_MOD("adc1_pclk", R9A08G046_ADC1_PCLK, R9A08G046_CLK_P20, 0x5a8, 3, + MSTOP(BUS_PERI_VIDEO, BIT(14))), + DEF_MOD("tsu_pclk", R9A08G046_TSU_PCLK, R9A08G046_CLK_P20, 0x5ac, 0, + MSTOP(BUS_PERI_VIDEO, BIT(15))), + DEF_MOD("pci_aclk", R9A08G046_PCI_ACLK, R9A08G046_CLK_P1, 0x608, 0, + MSTOP(BUS_PERI_COM, BIT(10))), + DEF_MOD("pci_clkl1pm", R9A08G046_PCI_CLKL1PM, R9A08G046_CLK_P8, 0x608, 1, + MSTOP(BUS_PERI_COM, BIT(10))), + DEF_MOD("pci_clk_pmu", R9A08G046_PCI_CLK_PMU, R9A08G046_CLK_P1, 0x608, 2, + MSTOP(BUS_PERI_COM, BIT(10))), DEF_MOD("rsci0_pclk", R9A08G046_RSCI0_PCLK, R9A08G046_CLK_P0, 0x618, 0, MSTOP(BUS_MCPU2, BIT(7))), DEF_MOD("rsci1_pclk", R9A08G046_RSCI1_PCLK, R9A08G046_CLK_P0, 0x618, 1, @@ -516,6 +597,10 @@ static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = { MSTOP(BUS_MCPU3, BIT(11))), DEF_MOD("rsci3_tclk", R9A08G046_RSCI3_TCLK, R9A08G046_CLK_P16, 0x618, 11, MSTOP(BUS_MCPU3, BIT(12))), + DEF_MOD("lvds_pllclk", R9A08G046_LVDS_PLLCLK, R9A08G046_CLK_M2, 0x61c, 0, + MSTOP(BUS_PERI_VIDEO, BIT(11))), + DEF_MOD("lvds_clk_dot0", R9A08G046_LVDS_CLK_DOT0, R9A08G046_CLK_M3, 0x61c, 1, + MSTOP(BUS_PERI_VIDEO, BIT(11))), }; static const struct rzg2l_reset r9a08g046_resets[] = { @@ -537,6 +622,10 @@ static const struct rzg2l_reset r9a08g046_resets[] = { 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_MIPI_DSI_CMN_RSTB, 0x868, 0), + DEF_RST(R9A08G046_MIPI_DSI_ARESET_N, 0x868, 1), + DEF_RST(R9A08G046_MIPI_DSI_PRESET_N, 0x868, 2), + DEF_RST(R9A08G046_LCDC_RESET_N, 0x86c, 0), 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), @@ -564,9 +653,15 @@ static const struct rzg2l_reset r9a08g046_resets[] = { DEF_RST(R9A08G046_RSPI0_TRESETN, 0x890, 8), DEF_RST(R9A08G046_RSPI1_TRESETN, 0x890, 9), DEF_RST(R9A08G046_RSPI2_TRESETN, 0x890, 10), + DEF_RST(R9A08G046_CANFD_RSTP_N, 0x894, 0), + DEF_RST(R9A08G046_CANFD_RSTC_N, 0x894, 1), DEF_RST(R9A08G046_GPIO_RSTN, 0x898, 0), DEF_RST(R9A08G046_GPIO_PORT_RESETN, 0x898, 1), DEF_RST(R9A08G046_GPIO_SPARE_RESETN, 0x898, 2), + DEF_RST(R9A08G046_ADC1_PRESETN, 0x8a8, 2), + DEF_RST(R9A08G046_ADC1_ADRST_N, 0x8a8, 3), + DEF_RST(R9A08G046_TSU_PRESETN, 0x8ac, 0), + DEF_RST(R9A08G046_PCI_ARESETN, 0x908, 0), DEF_RST(R9A08G046_RSCI0_PRESETN, 0x918, 0), DEF_RST(R9A08G046_RSCI1_PRESETN, 0x918, 1), DEF_RST(R9A08G046_RSCI2_PRESETN, 0x918, 2), @@ -575,6 +670,7 @@ static const struct rzg2l_reset r9a08g046_resets[] = { DEF_RST(R9A08G046_RSCI1_TRESETN, 0x918, 9), DEF_RST(R9A08G046_RSCI2_TRESETN, 0x918, 10), DEF_RST(R9A08G046_RSCI3_TRESETN, 0x918, 11), + DEF_RST(R9A08G046_LVDS_RESET_N, 0x91c, 0), }; static const unsigned int r9a08g046_crit_mod_clks[] __initconst = { @@ -604,6 +700,7 @@ static const unsigned int r9a08g046_no_pm_mod_clks[] = { MOD_CLK_BASE + R9A08G046_ETH1_CLK_RMII_I, MOD_CLK_BASE + R9A08G046_ETH1_CLK_TX_I_RMII, MOD_CLK_BASE + R9A08G046_ETH1_CLK_RX_I_RMII, + MOD_CLK_BASE + R9A08G046_PCI_CLKL1PM, }; const struct rzg2l_cpg_info r9a08g046_cpg_info = { diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index 5640c2035e5a..5a0e7df1eb06 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -7,6 +7,8 @@ */ #include +#include +#include #include #include #include @@ -15,7 +17,11 @@ #include #include #include +#include #include +#include +#include +#include #include #include @@ -87,6 +93,20 @@ MODULE_IMPORT_NS("RZV2H_CPG"); #define CPG_PLL_MON(x) ((x) - 0x10) #define CPG_PLL_MON_LOCK BIT(0) +/* Size of each mapped CPG/MSSR register region (base0, base1) */ +#define RZT2H_CPG_REG_SIZE 0x20000 +/* This is the size of two SYSC regions combined */ +#define RZT2H_SYSC_SIZE 0x20000 +#define RZT2H_SYSC_OFFSET 0x10000 +#define RZT2H_SYSC_BLOCK_MASK BIT(16) +#define RZT2H_SYSC_OFFSET_MASK GENMASK(15, 0) +#define RZT2H_SYSC_BLOCK(x) FIELD_GET(RZT2H_SYSC_BLOCK_MASK, x) +#define RZT2H_SYSC_REG_OFFSET(x) FIELD_GET(RZT2H_SYSC_OFFSET_MASK, x) + +struct r9a09g077_sysc_reg { + void __iomem *base[2]; +}; + enum rzt2h_clk_types { CLK_TYPE_RZT2H_DIV = CLK_TYPE_CUSTOM, /* Clock with divider */ CLK_TYPE_RZT2H_MUX, /* Clock with clock source selector */ @@ -875,6 +895,126 @@ r9a09g077_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, } } +static int r9a09g077_regmap_read(void *context, unsigned int reg, unsigned int *val) +{ + struct r9a09g077_sysc_reg *sysc = context; + void __iomem *base = sysc->base[RZT2H_SYSC_BLOCK(reg)]; + + *val = readl(base + RZT2H_SYSC_REG_OFFSET(reg)); + + return 0; +} + +static int r9a09g077_regmap_write(void *context, unsigned int reg, unsigned int val) +{ + struct r9a09g077_sysc_reg *sysc = context; + void __iomem *base = sysc->base[RZT2H_SYSC_BLOCK(reg)]; + + writel(val, base + RZT2H_SYSC_REG_OFFSET(reg)); + + return 0; +} + +static const struct regmap_bus r9a09g077_sys_regmap_bus = { + .reg_write = r9a09g077_regmap_write, + .reg_read = r9a09g077_regmap_read, +}; + +static bool r9a09g077_writeable_readable_sysc(struct device *dev, unsigned int reg) +{ + unsigned int offset = RZT2H_SYSC_REG_OFFSET(reg); + + switch (RZT2H_SYSC_BLOCK(reg)) { + case 0: + switch (offset) { + /* ELOPA/B and GTIOCSEL */ + case 0x0000 ... 0x0008: + /* Encoder config */ + case 0x1000 ... 0x1164: + /* PCIe config */ + case 0x2000 ... 0x2024: + case 0x2030 ... 0x2054: + case 0x2060: + /* xSPI config */ + case 0x3000 ... 0x300C: + case 0x3100 ... 0x310C: + /* MD_MON */ + case 0x4100: + /* PRCRN */ + case 0x4200: + return true; + + default: + return false; + } + case 1: + switch (offset) { + /* WDTDCRm */ + case 0x5100 ... 0x5114: + /* PRCRS */ + case 0x6000: + return true; + + default: + return false; + } + default: + return false; + } +} + +static int r9a09g077_post_init(struct device *dev, struct cpg_mssr_pub *pub) +{ + struct regmap_config *regmap_cfg __free(kfree) = kzalloc_obj(*regmap_cfg); + struct r9a09g077_sysc_reg *sysc_reg; + struct regmap *regmap; + struct resource res; + int ret; + + /* + * Return early if the SYSC sizes are not as expected, for backwards + * compatibility with older device trees that only expose the 64 KiB + * CPG register window. + */ + ret = of_address_to_resource(dev->of_node, 0, &res); + if (ret) + return ret; + if (resource_size(&res) != RZT2H_CPG_REG_SIZE) + return 0; + + ret = of_address_to_resource(dev->of_node, 1, &res); + if (ret) + return ret; + if (resource_size(&res) != RZT2H_CPG_REG_SIZE) + return 0; + + if (!regmap_cfg) + return -ENOMEM; + + sysc_reg = devm_kzalloc(dev, sizeof(*sysc_reg), GFP_KERNEL); + if (!sysc_reg) + return -ENOMEM; + + /* Only allow access in the SYSC regions */ + sysc_reg->base[0] = pub->base0 + RZT2H_SYSC_OFFSET; + sysc_reg->base[1] = pub->base1 + RZT2H_SYSC_OFFSET; + + regmap_cfg->name = "rzt2h_sysc"; + regmap_cfg->reg_bits = 32; + regmap_cfg->reg_stride = 4; + regmap_cfg->val_bits = 32; + regmap_cfg->fast_io = true; + regmap_cfg->max_register = RZT2H_SYSC_SIZE - 1; + regmap_cfg->readable_reg = r9a09g077_writeable_readable_sysc; + regmap_cfg->writeable_reg = r9a09g077_writeable_readable_sysc; + + regmap = devm_regmap_init(dev, &r9a09g077_sys_regmap_bus, sysc_reg, regmap_cfg); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return of_syscon_register_regmap(dev->of_node, regmap); +} + const struct cpg_mssr_info r9a09g077_cpg_mssr_info = { /* Core Clocks */ .core_clks = r9a09g077_core_clks, @@ -889,4 +1029,6 @@ const struct cpg_mssr_info r9a09g077_cpg_mssr_info = { .reg_layout = CLK_REG_LAYOUT_RZ_T2H, .cpg_clk_register = r9a09g077_cpg_clk_register, + + .post_init = r9a09g077_post_init, }; diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index e5b503332217..bbb76e4fa333 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -36,7 +36,11 @@ #define CPG_PLLnCR_STC_MASK GENMASK(30, 24) /* PLL Circuit Mult. Ratio */ -#define CPG_RCKCR_CKSEL BIT(15) /* RCLK Clock Source Select */ +#define CPG_RPCCKCR 0x238 /* RPC-IF Clock Frequency Control Reg */ +#define CPG_RPCCKCR_DIV_RPCSRC GENMASK(4, 3) /* RPCSRC divider */ + +#define CPG_RCKCR_CKSEL BIT(15) /* RCLK Clock Source Select */ +#define CPG_RCKCR_DIV GENMASK(5, 0) /* RCLK Division Ratio */ /* PLL Clocks */ struct cpg_pll_clk { @@ -395,7 +399,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, * the multiplier value. */ value = readl(base + CPG_PLL4CR); - mult = (((value >> 24) & 0x7f) + 1) * 2; + mult = (FIELD_GET(CPG_PLLnCR_STC_MASK, value) + 1) * 2; break; case CLK_TYPE_GEN3_SDH: @@ -420,7 +424,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, * RINT is default. * Only if EXTALR is populated, we switch to it. */ - value = readl(csn->reg) & 0x3f; + value = readl(csn->reg) & CPG_RCKCR_DIV; if (clk_get_rate(clks[cpg_clk_extalr])) { parent = clks[cpg_clk_extalr]; @@ -496,9 +500,8 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, * MD[4:1] pins and CPG_RPCCKCR[4:3] register value for * which has been set prior to booting the kernel. */ - value = (readl(base + CPG_RPCCKCR) & GENMASK(4, 3)) >> 3; - - switch (value) { + value = readl(base + CPG_RPCCKCR); + switch (FIELD_GET(CPG_RPCCKCR_DIV_RPCSRC, value)) { case 0: div = 5; break; diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index d15a5d1df71c..fa25911b993e 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -76,8 +76,7 @@ struct rcar_gen3_cpg_pll_config { u8 osc_prediv; }; -#define CPG_RPCCKCR 0x238 -#define CPG_RCKCR 0x240 +#define CPG_RCKCR 0x240 /* RCLK Frequency Control Register */ struct clk *rcar_gen3_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, diff --git a/drivers/clk/renesas/rcar-gen4-cpg.c b/drivers/clk/renesas/rcar-gen4-cpg.c index 96922789e02a..dd973e4feb1b 100644 --- a/drivers/clk/renesas/rcar-gen4-cpg.c +++ b/drivers/clk/renesas/rcar-gen4-cpg.c @@ -259,10 +259,7 @@ static struct clk * __init cpg_pll_clk_register(const char *name, /* * Z0, Z1 and ZG Clock */ -#define CPG_FRQCRB 0x00000804 #define CPG_FRQCRB_KICK BIT(31) -#define CPG_FRQCRC0 0x00000808 -#define CPG_FRQCRC1 0x000008e0 struct cpg_z_clk { struct clk_hw hw; @@ -384,17 +381,17 @@ static struct clk * __init cpg_z_clk_register(const char *name, init.parent_names = &parent_name; init.num_parents = 1; - if (offset < 32) { - zclk->reg = reg + CPG_FRQCRC0; - } else if (offset < 64) { - zclk->reg = reg + CPG_FRQCRC1; - offset -= 32; - } else if (offset < 96) { - zclk->reg = reg + CPG_FRQCRB; - offset -= 64; - } else { - return ERR_PTR(-EINVAL); - } + /* + * offset 0xAAABB + * AAA : reg + * BB : pos + * + * see + * DEF_GEN4_Z() + */ + zclk->reg = reg + (offset >> FRQCR_offset); + offset &= 0x1f; /* 0 - 31 */ + zclk->kick_reg = reg + CPG_FRQCRB; zclk->hw.init = &init; zclk->mask = GENMASK(offset + 4, offset); diff --git a/drivers/clk/renesas/rcar-gen4-cpg.h b/drivers/clk/renesas/rcar-gen4-cpg.h index 6c8280b37c37..3556cf31ee8f 100644 --- a/drivers/clk/renesas/rcar-gen4-cpg.h +++ b/drivers/clk/renesas/rcar-gen4-cpg.h @@ -58,8 +58,15 @@ enum rcar_gen4_clk_types { #define DEF_GEN4_PLL_V9_24(_name, _idx, _id, _parent) \ DEF_BASE(_name, _id, CLK_TYPE_GEN4_PLL_V9_24, _parent, .offset = _idx) -#define DEF_GEN4_Z(_name, _id, _type, _parent, _div, _offset) \ - DEF_BASE(_name, _id, _type, _parent, .div = _div, .offset = _offset) +/* + * offset 0xAAABB + * AAA : reg + * BB : pos + */ +#define FRQCR_offset 8 +#define DEF_GEN4_Z(_name, _id, _parent, _div, reg, pos) \ + DEF_BASE(_name, _id, CLK_TYPE_GEN4_Z, _parent, .div = _div, \ + .offset = ((reg) << FRQCR_offset) | (pos)) struct rcar_gen4_cpg_pll_config { u8 extal_div; @@ -70,6 +77,9 @@ struct rcar_gen4_cpg_pll_config { u8 osc_prediv; }; +#define CPG_FRQCRB 0x804 /* Frequency Control Register B */ +#define CPG_FRQCRC0 0x808 /* Frequency Control Register C0 */ +#define CPG_FRQCRC1 0x8e0 /* Frequency Control Register C1 */ #define CPG_SD0CKCR 0x870 /* SD-IF0 Clock Frequency Control Register */ #define CPG_CANFDCKCR 0x878 /* CAN-FD Clock Frequency Control Register */ #define CPG_MSOCKCR 0x87c /* MSIOF Clock Frequency Control Register */ diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 80f4403ea2ba..ffac4409a161 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -944,6 +944,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a774a1_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A774A3 + { + .compatible = "renesas,r8a774a3-cpg-mssr", + .data = &r8a774a3_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A774B1 { .compatible = "renesas,r8a774b1-cpg-mssr", @@ -1414,6 +1420,9 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) error = cpg_mssr_reset_controller_register(priv); + if (!error && info->post_init) + error = info->post_init(priv->dev, &priv->pub); + reserve_exit: cpg_mssr_reserved_exit(priv); @@ -1428,12 +1437,7 @@ static struct platform_driver cpg_mssr_driver = { }, }; -static int __init cpg_mssr_init(void) -{ - return platform_driver_probe(&cpg_mssr_driver, cpg_mssr_probe); -} - -subsys_initcall(cpg_mssr_init); +subsys_platform_driver_probe(cpg_mssr_driver, cpg_mssr_probe); void __init mssr_mod_nullify(struct mssr_mod_clk *mod_clks, unsigned int num_mod_clks, diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index ad11ab5f0069..dc3015b3032d 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -178,6 +178,7 @@ struct cpg_mssr_info { /* Callbacks */ int (*init)(struct device *dev); + int (*post_init)(struct device *dev, struct cpg_mssr_pub *pub); struct clk *(*cpg_clk_register)(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, @@ -190,6 +191,7 @@ extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; extern const struct cpg_mssr_info r8a77470_cpg_mssr_info; extern const struct cpg_mssr_info r8a774a1_cpg_mssr_info; +extern const struct cpg_mssr_info r8a774a3_cpg_mssr_info; extern const struct cpg_mssr_info r8a774b1_cpg_mssr_info; extern const struct cpg_mssr_info r8a774c0_cpg_mssr_info; extern const struct cpg_mssr_info r8a774e1_cpg_mssr_info; diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index a899c37dd4cd..f6293c968bcf 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -67,6 +67,17 @@ #define CPG_PLL_MON_LOCK BIT(4) #define CPG_PLL_MON_RESETB BIT(0) +#define DIV_DSI_A_SET GENMASK(2, 0) +#define DIV_DSI_B_SET GENMASK(7, 4) + +#define RZG3L_SDIV_DIV_DSI_A_WEN BIT(16) +#define RZG3L_SDIV_DIV_DSI_B_WEN BIT(20) + +#define CPG_PLL_CLK1_DIV_NF GENMASK(12, 1) +#define CPG_PLL_CLK1_DIV_NI GENMASK(21, 13) +#define CPG_PLL_CLK1_DIV_M GENMASK(25, 22) +#define CPG_PLL_CLK1_DIV_P GENMASK(28, 26) + #define CLK_ON_R(reg) (reg) #define CLK_MON_R(reg) (0x180 + (reg)) #define CLK_RST_R(reg) (reg) @@ -92,6 +103,26 @@ #define PLL5_HSCLK_MIN 10000000 #define PLL5_HSCLK_MAX 187500000 +#define RZG3L_OSC_CLK (24 * MEGA) +#define RZG3L_PLL7_FDCO_RANGE_0_MIN (900 * MEGA) +#define RZG3L_PLL7_FDCO_RANGE_0_MAX (2000 * MEGA) +#define RZG3L_PLL7_FDCO_RANGE_1_MIN (2000 * MEGA) +#define RZG3L_PLL7_FDCO_RANGE_1_MAX (3000ULL * MEGA) +#define RZG3L_PLL7_PR_MIN (0) +#define RZG3L_PLL7_PR_MAX (4) +#define RZG3L_PLL7_MR_MIN (0) +#define RZG3L_PLL7_MR_MAX (11) +#define RZG3L_PLL7_NIR_MIN (55) +#define RZG3L_PLL7_NIR_MAX (374) +#define RZG3L_PLL7_NFR_MIN (0) +#define RZG3L_PLL7_NFR_MAX (4095) +#define RZG3L_PLL7_NR_MIN (56250) /* Multiplied value 56.25 * 1000 */ +#define RZG3L_PLL7_NR_MAX (375000) /* Multiplied value 375 * 1000 */ +#define RZG3L_PLL7_MULT_MIN (293) /* Multiplied value 0.293 * 1000 */ +#define RZG3L_PLL7_MULT_MAX (375000) /* Multiplied value 375 * 1000 */ +#define RZG3L_PLL7_FSTD_DIV_MR_MIN (8 * MEGA) +#define RZG3L_PLL7_FSTD_DIV_MR_MAX (16 * MEGA) + /** * struct clk_hw_data - clock hardware data * @hw: clock hw @@ -402,7 +433,7 @@ rzg3s_cpg_div_clk_register(const struct cpg_core_clk *core, struct rzg2l_cpg_pri return ERR_PTR(-ENOMEM); init.name = core->name; - init.flags = core->flag; + init.flags = core->core_flags; init.ops = &rzg3s_div_clk_ops; init.parent_names = &parent_name; init.num_parents = 1; @@ -456,20 +487,20 @@ rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core, if (core->dtable) clk_hw = clk_hw_register_divider_table(dev, core->name, - parent_name, 0, + parent_name, core->core_flags, base + GET_REG_OFFSET(core->conf), GET_SHIFT(core->conf), GET_WIDTH(core->conf), - core->flag, + core->div_flags, core->dtable, &priv->rmw_lock); else clk_hw = clk_hw_register_divider(dev, core->name, - parent_name, 0, + parent_name, core->core_flags, base + GET_REG_OFFSET(core->conf), GET_SHIFT(core->conf), GET_WIDTH(core->conf), - core->flag, &priv->rmw_lock); + core->div_flags, &priv->rmw_lock); if (IS_ERR(clk_hw)) return ERR_CAST(clk_hw); @@ -485,7 +516,7 @@ rzg2l_cpg_mux_clk_register(const struct cpg_core_clk *core, clk_hw = devm_clk_hw_register_mux(priv->dev, core->name, core->parent_names, core->num_parents, - core->flag, + core->core_flags, priv->base + GET_REG_OFFSET(core->conf), GET_SHIFT(core->conf), GET_WIDTH(core->conf), @@ -549,7 +580,7 @@ rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core, struct rzg2l_cpg_priv *priv) { struct sd_mux_hw_data *sd_mux_hw_data; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_hw *clk_hw; int ret; @@ -564,7 +595,7 @@ rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core, init.name = core->name; init.ops = &rzg2l_cpg_sd_clk_mux_ops; - init.flags = core->flag; + init.flags = core->core_flags; init.num_parents = core->num_parents; init.parent_names = core->parent_names; @@ -800,9 +831,9 @@ rzg2l_cpg_dsi_div_clk_register(const struct cpg_core_clk *core, struct rzg2l_cpg_priv *priv) { struct dsi_div_hw_data *clk_hw_data; + struct clk_init_data init = {}; const struct clk *parent; const char *parent_name; - struct clk_init_data init; struct clk_hw *clk_hw; int ret; @@ -833,6 +864,207 @@ rzg2l_cpg_dsi_div_clk_register(const struct cpg_core_clk *core, return clk_hw->clk; } +static int rzg3l_cpg_lvds_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + return clk_fixed_factor_ops.determine_rate(hw, req); +} + +static int rzg3l_cpg_lvds_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return clk_fixed_factor_ops.set_rate(hw, rate, parent_rate); +} + +static unsigned long rzg3l_cpg_lvds_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return clk_fixed_factor_ops.recalc_rate(hw, parent_rate); +} + +static unsigned long rzg3l_cpg_lvds_div_recalc_accuracy(struct clk_hw *hw, + unsigned long parent_accuracy) +{ + return clk_fixed_factor_ops.recalc_accuracy(hw, parent_accuracy); +} + +static int rzg3l_cpg_lvds_div_get_duty_cycle(struct clk_hw *hw, + struct clk_duty *duty) +{ + struct clk_fixed_factor *fix = to_clk_fixed_factor(hw); + + /* + * An odd divider cannot generate a 50% duty cycle: the output stays + * high for (div + 1) / 2 input clock cycles out of div, e.g. a divider + * of 7 gives a duty cycle of 4/7. + */ + duty->num = DIV_ROUND_UP(fix->div, 2); + duty->den = fix->div; + + return 0; +} + +static const struct clk_ops rzg3l_cpg_lvds_div_ops = { + .determine_rate = rzg3l_cpg_lvds_div_determine_rate, + .set_rate = rzg3l_cpg_lvds_div_set_rate, + .recalc_rate = rzg3l_cpg_lvds_div_recalc_rate, + .recalc_accuracy = rzg3l_cpg_lvds_div_recalc_accuracy, + .get_duty_cycle = rzg3l_cpg_lvds_div_get_duty_cycle, +}; + +static struct clk * __init +rzg3l_cpg_lvds_div_clk_register(const struct cpg_core_clk *core, + struct rzg2l_cpg_priv *priv) +{ + struct clk_init_data init = {}; + struct clk_fixed_factor *ff; + const struct clk *parent; + const char *parent_name; + int ret; + + parent = priv->clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + ff = devm_kzalloc(priv->dev, sizeof(*ff), GFP_KERNEL); + if (!ff) + return ERR_PTR(-ENOMEM); + + parent_name = __clk_get_name(parent); + init.name = core->name; + init.ops = &rzg3l_cpg_lvds_div_ops; + init.flags = CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; + + ff->hw.init = &init; + ff->mult = 1; + ff->div = core->conf; + + ret = devm_clk_hw_register(priv->dev, &ff->hw); + if (ret) + return ERR_PTR(ret); + + return ff->hw.clk; +} + +struct g3l_dsi_div_hw_data { + struct clk_hw hw; + struct rzg2l_cpg_priv *priv; + unsigned long rate; + u32 off; + u8 div_a; + u8 div_b; +}; + +#define to_g3l_dsi_div_hw_data(_hw) container_of(_hw, struct g3l_dsi_div_hw_data, hw) + +static unsigned long rzg3l_cpg_dsi_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct g3l_dsi_div_hw_data *dsi_div = to_g3l_dsi_div_hw_data(hw); + struct rzg2l_cpg_priv *priv = dsi_div->priv; + int div_a, div_b, val; + + val = readl(priv->base + dsi_div->off); + div_a = FIELD_GET(DIV_DSI_A_SET, val); + div_b = FIELD_GET(DIV_DSI_B_SET, val); + + return DIV_ROUND_CLOSEST_ULL((u64)parent_rate, (div_b + 1) << div_a); +} + +static int rzg3l_cpg_dsi_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct g3l_dsi_div_hw_data *dsi_div = to_g3l_dsi_div_hw_data(hw); + struct rzg2l_cpg_priv *priv = dsi_div->priv; + unsigned int divider = dsi_div_ab_desired; + unsigned int div_b_max = dsi_div_target ? 15 : 0; + bool divider_found = false; + + for (unsigned int i = 0; i <= 5 && !divider_found; i++) { + unsigned int div_a = 5 - i; + + for (unsigned int div_b = 0; div_b <= div_b_max; div_b++) { + divider = (div_b + 1) << div_a; + if (divider == dsi_div_ab_desired) { + dsi_div->div_a = div_a; + dsi_div->div_b = div_b; + divider_found = true; + break; + } + } + } + + if (!divider_found) { + dev_err(priv->dev, "failed dsi div for: %u\n", divider); + return -EINVAL; + } + + req->best_parent_rate = req->rate * divider; + + return 0; +} + +static int rzg3l_cpg_dsi_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct g3l_dsi_div_hw_data *dsi_div = to_g3l_dsi_div_hw_data(hw); + struct rzg2l_cpg_priv *priv = dsi_div->priv; + + writel(RZG3L_SDIV_DIV_DSI_A_WEN | RZG3L_SDIV_DIV_DSI_B_WEN | + FIELD_PREP(DIV_DSI_A_SET, dsi_div->div_a) | + FIELD_PREP(DIV_DSI_B_SET, dsi_div->div_b), + priv->base + dsi_div->off); + + return 0; +} + +static const struct clk_ops rzg3l_cpg_dsi_div_ops = { + .recalc_rate = rzg3l_cpg_dsi_div_recalc_rate, + .determine_rate = rzg3l_cpg_dsi_div_determine_rate, + .set_rate = rzg3l_cpg_dsi_div_set_rate, +}; + +static struct clk * __init +rzg3l_cpg_dsi_div_clk_register(const struct cpg_core_clk *core, + struct rzg2l_cpg_priv *priv) +{ + struct g3l_dsi_div_hw_data *clk_hw_data; + struct clk_init_data init = {}; + const struct clk *parent; + const char *parent_name; + struct clk_hw *clk_hw; + int ret; + + parent = priv->clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); + if (!clk_hw_data) + return ERR_PTR(-ENOMEM); + + clk_hw_data->priv = priv; + clk_hw_data->off = core->conf; + + parent_name = __clk_get_name(parent); + init.name = core->name; + init.ops = &rzg3l_cpg_dsi_div_ops; + init.flags = CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; + + clk_hw = &clk_hw_data->hw; + clk_hw->init = &init; + + ret = devm_clk_hw_register(priv->dev, clk_hw); + if (ret) + return ERR_PTR(ret); + + return clk_hw->clk; +} + struct pll5_mux_hw_data { struct clk_hw hw; u32 conf; @@ -896,7 +1128,7 @@ rzg2l_cpg_pll5_4_mux_clk_register(const struct cpg_core_clk *core, struct rzg2l_cpg_priv *priv) { struct pll5_mux_hw_data *clk_hw_data; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_hw *clk_hw; int ret; @@ -1023,8 +1255,8 @@ static struct clk * __init rzg2l_cpg_sipll5_register(const struct cpg_core_clk *core, struct rzg2l_cpg_priv *priv) { + struct clk_init_data init = {}; const struct clk *parent; - struct clk_init_data init; const char *parent_name; struct sipll5 *sipll5; struct clk_hw *clk_hw; @@ -1064,6 +1296,15 @@ rzg2l_cpg_sipll5_register(const struct cpg_core_clk *core, return clk_hw->clk; } +/* RZ/G3L PLL7 parameters */ +struct rzg3l_plldsi_parameters { + s64 error_millihz; + u64 freq_millihz; + u16 nir, nfr; + u8 rangesel; + u8 pr, mr; +}; + struct pll_clk { struct clk_hw hw; unsigned long default_rate; @@ -1071,6 +1312,7 @@ struct pll_clk { unsigned int type; void __iomem *base; struct rzg2l_cpg_priv *priv; + struct rzg3l_plldsi_parameters pll7_dsi_params; }; #define to_pll(_hw) container_of(_hw, struct pll_clk, hw) @@ -1139,9 +1381,9 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, struct rzg2l_cpg_priv *priv, const struct clk_ops *ops) { + struct clk_init_data init = {}; struct device *dev = priv->dev; const struct clk *parent; - struct clk_init_data init; const char *parent_name; struct pll_clk *pll_clk; int ret; @@ -1230,6 +1472,280 @@ static const struct clk_ops rzg3l_cpg_pll_ops = { .recalc_rate = rzg3s_cpg_pll_clk_recalc_rate, }; +static u8 rzg3l_cpg_dsi_smux_get_parent(struct clk_hw *hw) +{ + return clk_mux_ops.get_parent(hw); +} + +static int rzg3l_cpg_dsi_smux_set_parent(struct clk_hw *hw, u8 index) +{ + return clk_mux_ops.set_parent(hw, index); +} + +static int rzg3l_cpg_dsi_smux_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + return clk_mux_ops.determine_rate(hw, req); +} + +static int rzg3l_cpg_dsi_smux_set_duty_cycle(struct clk_hw *hw, + struct clk_duty *duty) +{ + struct clk_hw *parent_hw; + u8 parent_idx; + + /* + * Select parent based on requested duty cycle: + * - If duty > 50% (num/den > 1/2), select LVDS path (parent 0) + * - Otherwise, select DSI/RGB path (parent 1) + */ + if (duty->num * 2 > duty->den) + parent_idx = 0; + else + parent_idx = 1; + + if (parent_idx >= clk_hw_get_num_parents(hw)) + return -EINVAL; + + parent_hw = clk_hw_get_parent_by_index(hw, parent_idx); + if (!parent_hw) + return -EINVAL; + + return clk_hw_set_parent(hw, parent_hw); +} + +static const struct clk_ops rzg3l_cpg_dsi_smux_ops = { + .determine_rate = rzg3l_cpg_dsi_smux_determine_rate, + .get_parent = rzg3l_cpg_dsi_smux_get_parent, + .set_parent = rzg3l_cpg_dsi_smux_set_parent, + .set_duty_cycle = rzg3l_cpg_dsi_smux_set_duty_cycle, +}; + +static struct clk * __init +rzg3l_cpg_dsi_mux_clk_register(const struct cpg_core_clk *core, + struct rzg2l_cpg_priv *priv) +{ + struct clk_init_data init = {}; + struct clk_mux *mux_data; + int ret; + + mux_data = devm_kzalloc(priv->dev, sizeof(*mux_data), GFP_KERNEL); + if (!mux_data) + return ERR_PTR(-ENOMEM); + + init.name = core->name; + init.ops = &rzg3l_cpg_dsi_smux_ops; + init.flags = core->core_flags | CLK_SET_RATE_PARENT; + init.parent_names = core->parent_names; + init.num_parents = core->num_parents; + + mux_data->reg = priv->base + GET_REG_OFFSET(core->conf); + mux_data->shift = GET_SHIFT(core->conf); + mux_data->mask = clk_div_mask(GET_WIDTH(core->conf)); + mux_data->flags = core->mux_flags; + mux_data->lock = &priv->rmw_lock; + mux_data->hw.init = &init; + + ret = devm_clk_hw_register(priv->dev, &mux_data->hw); + if (ret) + return ERR_PTR(ret); + + return mux_data->hw.clk; +} + +static inline bool +rzg3l_dsi_compute_pll_parameters(struct rzg3l_plldsi_parameters *pars, + struct rzg3l_plldsi_parameters *p, + struct rzg3l_plldsi_parameters *best, + u64 freq_millihz, u32 fpfd, u32 pr) +{ + for (p->nir = RZG3L_PLL7_NIR_MIN; p->nir <= RZG3L_PLL7_NIR_MAX; p->nir++) { + u64 output_nir, output_nfr_range; + s64 nfr, output_nfr; + u64 fdco, output; + u64 nr_div_mr_pr; + + /* + * The frequency generated by the PLL is calculated as follows: + * + * With: + * Freq = Ffout = Ffdco / pr + * input frequency(fstd) = 24MHz + * fpfd = fstd / mr + * nr = nir + nfr / 4096 + * Ffdco = nr * fpfd + * Ffdco = (nir + (nfr / 4096)) * fpfd + * + * Freq can also be rewritten as: + * Freq = Ffdco / pr + * = (nir * fpfd) / pr + ((nfr / 4096) * fpfd) / pr + * = output_nir + output_nfr + * + * Every parameter has been determined at this point, but nfr. + * Considering that: + * 0 <= nfr <= 4095 + * Then: + * 0 <= (nfr / 4096) < 1 + * Therefore: + * 0 <= output_nfr < fpfd / pr + */ + + /* Compute output nir component (in mHz) */ + output_nir = DIV_ROUND_CLOSEST_ULL(mul_u32_u32((p->nir + 1) * MILLI, fpfd), pr); + /* Compute range for output nfr (in mHz) */ + output_nfr_range = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(fpfd, MILLI), pr); + /* No point in continuing if we can't achieve the desired frequency */ + if (freq_millihz < output_nir || freq_millihz >= (output_nir + output_nfr_range)) + continue; + + /* + * Compute the nfr component + * + * Since: + * Freq = output_nir + output_nfr + * Then: + * output_nfr = Freq - output_nir + * = ((nfr / 4096) * fpfd) / pr + * Therefore: + * nfr = (output_nfr * 4096 * pr) / fpfd + */ + output_nfr = freq_millihz - output_nir; + nfr = div_s64(output_nfr * 4096 * pr, fpfd); + nfr = DIV_S64_ROUND_CLOSEST(nfr, 1000); + + /* Validate nfr value within allowed limits */ + if (nfr < RZG3L_PLL7_NFR_MIN || nfr > RZG3L_PLL7_NFR_MAX) + continue; + + p->nfr = nfr; + + /* Compute (Ffdco * 4096) */ + output = mul_u32_u32(p->nir + 1, 4096); + fdco = (output + p->nfr) * fpfd; + if (fdco < (RZG3L_PLL7_FDCO_RANGE_0_MIN * 4096ULL) || + fdco > (RZG3L_PLL7_FDCO_RANGE_1_MAX * 4096ULL)) + continue; + + if (fdco <= (RZG3L_PLL7_FDCO_RANGE_0_MAX * 4096ULL)) + p->rangesel = 0; + else + p->rangesel = 1; + + /* compute the nr and magnify by 1000 */ + output = mul_u32_u32(p->nir + 1, 4096); + output += p->nfr; + output *= 1000; + nr_div_mr_pr = div_u64(output, 4096); + if (nr_div_mr_pr < RZG3L_PLL7_NR_MIN || nr_div_mr_pr > RZG3L_PLL7_NR_MAX) + continue; + + /* compute the magnified multipier = nr(magnified)/(mr *pr) */ + nr_div_mr_pr = div_u64(nr_div_mr_pr, (p->mr + 1) * pr); + if (nr_div_mr_pr < RZG3L_PLL7_MULT_MIN || nr_div_mr_pr > RZG3L_PLL7_MULT_MAX) + continue; + + output *= RZG3L_OSC_CLK; + output = div_u64(output, (p->mr + 1) * pr * 4096); + + 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(p->error_millihz) < abs(best->error_millihz)) + *best = *p; + } + + return false; +} + +static bool +rzg3l_dsi_get_pll_parameters_values(struct rzg3l_plldsi_parameters *pars, + u64 freq_millihz) +{ + struct rzg3l_plldsi_parameters p, best; + + /* Initialize best error to maximum possible value */ + best.error_millihz = S64_MAX; + p.error_millihz = S64_MAX; + for (p.mr = RZG3L_PLL7_MR_MIN; p.mr <= RZG3L_PLL7_MR_MAX; p.mr++) { + u32 fpfd = RZG3L_OSC_CLK / (p.mr + 1); + + if (fpfd > RZG3L_PLL7_FSTD_DIV_MR_MAX || fpfd < RZG3L_PLL7_FSTD_DIV_MR_MIN) + continue; + + for (p.pr = RZG3L_PLL7_PR_MIN; p.pr <= RZG3L_PLL7_PR_MAX; p.pr++) + if (rzg3l_dsi_compute_pll_parameters(pars, &p, &best, + freq_millihz, fpfd, 1 << p.pr)) + return true; + } + + /* If no valid parameters were found, return false */ + if (best.error_millihz == S64_MAX) + return false; + + *pars = best; + return true; +} + +static int rzg3l_cpg_plldsi_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzg2l_cpg_priv *priv = pll_clk->priv; + struct rzg3l_plldsi_parameters *pll7_dsi_params = &pll_clk->pll7_dsi_params; + u64 rate_millihz; + + rate_millihz = mul_u32_u32(req->rate, MILLI); + if (rate_millihz == pll7_dsi_params->error_millihz + pll7_dsi_params->freq_millihz) + goto exit_determine_rate; + + if (!rzg3l_dsi_get_pll_parameters_values(pll7_dsi_params, rate_millihz)) { + dev_err(priv->dev, "failed %s for req->rate: %lu\n", __func__, req->rate); + return -EINVAL; + } + +exit_determine_rate: + req->rate = DIV_ROUND_CLOSEST_ULL(pll7_dsi_params->freq_millihz, MILLI); + return 0; +} + +static int rzg3l_cpg_plldsi_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzg3l_plldsi_parameters *dsi_dividers = &pll_clk->pll7_dsi_params; + u32 val; + + /* Put PLL into standby mode */ + rzg3l_cpg_pll_clk_endisable(hw, false); + + /* Output clock setting 1 */ + val = FIELD_PREP(CPG_PLL_CLK1_DIV_P, dsi_dividers->pr) | + FIELD_PREP(CPG_PLL_CLK1_DIV_M, dsi_dividers->mr) | + FIELD_PREP(CPG_PLL_CLK1_DIV_NI, dsi_dividers->nir) | + FIELD_PREP(CPG_PLL_CLK1_DIV_NF, dsi_dividers->nfr) | + dsi_dividers->rangesel; + writel(val, pll_clk->base + CPG_PLL_CLK1_OFFSET(pll_clk->conf)); + + /* Put PLL to normal mode */ + rzg3l_cpg_pll_clk_endisable(hw, true); + + return 0; +}; + +static const struct clk_ops rzg3l_cpg_plldsi_ops = { + .recalc_rate = rzg3s_cpg_pll_clk_recalc_rate, + .determine_rate = rzg3l_cpg_plldsi_determine_rate, + .set_rate = rzg3l_cpg_plldsi_set_rate, + .is_enabled = rzg3l_cpg_pll_clk_is_enabled, + .enable = rzg3l_cpg_pll_clk_enable, +}; + static struct clk *rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec, void *data) @@ -1340,6 +1856,18 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, case CLK_TYPE_DSI_DIV: clk = rzg2l_cpg_dsi_div_clk_register(core, priv); break; + case CLK_TYPE_G3L_DSI_DIV: + clk = rzg3l_cpg_dsi_div_clk_register(core, priv); + break; + case CLK_TYPE_G3L_LVDS_DIV: + clk = rzg3l_cpg_lvds_div_clk_register(core, priv); + break; + case CLK_TYPE_G3L_PLLDSI: + clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg3l_cpg_plldsi_ops); + break; + case CLK_TYPE_G3L_DSI_MUX: + clk = rzg3l_cpg_dsi_mux_clk_register(core, priv); + break; default: goto fail; } @@ -1736,10 +2264,10 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, const struct rzg2l_cpg_info *info, struct rzg2l_cpg_priv *priv) { + struct clk_init_data init = {}; struct mod_clock *clock = NULL; struct device *dev = priv->dev; unsigned int id = mod->id; - struct clk_init_data init; struct clk *parent, *clk; const char *parent_name; unsigned int i; @@ -2230,11 +2758,6 @@ static struct platform_driver rzg2l_cpg_driver = { }, }; -static int __init rzg2l_cpg_init(void) -{ - return platform_driver_probe(&rzg2l_cpg_driver, rzg2l_cpg_probe); -} - -subsys_initcall(rzg2l_cpg_init); +subsys_platform_driver_probe(rzg2l_cpg_driver, rzg2l_cpg_probe); MODULE_DESCRIPTION("Renesas RZ/G2L CPG Driver"); diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h index bd6169f62538..81296046e353 100644 --- a/drivers/clk/renesas/rzg2l-cpg.h +++ b/drivers/clk/renesas/rzg2l-cpg.h @@ -110,8 +110,9 @@ struct cpg_core_clk { }; const char * const *parent_names; notifier_fn_t notifier; - u32 flag; + u32 core_flags; u32 mux_flags; + u32 div_flags; int num_parents; }; @@ -142,6 +143,17 @@ enum clk_types { /* Clock for DSI divider */ CLK_TYPE_DSI_DIV, + /* Clock for G3L DSI PLL */ + CLK_TYPE_G3L_PLLDSI, + + /* Clock for G3L DSI divider */ + CLK_TYPE_G3L_DSI_DIV, + + /* Clock for G3L LVDS divider */ + CLK_TYPE_G3L_LVDS_DIV, + + /* Clock for G3L DSI clock source selector */ + CLK_TYPE_G3L_DSI_MUX, }; #define DEF_TYPE(_name, _id, _type...) \ @@ -160,27 +172,31 @@ enum clk_types { DEF_TYPE(_name, _id, CLK_TYPE_IN) #define DEF_FIXED(_name, _id, _parent, _mult, _div) \ DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) -#define DEF_DIV(_name, _id, _parent, _conf, _dtable) \ +#define DEF_DIV_FLAGS(_name, _id, _parent, _conf, _dtable, _flags, _div_flags) \ DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \ .parent = _parent, .dtable = _dtable, \ - .flag = CLK_DIVIDER_HIWORD_MASK) + .core_flags = _flags, \ + .div_flags = CLK_DIVIDER_HIWORD_MASK | (_div_flags)) +#define DEF_DIV(_name, _id, _parent, _conf, _dtable) \ + DEF_DIV_FLAGS(_name, _id, _parent, _conf, _dtable, 0, 0) #define DEF_DIV_RO(_name, _id, _parent, _conf, _dtable) \ DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \ .parent = _parent, .dtable = _dtable, \ - .flag = CLK_DIVIDER_READ_ONLY) + .core_flags = 0, \ + .div_flags = CLK_DIVIDER_READ_ONLY) #define DEF_G3S_DIV(_name, _id, _parent, _conf, _sconf, _dtable, _invalid_rate, \ _max_rate, _clk_flags, _notif) \ DEF_TYPE(_name, _id, CLK_TYPE_G3S_DIV, .conf = _conf, .sconf = _sconf, \ .parent = _parent, .dtable = _dtable, \ .invalid_rate = _invalid_rate, \ - .max_rate = _max_rate, .flag = (_clk_flags), \ + .max_rate = _max_rate, .core_flags = (_clk_flags), \ .notifier = _notif) -#define DEF_MUX_FLAGS(_name, _id, _conf, _parent_names, _flag) \ +#define DEF_MUX_FLAGS(_name, _id, _conf, _parent_names, _flags) \ DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \ .parent_names = _parent_names, \ .num_parents = ARRAY_SIZE(_parent_names), \ .mux_flags = CLK_MUX_HIWORD_MASK, \ - .flag = _flag) + .core_flags = _flags) #define DEF_MUX(_name, _id, _conf, _parent_names) \ DEF_MUX_FLAGS(_name, _id, _conf, _parent_names, 0) #define DEF_MUX_RO(_name, _id, _conf, _parent_names) \ @@ -188,19 +204,34 @@ enum clk_types { .parent_names = _parent_names, \ .num_parents = ARRAY_SIZE(_parent_names), \ .mux_flags = CLK_MUX_READ_ONLY) +#define DEF_G3L_SEL_DSI_MUX(_name, _id, _conf, _parent_names) \ + DEF_TYPE(_name, _id, CLK_TYPE_G3L_DSI_MUX, .conf = _conf, \ + .parent_names = _parent_names, \ + .num_parents = ARRAY_SIZE(_parent_names), \ + .core_flags = CLK_SET_RATE_PARENT | CLK_DUTY_CYCLE_PARENT | \ + CLK_SET_RATE_NO_REPARENT, \ + .mux_flags = CLK_MUX_HIWORD_MASK) #define DEF_SD_MUX(_name, _id, _conf, _sconf, _parent_names, _mtable, _clk_flags, _notifier) \ DEF_TYPE(_name, _id, CLK_TYPE_SD_MUX, .conf = _conf, .sconf = _sconf, \ .parent_names = _parent_names, \ .num_parents = ARRAY_SIZE(_parent_names), \ - .mtable = _mtable, .flag = _clk_flags, .notifier = _notifier) + .mtable = _mtable, .core_flags = _clk_flags, .notifier = _notifier) #define DEF_PLL5_FOUTPOSTDIV(_name, _id, _parent) \ DEF_TYPE(_name, _id, CLK_TYPE_SIPLL5, .parent = _parent) #define DEF_PLL5_4_MUX(_name, _id, _conf, _parent_names) \ DEF_TYPE(_name, _id, CLK_TYPE_PLL5_4_MUX, .conf = _conf, \ .parent_names = _parent_names, \ .num_parents = ARRAY_SIZE(_parent_names)) -#define DEF_DSI_DIV(_name, _id, _parent, _flag) \ - DEF_TYPE(_name, _id, CLK_TYPE_DSI_DIV, .parent = _parent, .flag = _flag) +#define DEF_DSI_DIV(_name, _id, _parent, _flags) \ + DEF_TYPE(_name, _id, CLK_TYPE_DSI_DIV, .parent = _parent, .core_flags = _flags) +#define DEF_G3L_DSI_DIV(_name, _id, _parent, _conf) \ + DEF_TYPE(_name, _id, CLK_TYPE_G3L_DSI_DIV, .parent = _parent, .conf = _conf, \ + .core_flags = CLK_SET_RATE_PARENT) +#define DEF_G3L_LVDS_DIV(_name, _id, _parent, _conf) \ + DEF_TYPE(_name, _id, CLK_TYPE_G3L_LVDS_DIV, .parent = _parent, .conf = _conf, \ + .core_flags = CLK_SET_RATE_PARENT) +#define DEF_G3L_PLLDSI(_name, _id, _parent, _conf) \ + DEF_TYPE(_name, _id, CLK_TYPE_G3L_PLLDSI, .parent = _parent, .conf = _conf) /** * struct rzg2l_mod_clk - Module Clocks definitions diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index 917fc737f254..7ce94680c79a 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -99,7 +99,7 @@ struct rzv2h_pll_dsi_info { * @dev: CPG device * @base: CPG register block base address * @rmw_lock: protects register accesses - * @clks: Array containing all Core and Module Clocks + * @clks: Array containing all Core and Module clk_hw entries * @num_core_clks: Number of Core Clocks in clks[] * @num_mod_clks: Number of Module Clocks in clks[] * @resets: Array of resets @@ -115,7 +115,7 @@ struct rzv2h_cpg_priv { void __iomem *base; spinlock_t rmw_lock; - struct clk **clks; + struct clk_hw **clks; unsigned int num_core_clks; unsigned int num_mod_clks; struct rzv2h_reset *resets; @@ -332,14 +332,14 @@ static const struct clk_ops rzv2h_cpg_plldsi_div_ops = { .set_rate = rzv2h_cpg_plldsi_div_set_rate, }; -static struct clk * __init +static struct clk_hw * __init rzv2h_cpg_plldsi_div_clk_register(const struct cpg_core_clk *core, struct rzv2h_cpg_priv *priv) { struct rzv2h_plldsi_div_clk *clk_hw_data; - struct clk **clks = priv->clks; - struct clk_init_data init; - const struct clk *parent; + struct clk_hw **clks = priv->clks; + struct clk_init_data init = {}; + const struct clk_hw *parent; const char *parent_name; struct clk_hw *clk_hw; int ret; @@ -356,7 +356,7 @@ rzv2h_cpg_plldsi_div_clk_register(const struct cpg_core_clk *core, clk_hw_data->ddiv = core->cfg.ddiv; clk_hw_data->dtable = core->dtable; - parent_name = __clk_get_name(parent); + parent_name = clk_hw_get_name(parent); init.name = core->name; init.ops = &rzv2h_cpg_plldsi_div_ops; init.flags = core->flag; @@ -370,7 +370,7 @@ rzv2h_cpg_plldsi_div_clk_register(const struct cpg_core_clk *core, if (ret) return ERR_PTR(ret); - return clk_hw->clk; + return clk_hw; } static int rzv2h_cpg_plldsi_determine_rate(struct clk_hw *hw, @@ -577,12 +577,12 @@ static const struct clk_ops rzv2h_cpg_plldsi_smux_ops = { .set_duty_cycle = rzv2h_cpg_plldsi_smux_set_duty_cycle, }; -static struct clk * __init +static struct clk_hw * __init rzv2h_cpg_plldsi_smux_clk_register(const struct cpg_core_clk *core, struct rzv2h_cpg_priv *priv) { struct rzv2h_plldsi_mux_clk *clk_hw_data; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_hw *clk_hw; struct smuxed smux; int ret; @@ -620,7 +620,7 @@ rzv2h_cpg_plldsi_smux_clk_register(const struct cpg_core_clk *core, if (ret) return ERR_PTR(ret); - return clk_hw->clk; + return clk_hw; } static int rzv2h_cpg_pll_clk_is_enabled(struct clk_hw *hw) @@ -705,14 +705,14 @@ static const struct clk_ops rzv2h_cpg_pll_ops = { .recalc_rate = rzv2h_cpg_pll_clk_recalc_rate, }; -static struct clk * __init +static struct clk_hw * __init rzv2h_cpg_pll_clk_register(const struct cpg_core_clk *core, struct rzv2h_cpg_priv *priv, const struct clk_ops *ops) { struct device *dev = priv->dev; - struct clk_init_data init; - const struct clk *parent; + struct clk_init_data init = {}; + const struct clk_hw *parent; const char *parent_name; struct pll_clk *pll_clk; int ret; @@ -729,7 +729,7 @@ rzv2h_cpg_pll_clk_register(const struct cpg_core_clk *core, priv->pll_dsi_info[core->cfg.pll.instance].pll_dsi_limits = core->cfg.pll.limits; - parent_name = __clk_get_name(parent); + parent_name = clk_hw_get_name(parent); init.name = core->name; init.ops = ops; init.flags = 0; @@ -744,7 +744,7 @@ rzv2h_cpg_pll_clk_register(const struct cpg_core_clk *core, if (ret) return ERR_PTR(ret); - return pll_clk->hw.clk; + return &pll_clk->hw; } static unsigned long rzv2h_ddiv_recalc_rate(struct clk_hw *hw, @@ -820,7 +820,7 @@ static const struct clk_ops rzv2h_ddiv_clk_divider_ops = { .set_rate = rzv2h_ddiv_set_rate, }; -static struct clk * __init +static struct clk_hw * __init rzv2h_cpg_ddiv_clk_register(const struct cpg_core_clk *core, struct rzv2h_cpg_priv *priv) { @@ -829,7 +829,7 @@ rzv2h_cpg_ddiv_clk_register(const struct cpg_core_clk *core, struct device *dev = priv->dev; u8 shift = cfg_ddiv.shift; u8 width = cfg_ddiv.width; - const struct clk *parent; + const struct clk_hw *parent; const char *parent_name; struct clk_divider *div; struct ddiv_clk *ddiv; @@ -839,7 +839,7 @@ rzv2h_cpg_ddiv_clk_register(const struct cpg_core_clk *core, if (IS_ERR(parent)) return ERR_CAST(parent); - parent_name = __clk_get_name(parent); + parent_name = clk_hw_get_name(parent); if ((shift + width) > 16) return ERR_PTR(-EINVAL); @@ -872,15 +872,15 @@ rzv2h_cpg_ddiv_clk_register(const struct cpg_core_clk *core, if (ret) return ERR_PTR(ret); - return div->hw.clk; + return &div->hw; } -static struct clk * __init +static struct clk_hw * __init rzv2h_cpg_mux_clk_register(const struct cpg_core_clk *core, struct rzv2h_cpg_priv *priv) { struct smuxed mux = core->cfg.smux; - const struct clk_hw *clk_hw; + struct clk_hw *clk_hw; clk_hw = devm_clk_hw_register_mux(priv->dev, core->name, core->parent_names, core->num_parents, @@ -890,7 +890,7 @@ rzv2h_cpg_mux_clk_register(const struct cpg_core_clk *core, if (IS_ERR(clk_hw)) return ERR_CAST(clk_hw); - return clk_hw->clk; + return clk_hw; } static int @@ -906,14 +906,14 @@ rzv2h_clk_ff_mod_status_is_enabled(struct clk_hw *hw) return !!(val & bitmask); } -static struct clk * __init +static struct clk_hw * __init rzv2h_cpg_fixed_mod_status_clk_register(const struct cpg_core_clk *core, struct rzv2h_cpg_priv *priv) { struct rzv2h_ff_mod_status_clk *clk_hw_data; struct clk_init_data init = { }; struct clk_fixed_factor *fix; - const struct clk *parent; + const struct clk_hw *parent; const char *parent_name; int ret; @@ -922,10 +922,7 @@ rzv2h_cpg_fixed_mod_status_clk_register(const struct cpg_core_clk *core, if (IS_ERR(parent)) return ERR_CAST(parent); - parent_name = __clk_get_name(parent); - parent = priv->clks[core->parent]; - if (IS_ERR(parent)) - return ERR_CAST(parent); + parent_name = clk_hw_get_name(parent); clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); if (!clk_hw_data) @@ -949,18 +946,18 @@ rzv2h_cpg_fixed_mod_status_clk_register(const struct cpg_core_clk *core, if (ret) return ERR_PTR(ret); - return clk_hw_data->fix.hw.clk; + return &clk_hw_data->fix.hw; } -static struct clk +static struct clk_hw *rzv2h_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec, void *data) { unsigned int clkidx = clkspec->args[1]; struct rzv2h_cpg_priv *priv = data; struct device *dev = priv->dev; + struct clk_hw *clk_hw; const char *type; - struct clk *clk; switch (clkspec->args[0]) { case CPG_CORE: @@ -969,7 +966,7 @@ static struct clk dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); return ERR_PTR(-EINVAL); } - clk = priv->clks[clkidx]; + clk_hw = priv->clks[clkidx]; break; case CPG_MOD: @@ -978,7 +975,7 @@ static struct clk dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); return ERR_PTR(-EINVAL); } - clk = priv->clks[priv->num_core_clks + clkidx]; + clk_hw = priv->clks[priv->num_core_clks + clkidx]; break; default: @@ -986,25 +983,25 @@ static struct clk return ERR_PTR(-EINVAL); } - if (IS_ERR(clk)) + if (IS_ERR(clk_hw)) dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx, - PTR_ERR(clk)); + PTR_ERR(clk_hw)); else - dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", - clkspec->args[0], clkspec->args[1], clk, - clk_get_rate(clk)); - return clk; + dev_dbg(dev, "clock (%u, %u) is %s at %lu Hz\n", + clkspec->args[0], clkspec->args[1], + clk_hw_get_name(clk_hw), clk_hw_get_rate(clk_hw)); + return clk_hw; } static void __init rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core, struct rzv2h_cpg_priv *priv) { - struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent; + struct clk_hw *clk_hw = ERR_PTR(-EOPNOTSUPP), *parent; unsigned int id = core->id, div = core->div; struct device *dev = priv->dev; const char *parent_name; - struct clk_hw *clk_hw; + struct clk *clk; WARN_DEBUG(id >= priv->num_core_clks); WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); @@ -1012,70 +1009,72 @@ rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core, switch (core->type) { case CLK_TYPE_IN: clk = of_clk_get_by_name(priv->dev->of_node, core->name); + if (IS_ERR(clk)) { + clk_hw = ERR_CAST(clk); + goto fail; + } + clk_hw = __clk_get_hw(clk); break; case CLK_TYPE_FF: WARN_DEBUG(core->parent >= priv->num_core_clks); parent = priv->clks[core->parent]; if (IS_ERR(parent)) { - clk = parent; + clk_hw = parent; goto fail; } - parent_name = __clk_get_name(parent); + parent_name = clk_hw_get_name(parent); clk_hw = devm_clk_hw_register_fixed_factor(dev, core->name, parent_name, CLK_SET_RATE_PARENT, core->mult, div); - if (IS_ERR(clk_hw)) - clk = ERR_CAST(clk_hw); - else - clk = clk_hw->clk; break; case CLK_TYPE_FF_MOD_STATUS: if (!priv->ff_mod_status_ops) { priv->ff_mod_status_ops = devm_kzalloc(dev, sizeof(*priv->ff_mod_status_ops), GFP_KERNEL); if (!priv->ff_mod_status_ops) { - clk = ERR_PTR(-ENOMEM); + clk_hw = ERR_PTR(-ENOMEM); goto fail; } memcpy(priv->ff_mod_status_ops, &clk_fixed_factor_ops, sizeof(const struct clk_ops)); priv->ff_mod_status_ops->is_enabled = rzv2h_clk_ff_mod_status_is_enabled; } - clk = rzv2h_cpg_fixed_mod_status_clk_register(core, priv); + clk_hw = rzv2h_cpg_fixed_mod_status_clk_register(core, priv); break; case CLK_TYPE_PLL: - clk = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_pll_ops); + clk_hw = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_pll_ops); break; case CLK_TYPE_DDIV: - clk = rzv2h_cpg_ddiv_clk_register(core, priv); + clk_hw = rzv2h_cpg_ddiv_clk_register(core, priv); break; case CLK_TYPE_SMUX: - clk = rzv2h_cpg_mux_clk_register(core, priv); + clk_hw = rzv2h_cpg_mux_clk_register(core, priv); break; case CLK_TYPE_PLLDSI: - clk = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_plldsi_ops); + clk_hw = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_plldsi_ops); break; case CLK_TYPE_PLLDSI_DIV: - clk = rzv2h_cpg_plldsi_div_clk_register(core, priv); + clk_hw = rzv2h_cpg_plldsi_div_clk_register(core, priv); break; case CLK_TYPE_PLLDSI_SMUX: - clk = rzv2h_cpg_plldsi_smux_clk_register(core, priv); + clk_hw = rzv2h_cpg_plldsi_smux_clk_register(core, priv); break; default: goto fail; } - if (IS_ERR(clk)) + if (IS_ERR(clk_hw)) goto fail; - dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); - priv->clks[id] = clk; + dev_dbg(dev, "Core clock %s at %lu Hz\n", + clk_hw_get_name(clk_hw), clk_hw_get_rate(clk_hw)); + priv->clks[id] = clk_hw; return; fail: - dev_err(dev, "Failed to register core clock %s: %ld\n", - core->name, PTR_ERR(clk)); + dev_err(dev, "Failed to register core clock %s: %ld\n", core->name, + PTR_ERR(clk_hw)); } static void rzv2h_mod_clock_mstop_enable(struct rzv2h_cpg_priv *priv, @@ -1122,15 +1121,10 @@ static void rzv2h_mod_clock_mstop_disable(struct rzv2h_cpg_priv *priv, static int rzv2h_parent_clk_mux_to_index(struct clk_hw *hw) { - struct clk_hw *parent_hw; - struct clk *parent_clk; + struct clk_hw *parent_hw = clk_hw_get_parent(hw); struct clk_mux *mux; u32 val; - /* This will always succeed, so no need to check for IS_ERR() */ - parent_clk = clk_get_parent(hw->clk); - - parent_hw = __clk_get_hw(parent_clk); mux = to_clk_mux(parent_hw); val = readl(mux->reg) >> mux->shift; @@ -1229,9 +1223,9 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod, { struct mod_clock *clock = NULL; struct device *dev = priv->dev; - struct clk_init_data init; - struct clk *parent, *clk; + struct clk_init_data init = {}; const char *parent_name; + struct clk_hw *parent; unsigned int id; int ret; @@ -1242,13 +1236,13 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod, parent = priv->clks[mod->parent]; if (IS_ERR(parent)) { - clk = parent; + ret = PTR_ERR(parent); goto fail; } clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL); if (!clock) { - clk = ERR_PTR(-ENOMEM); + ret = -ENOMEM; goto fail; } @@ -1258,7 +1252,7 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod, if (mod->critical) init.flags |= CLK_IS_CRITICAL; - parent_name = __clk_get_name(parent); + parent_name = clk_hw_get_name(parent); init.parent_names = &parent_name; init.num_parents = 1; @@ -1273,12 +1267,10 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod, clock->mstop_data = mod->mstop_data; ret = devm_clk_hw_register(dev, &clock->hw); - if (ret) { - clk = ERR_PTR(ret); + if (ret) goto fail; - } - priv->clks[id] = clock->hw.clk; + priv->clks[id] = &clock->hw; /* * Ensure the module clocks and MSTOP bits are synchronized when they are @@ -1317,8 +1309,8 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod, return; fail: - dev_err(dev, "Failed to register module clock %s: %ld\n", - mod->name, PTR_ERR(clk)); + dev_err(dev, "Failed to register module clock %s: %d\n", mod->name, + ret); } static int __rzv2h_cpg_assert(struct reset_controller_dev *rcdev, @@ -1451,7 +1443,7 @@ static bool rzv2h_cpg_is_pm_clk(struct rzv2h_cpg_pd *pd, if (priv->clks[priv->num_core_clks + id] == ERR_PTR(-ENOENT)) return false; - clock = to_mod_clock(__clk_get_hw(priv->clks[priv->num_core_clks + id])); + clock = to_mod_clock(priv->clks[priv->num_core_clks + id]); return !clock->no_pm; } @@ -1550,19 +1542,13 @@ static int __init rzv2h_cpg_add_pm_domains(struct rzv2h_cpg_priv *priv) return of_genpd_add_provider_simple(np, &pd->genpd); } -static void rzv2h_cpg_del_clk_provider(void *data) -{ - of_clk_del_provider(data); -} - static int __init rzv2h_cpg_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; const struct rzv2h_cpg_info *info; struct rzv2h_cpg_priv *priv; unsigned int nclks, i; - struct clk **clks; + struct clk_hw **clks; int error; info = of_device_get_match_data(dev); @@ -1613,11 +1599,7 @@ static int __init rzv2h_cpg_probe(struct platform_device *pdev) for (i = 0; i < info->num_mod_clks; i++) rzv2h_cpg_register_mod_clk(&info->mod_clks[i], priv); - error = of_clk_add_provider(np, rzv2h_cpg_clk_src_twocell_get, priv); - if (error) - return error; - - error = devm_add_action_or_reset(dev, rzv2h_cpg_del_clk_provider, np); + error = devm_of_clk_add_hw_provider(dev, rzv2h_cpg_clk_src_twocell_get, priv); if (error) return error; @@ -1661,11 +1643,6 @@ static struct platform_driver rzv2h_cpg_driver = { }, }; -static int __init rzv2h_cpg_init(void) -{ - return platform_driver_probe(&rzv2h_cpg_driver, rzv2h_cpg_probe); -} - -subsys_initcall(rzv2h_cpg_init); +subsys_platform_driver_probe(rzv2h_cpg_driver, rzv2h_cpg_probe); MODULE_DESCRIPTION("Renesas RZ/V2H CPG Driver"); diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index 6205af9ba88a..eb6b8b878e4d 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -304,7 +304,7 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, int nrates, void __iomem *reg_base, spinlock_t *lock) { struct rockchip_cpuclk *cpuclk; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk *clk, *cclk; int ret; diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c index 81ae8a4ee30e..fbb702d0b9d9 100644 --- a/drivers/clk/rockchip/clk-ddr.c +++ b/drivers/clk/rockchip/clk-ddr.c @@ -97,7 +97,7 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, spinlock_t *lock) { struct rockchip_ddrclk *ddrclk; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk *clk; ddrclk = kzalloc_obj(*ddrclk); diff --git a/drivers/clk/rockchip/clk-gate-grf.c b/drivers/clk/rockchip/clk-gate-grf.c index 88e409e91a63..458314a25691 100644 --- a/drivers/clk/rockchip/clk-gate-grf.c +++ b/drivers/clk/rockchip/clk-gate-grf.c @@ -73,7 +73,7 @@ struct clk *rockchip_clk_register_gate_grf(const char *name, u8 gate_flags) { struct rockchip_gate_grf *gate; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk *clk; if (IS_ERR(regmap)) { diff --git a/drivers/clk/rockchip/clk-inverter.c b/drivers/clk/rockchip/clk-inverter.c index bf9072ed9fd4..e6c7dad60e96 100644 --- a/drivers/clk/rockchip/clk-inverter.c +++ b/drivers/clk/rockchip/clk-inverter.c @@ -75,8 +75,8 @@ struct clk *rockchip_clk_register_inverter(const char *name, void __iomem *reg, int shift, int flags, spinlock_t *lock) { - struct clk_init_data init; struct rockchip_inv_clock *inv_clock; + struct clk_init_data init = {}; struct clk *clk; inv_clock = kmalloc_obj(*inv_clock); diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c index 4efd22953f3e..d92bea75faf7 100644 --- a/drivers/clk/rockchip/clk-mmc-phase.c +++ b/drivers/clk/rockchip/clk-mmc-phase.c @@ -205,8 +205,8 @@ struct clk *rockchip_clk_register_mmc(const char *name, struct regmap *grf, int grf_reg, int shift) { - struct clk_init_data init; struct rockchip_mmc_clock *mmc_clock; + struct clk_init_data init = {}; struct clk *clk; int ret; diff --git a/drivers/clk/rockchip/clk-muxgrf.c b/drivers/clk/rockchip/clk-muxgrf.c index ccbb1379501a..ecdc77654813 100644 --- a/drivers/clk/rockchip/clk-muxgrf.c +++ b/drivers/clk/rockchip/clk-muxgrf.c @@ -59,7 +59,7 @@ struct clk *rockchip_clk_register_muxgrf(const char *name, int shift, int width, int mux_flags) { struct rockchip_muxgrf_clock *muxgrf_clock; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk *clk; if (IS_ERR(regmap)) { diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index 706ca4b344d3..7204b09243d4 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -1069,7 +1069,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, unsigned long flags, u8 clk_pll_flags) { const char *pll_parents[3]; - struct clk_init_data init; + struct clk_init_data init = {}; struct rockchip_clk_pll *pll; struct clk_mux *pll_mux; struct clk *pll_clk, *mux_clk; diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index ee8c79b938d3..10df21178ba4 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -257,7 +257,7 @@ static struct clk *rockchip_clk_register_frac_branch( if (child) { struct clk_mux *frac_mux = &frac->mux; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk *mux_clk; int ret; diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index b3c4ef4e0dbf..b3e994bd525d 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o obj-$(CONFIG_EXYNOS_CLKOUT) += clk-exynos-clkout.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos-arm64.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos2200.o +obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5515.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7870.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7885.o diff --git a/drivers/clk/samsung/clk-acpm.c b/drivers/clk/samsung/clk-acpm.c index 7680bc8c5275..e5a2d3ab34cb 100644 --- a/drivers/clk/samsung/clk-acpm.c +++ b/drivers/clk/samsung/clk-acpm.c @@ -21,6 +21,7 @@ struct acpm_clk { struct clk_hw hw; unsigned int mbox_chan_id; struct acpm_handle *handle; + const struct acpm_clk_driver_data *drv_data; }; struct acpm_clk_variant { @@ -31,6 +32,8 @@ struct acpm_clk_driver_data { const struct acpm_clk_variant *clks; unsigned int nr_clks; unsigned int mbox_chan_id; + /* For SoCs where ACPM firmware doesn't implement get_rate call */ + unsigned long (*get_rate)(struct clk_hw *clk, unsigned long parent_rate); }; #define to_acpm_clk(clk) container_of(clk, struct acpm_clk, hw) @@ -40,6 +43,18 @@ struct acpm_clk_driver_data { .name = cname, \ } +static const struct acpm_clk_variant exynos850_acpm_clks[] = { + ACPM_CLK("mif"), + ACPM_CLK("int"), + ACPM_CLK("cpucl0"), + ACPM_CLK("cpucl1"), + ACPM_CLK("g3d"), + ACPM_CLK("aud"), + ACPM_CLK("cam"), + ACPM_CLK("disp"), + ACPM_CLK("cp"), +}; + static const struct acpm_clk_variant gs101_acpm_clks[] = { ACPM_CLK("mif"), ACPM_CLK("int"), @@ -57,6 +72,19 @@ static const struct acpm_clk_variant gs101_acpm_clks[] = { ACPM_CLK("bo"), }; +static unsigned long bypass_acpm_exynos850_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate; +} + +static const struct acpm_clk_driver_data acpm_clk_exynos850 = { + .clks = exynos850_acpm_clks, + .nr_clks = ARRAY_SIZE(exynos850_acpm_clks), + .mbox_chan_id = 0, + .get_rate = bypass_acpm_exynos850_get_rate, +}; + static const struct acpm_clk_driver_data acpm_clk_gs101 = { .clks = gs101_acpm_clks, .nr_clks = ARRAY_SIZE(gs101_acpm_clks), @@ -68,6 +96,9 @@ static unsigned long acpm_clk_recalc_rate(struct clk_hw *hw, { struct acpm_clk *clk = to_acpm_clk(hw); + if (clk->drv_data->get_rate) + return clk->drv_data->get_rate(hw, parent_rate); + return clk->handle->ops->dvfs.get_rate(clk->handle, clk->mbox_chan_id, clk->id); } @@ -88,19 +119,30 @@ static const struct clk_ops acpm_clk_ops = { }; static int acpm_clk_register(struct device *dev, struct acpm_clk *aclk, - const char *name) + const char *name, const struct acpm_clk_driver_data *drv_data) { struct clk_init_data init = {}; + struct clk_parent_data pdata = {}; init.name = name; init.ops = &acpm_clk_ops; aclk->hw.init = &init; + /* If get_rate is set, the SoC relies on parent topology */ + if (drv_data->get_rate) { + pdata.fw_name = name; + init.parent_data = &pdata; + init.num_parents = 1; + init.flags = CLK_GET_RATE_NOCACHE; + } + return devm_clk_hw_register(dev, &aclk->hw); } static int acpm_clk_probe(struct platform_device *pdev) { + const struct acpm_clk_driver_data *drv_data; + const struct platform_device_id *id; struct acpm_handle *acpm_handle; struct clk_hw_onecell_data *clk_data; struct clk_hw **hws; @@ -114,8 +156,14 @@ static int acpm_clk_probe(struct platform_device *pdev) return dev_err_probe(dev, PTR_ERR(acpm_handle), "Failed to get acpm handle\n"); - count = acpm_clk_gs101.nr_clks; - mbox_chan_id = acpm_clk_gs101.mbox_chan_id; + id = platform_get_device_id(pdev); + if (!id || !id->driver_data) + return -ENODEV; + + drv_data = (const struct acpm_clk_driver_data *)id->driver_data; + + count = drv_data->nr_clks; + mbox_chan_id = drv_data->mbox_chan_id; clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count), GFP_KERNEL); @@ -136,14 +184,14 @@ static int acpm_clk_probe(struct platform_device *pdev) * The code assumes the clock IDs start from zero, * are sequential and do not have gaps. */ + aclk->drv_data = drv_data; aclk->id = i; aclk->handle = acpm_handle; aclk->mbox_chan_id = mbox_chan_id; hws[i] = &aclk->hw; - err = acpm_clk_register(dev, aclk, - acpm_clk_gs101.clks[i].name); + err = acpm_clk_register(dev, aclk, drv_data->clks[i].name, drv_data); if (err) return dev_err_probe(dev, err, "Failed to register clock\n"); @@ -154,7 +202,8 @@ static int acpm_clk_probe(struct platform_device *pdev) } static const struct platform_device_id acpm_clk_id[] = { - { .name = "gs101-acpm-clk" }, + { .name = "exynos850-acpm-clk", (kernel_ulong_t)&acpm_clk_exynos850 }, + { .name = "gs101-acpm-clk", (kernel_ulong_t)&acpm_clk_gs101 }, { } }; MODULE_DEVICE_TABLE(platform, acpm_clk_id); diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c index 37cf47533dc6..a17ce26494f3 100644 --- a/drivers/clk/samsung/clk-cpu.c +++ b/drivers/clk/samsung/clk-cpu.c @@ -647,7 +647,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, const struct clk_hw *parent, *alt_parent; struct clk_hw **hws; struct exynos_cpuclk *cpuclk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *parent_name; unsigned int num_cfgs; int ret = 0; diff --git a/drivers/clk/samsung/clk-exynos-clkout.c b/drivers/clk/samsung/clk-exynos-clkout.c index 5f64d93b2fac..9c8b17cb5e7c 100644 --- a/drivers/clk/samsung/clk-exynos-clkout.c +++ b/drivers/clk/samsung/clk-exynos-clkout.c @@ -214,7 +214,7 @@ static void exynos_clkout_remove(struct platform_device *pdev) iounmap(clkout->reg); } -static int __maybe_unused exynos_clkout_suspend(struct device *dev) +static int exynos_clkout_suspend(struct device *dev) { struct exynos_clkout *clkout = dev_get_drvdata(dev); @@ -223,7 +223,7 @@ static int __maybe_unused exynos_clkout_suspend(struct device *dev) return 0; } -static int __maybe_unused exynos_clkout_resume(struct device *dev) +static int exynos_clkout_resume(struct device *dev) { struct exynos_clkout *clkout = dev_get_drvdata(dev); @@ -232,13 +232,13 @@ static int __maybe_unused exynos_clkout_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(exynos_clkout_pm_ops, exynos_clkout_suspend, +static DEFINE_SIMPLE_DEV_PM_OPS(exynos_clkout_pm_ops, exynos_clkout_suspend, exynos_clkout_resume); static struct platform_driver exynos_clkout_driver = { .driver = { .name = DRV_NAME, - .pm = &exynos_clkout_pm_ops, + .pm = pm_sleep_ptr(&exynos_clkout_pm_ops), }, .probe = exynos_clkout_probe, .remove = exynos_clkout_remove, diff --git a/drivers/clk/samsung/clk-exynos5515.c b/drivers/clk/samsung/clk-exynos5515.c new file mode 100644 index 000000000000..ddcef5819034 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5515.c @@ -0,0 +1,1484 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2026 Aiden Isik + * Author: Aiden Isik + * + * Common Clock Framework support for Exynos5515 SoC. + */ + +#include +#include +#include + +#include + +#include "clk.h" +#include "clk-exynos-arm64.h" +#include "clk-pll.h" + +/* NOTE: Must be equal to the last clock ID increased by one */ +#define CLKS_NR_TOP (CLK_GOUT_CMU_PERI_UART + 1) +#define CLKS_NR_PERI (CLK_GOUT_PERI_USI00_I2C + 1) +#define CLKS_NR_FSYS (CLK_GOUT_FSYS_XIU_P_ACLK + 1) + +#define EXYNOS5515_GATE_DBG_OFFSET 0x4000 +#define EXYNOS5515_DRCG_EN_OFFSET 0x0104 +#define EXYNOS5515_MEMCLK_OFFSET 0x0108 + +/* ---- CMU_TOP ------------------------------------------------------------- */ + +/* + * CMU_TOP: 0x15410000 + * SYSREG_TOP: 0x15430000 + */ + +/* Register Offset definitions for CMU_TOP */ +#define PLL_LOCKTIME_PLL_AUD 0x0000 +#define PLL_LOCKTIME_PLL_SHARED0 0x0004 +#define PLL_LOCKTIME_PLL_SHARED1 0x0008 +#define PLL_CON3_PLL_AUD 0x010c +#define PLL_CON8_PLL_AUD 0x0120 +#define PLL_CON9_PLL_AUD 0x0124 +#define PLL_CON3_PLL_SHARED0 0x014c +#define PLL_CON8_PLL_SHARED0 0x0160 +#define PLL_CON9_PLL_SHARED0 0x0164 +#define PLL_CON3_PLL_SHARED1 0x018c +#define PLL_CON8_PLL_SHARED1 0x01a0 +#define PLL_CON9_PLL_SHARED1 0x01a4 +#define CMU_CMU_TOP_CONTROLLER_OPTION 0x0800 +#define CLK_CON_MUX_MUX_CLKCMU_APM_BUS 0x1000 +#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS 0x1004 +#define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS 0x1008 +#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_BUSP 0x100c +#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_CPU 0x1010 +#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG 0x1014 +#define CLK_CON_MUX_MUX_CLKCMU_DPU_AUDIF 0x1018 +#define CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_BUS 0x101c +#define CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_CPU 0x1020 +#define CLK_CON_MUX_MUX_CLKCMU_DPU_BUS 0x1024 +#define CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS 0x1028 +#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD 0x102c +#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD 0x1030 +#define CLK_CON_MUX_MUX_CLKCMU_FSYS_USB20DRD 0x1034 +#define CLK_CON_MUX_MUX_CLKCMU_G3D_BUS 0x1038 +#define CLK_CON_MUX_MUX_CLKCMU_MFC_BUS 0x103c +#define CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP 0x1040 +#define CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH 0x1044 +#define CLK_CON_MUX_MUX_CLKCMU_MODEM_SHARED1 0x1048 +#define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS 0x104c +#define CLK_CON_MUX_MUX_CLKCMU_PERI_IP 0x1050 +#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART 0x1054 +#define CLK_CON_MUX_MUX_CMU_CMUREF 0x1058 +#define CLK_CON_DIV_AP2CP_SHARED0_PLL_CLK 0x1800 +#define CLK_CON_DIV_AP2CP_SHARED1_PLL_CLK 0x1804 +#define CLK_CON_DIV_AP2CP_SHARED2_PLL_CLK 0x1808 +#define CLK_CON_DIV_CLKCMU_APM_BUS 0x180c +#define CLK_CON_DIV_CLKCMU_CMU_BOOST 0x1810 +#define CLK_CON_DIV_CLKCMU_CORE_BUS 0x1814 +#define CLK_CON_DIV_CLKCMU_CORE_SSS 0x1818 +#define CLK_CON_DIV_CLKCMU_CPUCL0_BUSP 0x181c +#define CLK_CON_DIV_CLKCMU_CPUCL0_CPU 0x1820 +#define CLK_CON_DIV_CLKCMU_CPUCL0_DBG 0x1824 +#define CLK_CON_DIV_CLKCMU_DPU_AUDIF 0x1828 +#define CLK_CON_DIV_CLKCMU_DPU_AUD_BUS 0x182c +#define CLK_CON_DIV_CLKCMU_DPU_AUD_CPU 0x1830 +#define CLK_CON_DIV_CLKCMU_DPU_BUS 0x1834 +#define CLK_CON_DIV_CLKCMU_FSYS_BUS 0x1838 +#define CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD 0x183c +#define CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD 0x1840 +#define CLK_CON_DIV_CLKCMU_FSYS_USB20DRD 0x1844 +#define CLK_CON_DIV_CLKCMU_G3D_BUS 0x1848 +#define CLK_CON_DIV_CLKCMU_MFC_BUS 0x184c +#define CLK_CON_DIV_CLKCMU_MIF_BUSP 0x1850 +#define CLK_CON_DIV_CLKCMU_PERI_BUS 0x1854 +#define CLK_CON_DIV_CLKCMU_PERI_IP 0x1858 +#define CLK_CON_DIV_CLKCMU_PERI_UART 0x185c +#define CLK_CON_DIV_DIV_CLK_CMU_CMUREF 0x1860 +#define CLK_CON_GAT_CLKCMU_MIF_SWITCH 0x2030 +#define CLK_CON_GAT_GATE_CLKCMU_APM_BUS 0x2034 +#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS 0x2038 +#define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS 0x203c +#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_BUSP 0x2040 +#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_CPU 0x2044 +#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG 0x2048 +#define CLK_CON_GAT_GATE_CLKCMU_DPU_AUDIF 0x204c +#define CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_BUS 0x2050 +#define CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_CPU 0x2054 +#define CLK_CON_GAT_GATE_CLKCMU_DPU_BUS 0x2058 +#define CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS 0x205c +#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD 0x2060 +#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD 0x2064 +#define CLK_CON_GAT_GATE_CLKCMU_FSYS_USB20DRD 0x2068 +#define CLK_CON_GAT_GATE_CLKCMU_G3D_BUS 0x206c +#define CLK_CON_GAT_GATE_CLKCMU_MFC_BUS 0x2070 +#define CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP 0x2074 +#define CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED0 0x2078 +#define CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED1 0x207c +#define CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED2 0x2080 +#define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS 0x2084 +#define CLK_CON_GAT_GATE_CLKCMU_PERI_IP 0x2088 +#define CLK_CON_GAT_GATE_CLKCMU_PERI_UART 0x208c + +static const unsigned long top_clk_regs[] __initconst = { + PLL_LOCKTIME_PLL_AUD, + PLL_LOCKTIME_PLL_SHARED0, + PLL_LOCKTIME_PLL_SHARED1, + PLL_CON3_PLL_AUD, + PLL_CON8_PLL_AUD, + PLL_CON9_PLL_AUD, + PLL_CON3_PLL_SHARED0, + PLL_CON8_PLL_SHARED0, + PLL_CON9_PLL_SHARED0, + PLL_CON3_PLL_SHARED1, + PLL_CON8_PLL_SHARED1, + PLL_CON9_PLL_SHARED1, + CMU_CMU_TOP_CONTROLLER_OPTION, + CLK_CON_MUX_MUX_CLKCMU_APM_BUS, + CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, + CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, + CLK_CON_MUX_MUX_CLKCMU_CPUCL0_BUSP, + CLK_CON_MUX_MUX_CLKCMU_CPUCL0_CPU, + CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG, + CLK_CON_MUX_MUX_CLKCMU_DPU_AUDIF, + CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_BUS, + CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_CPU, + CLK_CON_MUX_MUX_CLKCMU_DPU_BUS, + CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS, + CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD, + CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD, + CLK_CON_MUX_MUX_CLKCMU_FSYS_USB20DRD, + CLK_CON_MUX_MUX_CLKCMU_G3D_BUS, + CLK_CON_MUX_MUX_CLKCMU_MFC_BUS, + CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP, + CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH, + CLK_CON_MUX_MUX_CLKCMU_MODEM_SHARED1, + CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, + CLK_CON_MUX_MUX_CLKCMU_PERI_IP, + CLK_CON_MUX_MUX_CLKCMU_PERI_UART, + CLK_CON_MUX_MUX_CMU_CMUREF, + CLK_CON_DIV_AP2CP_SHARED0_PLL_CLK, + CLK_CON_DIV_AP2CP_SHARED1_PLL_CLK, + CLK_CON_DIV_AP2CP_SHARED2_PLL_CLK, + CLK_CON_DIV_CLKCMU_APM_BUS, + CLK_CON_DIV_CLKCMU_CMU_BOOST, + CLK_CON_DIV_CLKCMU_CORE_BUS, + CLK_CON_DIV_CLKCMU_CORE_SSS, + CLK_CON_DIV_CLKCMU_CPUCL0_BUSP, + CLK_CON_DIV_CLKCMU_CPUCL0_CPU, + CLK_CON_DIV_CLKCMU_CPUCL0_DBG, + CLK_CON_DIV_CLKCMU_DPU_AUDIF, + CLK_CON_DIV_CLKCMU_DPU_AUD_BUS, + CLK_CON_DIV_CLKCMU_DPU_AUD_CPU, + CLK_CON_DIV_CLKCMU_DPU_BUS, + CLK_CON_DIV_CLKCMU_FSYS_BUS, + CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD, + CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD, + CLK_CON_DIV_CLKCMU_FSYS_USB20DRD, + CLK_CON_DIV_CLKCMU_G3D_BUS, + CLK_CON_DIV_CLKCMU_MFC_BUS, + CLK_CON_DIV_CLKCMU_MIF_BUSP, + CLK_CON_DIV_CLKCMU_PERI_BUS, + CLK_CON_DIV_CLKCMU_PERI_IP, + CLK_CON_DIV_CLKCMU_PERI_UART, + CLK_CON_DIV_DIV_CLK_CMU_CMUREF, + CLK_CON_GAT_CLKCMU_MIF_SWITCH, + CLK_CON_GAT_GATE_CLKCMU_APM_BUS, + CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, + CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, + CLK_CON_GAT_GATE_CLKCMU_CPUCL0_BUSP, + CLK_CON_GAT_GATE_CLKCMU_CPUCL0_CPU, + CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG, + CLK_CON_GAT_GATE_CLKCMU_DPU_AUDIF, + CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_BUS, + CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_CPU, + CLK_CON_GAT_GATE_CLKCMU_DPU_BUS, + CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS, + CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD, + CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD, + CLK_CON_GAT_GATE_CLKCMU_FSYS_USB20DRD, + CLK_CON_GAT_GATE_CLKCMU_G3D_BUS, + CLK_CON_GAT_GATE_CLKCMU_MFC_BUS, + CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP, + CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED0, + CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED1, + CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED2, + CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, + CLK_CON_GAT_GATE_CLKCMU_PERI_IP, + CLK_CON_GAT_GATE_CLKCMU_PERI_UART, +}; + +static const struct samsung_pll_clock top_pll_clks[] __initconst = { + PLL(pll_309, CLK_FOUT_AUD_PLL, "fout_aud_pll", "oscclk", + PLL_LOCKTIME_PLL_AUD, PLL_CON3_PLL_AUD, NULL), + PLL(pll_309, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk", + PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, NULL), + PLL(pll_309, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk", + PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, NULL), +}; + +/* Parent clock list for CMU_TOP muxes */ +PNAME(mout_cmu_cmuref_p) = { "oscclk", + "dout_cmu_cmuref" }; + +/* Parent clock list for CMU_TOP muxes: for CMU_APM */ +PNAME(mout_cmu_apm_bus_p) = { "dout_shared0_div2", + "dout_shared0_div3" }; + +/* Parent clock list for CMU_TOP muxes: for CMU_CORE */ +PNAME(mout_cmu_core_bus_p) = { "dout_shared0_div2", + "dout_shared1_div3", + "dout_shared0_div3", + "dout_aud_div3" }; + +PNAME(mout_cmu_core_sss_p) = { "dout_shared0_div2", + "dout_shared1_div3", + "dout_shared0_div3", + "dout_aud_div3"}; + +/* Parent clock list for CMU_TOP muxes: for CMU_CPUCL0 */ +PNAME(mout_cmu_cpucl0_busp_p) = { "dout_shared0_div3", + "dout_shared0_div4" }; + +PNAME(mout_cmu_cpucl0_cpu_p) = { "fout_aud_pll", + "dout_shared1_div2", + "dout_shared0_div2", + "dout_shared1_div3", + "dout_aud_div2", + "dout_shared0_div3", + "dout_shared1_div4", + "dout_shared0_div4" }; + +PNAME(mout_cmu_cpucl0_dbg_p) = { "dout_shared0_div3", + "dout_shared0_div4" }; + +/* Parent clock list for CMU_TOP muxes: for CMU_DPU */ +PNAME(mout_cmu_dpu_audif_p) = { "dout_aud_div2", + "dout_aud_div3" }; + +PNAME(mout_cmu_dpu_aud_bus_p) = { "dout_aud_div2", + "dout_shared0_div3", + "dout_aud_div3", + "dout_shared0_div4" }; + +PNAME(mout_cmu_dpu_aud_cpu_p) = { "fout_aud_pll", + "dout_shared1_div2", + "dout_shared0_div2", + "dout_shared1_div3", + "dout_aud_div2", + "dout_shared0_div3", + "dout_aud_div3", + "dout_aud_div4" }; + +PNAME(mout_cmu_dpu_bus_p) = { "dout_shared1_div3", + "dout_shared0_div3", + "dout_shared0_div4" }; + +/* Parent clock list for CMU_TOP muxes: for CMU_FSYS */ +PNAME(mout_cmu_fsys_bus_p) = { "dout_shared0_div2", + "dout_shared1_div3" }; + +PNAME(mout_cmu_fsys_mmc_card_p) = { "oscclk", + "dout_shared0_div2", + "dout_shared1_div3", + "dout_shared0_div3", + "dout_aud_div2" }; + +PNAME(mout_cmu_fsys_mmc_embd_p) = { "oscclk", + "dout_shared0_div2", + "dout_shared1_div3", + "dout_shared0_div3", + "dout_aud_div2" }; + +PNAME(mout_cmu_fsys_usb20drd_p) = { "oscclk", + "dout_shared0_div4" }; + +/* Parent clock list for CMU_TOP muxes: for CMU_G3D */ +PNAME(mout_cmu_g3d_bus_p) = { "dout_shared1_div2", + "dout_shared0_div2", + "dout_shared1_div3", + "dout_shared0_div3" }; + +/* Parent clock list for CMU_TOP muxes: for CMU_MFC */ +PNAME(mout_cmu_mfc_bus_p) = { "dout_shared1_div3", + "dout_shared0_div3", + "dout_shared1_div4", + "dout_shared0_div4" }; + +/* Parent clock list for CMU_TOP muxes: for CMU_MIF */ +PNAME(mout_cmu_mif_busp_p) = { "dout_shared0_div3", + "dout_shared0_div4" }; + +PNAME(mout_cmu_mif_switch_p) = { "fout_shared1_pll", + "fout_shared0_pll", + "dout_shared1_div2", + "dout_shared0_div2", + "dout_shared1_div3", + "dout_shared0_div3", + "dout_shared1_div4", + "dout_shared0_div4" }; + +/* Parent clock list for CMU_TOP muxes: for CMU_MODEM */ +PNAME(mout_cmu_modem_shared1_p) = { "dout_shared1_div2", + "dout_aud_div2", + "dout_shared1_div3", + "dout_shared0_div3" }; + +/* Parent clock list for CMU_TOP muxes: for CMU_PERI */ +PNAME(mout_cmu_peri_bus_p) = { "dout_shared0_div3", + "dout_shared0_div4" }; + +PNAME(mout_cmu_peri_ip_p) = { "oscclk", + "dout_shared0_div4", + "dout_shared1_div4", + "dout_aud_div3" }; + +PNAME(mout_cmu_peri_uart_p) = { "oscclk", + "dout_shared0_div4", + "dout_shared1_div4", + "dout_aud_div3" }; + +static const struct samsung_mux_clock top_mux_clks[] __initconst = { + /* APM (Active Power Management) */ + MUX(CLK_MOUT_CMU_APM_BUS, "mout_cmu_apm_bus", + mout_cmu_apm_bus_p, + CLK_CON_MUX_MUX_CLKCMU_APM_BUS, + 0, 1), + + /* CMU (Clock Management Unit) */ + MUX(CLK_MOUT_CMU_CMUREF, "mout_cmu_cmuref", + mout_cmu_cmuref_p, + CLK_CON_MUX_MUX_CMU_CMUREF, + 0, 1), + + /* CORE */ + MUX(CLK_MOUT_CMU_CORE_BUS, "mout_cmu_core_bus", + mout_cmu_core_bus_p, + CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, + 0, 2), + MUX(CLK_MOUT_CMU_CORE_SSS, "mout_cmu_core_sss", + mout_cmu_core_sss_p, + CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, + 0, 2), + + /* CPUCL0 (CPU Cluster 0) */ + MUX(CLK_MOUT_CMU_CPUCL0_BUSP, "mout_cmu_cpucl0_busp", + mout_cmu_cpucl0_busp_p, + CLK_CON_MUX_MUX_CLKCMU_CPUCL0_BUSP, + 0, 1), + MUX(CLK_MOUT_CMU_CPUCL0_CPU, "mout_cmu_cpucl0_cpu", + mout_cmu_cpucl0_cpu_p, + CLK_CON_MUX_MUX_CLKCMU_CPUCL0_CPU, + 0, 3), + MUX(CLK_MOUT_CMU_CPUCL0_DBG, "mout_cmu_cpucl0_dbg", + mout_cmu_cpucl0_dbg_p, + CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG, + 0, 1), + + /* DPU (Display Processing Unit) */ + MUX(CLK_MOUT_CMU_DPU_AUDIF, "mout_cmu_dpu_audif", + mout_cmu_dpu_audif_p, + CLK_CON_MUX_MUX_CLKCMU_DPU_AUDIF, + 0, 1), + MUX(CLK_MOUT_CMU_DPU_AUD_BUS, "mout_cmu_dpu_aud_bus", + mout_cmu_dpu_aud_bus_p, + CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_BUS, + 0, 2), + MUX(CLK_MOUT_CMU_DPU_AUD_CPU, "mout_cmu_dpu_aud_cpu", + mout_cmu_dpu_aud_cpu_p, + CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_CPU, + 0, 3), + MUX(CLK_MOUT_CMU_DPU_BUS, "mout_cmu_dpu_bus", + mout_cmu_dpu_bus_p, + CLK_CON_MUX_MUX_CLKCMU_DPU_BUS, + 0, 2), + + /* FSYS */ + MUX(CLK_MOUT_CMU_FSYS_BUS, "mout_cmu_fsys_bus", + mout_cmu_fsys_bus_p, + CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS, + 0, 1), + MUX(CLK_MOUT_CMU_FSYS_MMC_CARD, "mout_cmu_fsys_mmc_card", + mout_cmu_fsys_mmc_card_p, + CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD, + 0, 3), + MUX(CLK_MOUT_CMU_FSYS_MMC_EMBD, "mout_cmu_fsys_mmc_embd", + mout_cmu_fsys_mmc_embd_p, + CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD, + 0, 3), + MUX(CLK_MOUT_CMU_FSYS_USB20DRD, "mout_cmu_fsys_usb20drd", + mout_cmu_fsys_usb20drd_p, + CLK_CON_MUX_MUX_CLKCMU_FSYS_USB20DRD, + 0, 1), + + /* G3D */ + MUX(CLK_MOUT_CMU_G3D_BUS, "mout_cmu_g3d_bus", + mout_cmu_g3d_bus_p, + CLK_CON_MUX_MUX_CLKCMU_G3D_BUS, + 0, 2), + + /* MFC */ + MUX(CLK_MOUT_CMU_MFC_BUS, "mout_cmu_mfc_bus", + mout_cmu_mfc_bus_p, + CLK_CON_MUX_MUX_CLKCMU_MFC_BUS, + 0, 2), + + /* MIF */ + MUX(CLK_MOUT_CMU_MIF_BUSP, "mout_cmu_mif_busp", + mout_cmu_mif_busp_p, + CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP, + 0, 1), + MUX(CLK_MOUT_CMU_MIF_SWITCH, "mout_cmu_mif_switch", + mout_cmu_mif_switch_p, + CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH, + 0, 3), + + /* MODEM */ + MUX(CLK_MOUT_CMU_MODEM_SHARED1, "mout_cmu_modem_shared1", + mout_cmu_modem_shared1_p, + CLK_CON_MUX_MUX_CLKCMU_MODEM_SHARED1, + 0, 2), + + /* PERI */ + MUX(CLK_MOUT_CMU_PERI_BUS, "mout_cmu_peri_bus", + mout_cmu_peri_bus_p, + CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, + 0, 1), + MUX(CLK_MOUT_CMU_PERI_IP, "mout_cmu_peri_ip", + mout_cmu_peri_ip_p, + CLK_CON_MUX_MUX_CLKCMU_PERI_IP, + 0, 2), + MUX(CLK_MOUT_CMU_PERI_UART, "mout_cmu_peri_uart", + mout_cmu_peri_uart_p, + CLK_CON_MUX_MUX_CLKCMU_PERI_UART, + 0, 2), +}; + +static const struct samsung_div_clock top_div_clks[] __initconst = { + /* APM */ + DIV(CLK_DOUT_CMU_APM_BUS, "dout_cmu_apm_bus", + "gout_cmu_apm_bus", + CLK_CON_DIV_CLKCMU_APM_BUS, + 0, 3), + + /* CMU */ + DIV(CLK_DOUT_CMU_CMU_BOOST, "dout_cmu_cmu_boost", + "fout_shared0_pll", + CLK_CON_DIV_CLKCMU_CMU_BOOST, + 0, 3), + DIV(CLK_DOUT_CMU_CMUREF, "dout_cmu_cmuref", + "fout_shared0_pll", + CLK_CON_DIV_DIV_CLK_CMU_CMUREF, + 0, 2), + + /* CORE */ + DIV(CLK_DOUT_CMU_CORE_BUS, "dout_cmu_core_bus", + "gout_cmu_core_bus", + CLK_CON_DIV_CLKCMU_CORE_BUS, + 0, 4), + DIV(CLK_DOUT_CMU_CORE_SSS, "dout_cmu_core_sss", + "gout_cmu_core_sss", + CLK_CON_DIV_CLKCMU_CORE_SSS, + 0, 4), + + /* CPUCL0 */ + DIV(CLK_DOUT_CMU_CPUCL0_BUSP, "dout_cmu_cpucl0_busp", + "gout_cmu_cpucl0_busp", + CLK_CON_DIV_CLKCMU_CPUCL0_BUSP, + 0, 3), + DIV(CLK_DOUT_CMU_CPUCL0_CPU, "dout_cmu_cpucl0_cpu", + "gout_cmu_cpucl0_cpu", + CLK_CON_DIV_CLKCMU_CPUCL0_CPU, + 0, 3), + DIV(CLK_DOUT_CMU_CPUCL0_DBG, "dout_cmu_cpucl0_dbg", + "gout_cmu_cpucl0_dbg", + CLK_CON_DIV_CLKCMU_CPUCL0_DBG, + 0, 3), + + /* DPU */ + DIV(CLK_DOUT_CMU_DPU_AUDIF, "dout_cmu_dpu_audif", + "gout_cmu_dpu_audif", + CLK_CON_DIV_CLKCMU_DPU_AUDIF, + 0, 9), + DIV(CLK_DOUT_CMU_DPU_AUD_BUS, "dout_cmu_dpu_aud_bus", + "gout_cmu_dpu_aud_bus", + CLK_CON_DIV_CLKCMU_DPU_AUD_BUS, + 0, 3), + DIV(CLK_DOUT_CMU_DPU_AUD_CPU, "dout_cmu_dpu_aud_cpu", + "gout_cmu_dpu_aud_cpu", + CLK_CON_DIV_CLKCMU_DPU_AUD_CPU, + 0, 3), + DIV(CLK_DOUT_CMU_DPU_BUS, "dout_cmu_dpu_bus", + "gout_cmu_dpu_bus", + CLK_CON_DIV_CLKCMU_DPU_BUS, + 0, 3), + + /* FSYS */ + DIV(CLK_DOUT_CMU_FSYS_BUS, "dout_cmu_fsys_bus", + "gout_cmu_fsys_bus", + CLK_CON_DIV_CLKCMU_FSYS_BUS, + 0, 4), + DIV(CLK_DOUT_CMU_FSYS_MMC_CARD, "dout_cmu_fsys_mmc_card", + "gout_cmu_fsys_mmc_card", + CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD, + 0, 9), + DIV(CLK_DOUT_CMU_FSYS_MMC_EMBD, "dout_cmu_fsys_mmc_embd", + "gout_cmu_fsys_mmc_embd", + CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD, + 0, 9), + DIV(CLK_DOUT_CMU_FSYS_USB20DRD, "dout_cmu_fsys_usb20drd", + "gout_cmu_fsys_usb20drd", + CLK_CON_DIV_CLKCMU_FSYS_USB20DRD, + 0, 4), + + /* G3D */ + DIV(CLK_DOUT_CMU_G3D_BUS, "dout_cmu_g3d_bus", + "gout_cmu_g3d_bus", + CLK_CON_DIV_CLKCMU_G3D_BUS, + 0, 3), + + /* MFC */ + DIV(CLK_DOUT_CMU_MFC_BUS, "dout_cmu_mfc_bus", + "gout_cmu_mfc_bus", + CLK_CON_DIV_CLKCMU_MFC_BUS, + 0, 4), + + /* MIF */ + DIV(CLK_DOUT_CMU_MIF_BUSP, "dout_cmu_mif_busp", + "gout_cmu_mif_busp", + CLK_CON_DIV_CLKCMU_MIF_BUSP, + 0, 3), + + /* PERI */ + DIV(CLK_DOUT_CMU_PERI_BUS, "dout_cmu_peri_bus", + "gout_cmu_peri_bus", + CLK_CON_DIV_CLKCMU_PERI_BUS, + 0, 3), + DIV(CLK_DOUT_CMU_PERI_IP, "dout_cmu_peri_ip", + "gout_cmu_peri_ip", + CLK_CON_DIV_CLKCMU_PERI_IP, + 0, 4), + DIV(CLK_DOUT_CMU_PERI_UART, "dout_cmu_peri_uart", + "gout_cmu_peri_uart", + CLK_CON_DIV_CLKCMU_PERI_UART, + 0, 4), + + /* SHARED */ + DIV(CLK_DOUT_AP2CP_SHARED0_PLL, "dout_ap2cp_shared0_pll", + "gout_cmu_modem_shared0", + CLK_CON_DIV_AP2CP_SHARED0_PLL_CLK, + 0, 3), + DIV(CLK_DOUT_AP2CP_SHARED1_PLL, "dout_ap2cp_shared1_pll", + "gout_cmu_modem_shared1", + CLK_CON_DIV_AP2CP_SHARED1_PLL_CLK, + 0, 3), + DIV(CLK_DOUT_AP2CP_SHARED2_PLL, "dout_ap2cp_shared2_pll", + "gout_cmu_modem_shared2", + CLK_CON_DIV_AP2CP_SHARED2_PLL_CLK, + 0, 3), +}; + +static const struct samsung_fixed_factor_clock top_fixed_factor_clks[] __initconst = { + FFACTOR(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "fout_shared0_pll", + 1, 2, 0), + FFACTOR(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "fout_shared0_pll", + 1, 3, 0), + FFACTOR(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "fout_shared0_pll", + 1, 4, 0), + FFACTOR(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "fout_shared1_pll", + 1, 2, 0), + FFACTOR(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "fout_shared1_pll", + 1, 3, 0), + FFACTOR(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "fout_shared1_pll", + 1, 4, 0), + FFACTOR(CLK_DOUT_AUD_DIV2, "dout_aud_div2", "fout_aud_pll", + 1, 2, 0), + FFACTOR(CLK_DOUT_AUD_DIV3, "dout_aud_div3", "fout_aud_pll", + 1, 3, 0), + FFACTOR(CLK_DOUT_AUD_DIV4, "dout_aud_div4", "fout_aud_pll", + 1, 4, 0), +}; + +static const struct samsung_gate_clock top_gate_clks[] __initconst = { + /* APM */ + GATE(CLK_GOUT_CMU_APM_BUS, "gout_cmu_apm_bus", + "mout_cmu_apm_bus", + CLK_CON_GAT_GATE_CLKCMU_APM_BUS, + 21, 0, 0), + + /* CORE */ + GATE(CLK_GOUT_CMU_CORE_BUS, "gout_cmu_core_bus", + "mout_cmu_core_bus", + CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, + 21, 0, 0), + GATE(CLK_GOUT_CMU_CORE_SSS, "gout_cmu_core_sss", + "mout_cmu_core_sss", + CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, + 21, 0, 0), + + /* CPUCL0 */ + GATE(CLK_GOUT_CMU_CPUCL0_BUSP, "gout_cmu_cpucl0_busp", + "mout_cmu_cpucl0_busp", + CLK_CON_GAT_GATE_CLKCMU_CPUCL0_BUSP, + 21, 0, 0), + GATE(CLK_GOUT_CMU_CPUCL0_CPU, "gout_cmu_cpucl0_cpu", + "mout_cmu_cpucl0_cpu", + CLK_CON_GAT_GATE_CLKCMU_CPUCL0_CPU, + 21, 0, 0), + GATE(CLK_GOUT_CMU_CPUCL0_DBG, "gout_cmu_cpucl0_dbg", + "mout_cmu_cpucl0_dbg", + CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG, + 21, 0, 0), + + /* DPU */ + GATE(CLK_GOUT_CMU_DPU_AUDIF, "gout_cmu_dpu_audif", + "mout_cmu_dpu_audif", + CLK_CON_GAT_GATE_CLKCMU_DPU_AUDIF, + 21, 0, 0), + GATE(CLK_GOUT_CMU_DPU_AUD_BUS, "gout_cmu_dpu_aud_bus", + "mout_cmu_dpu_aud_bus", + CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_BUS, + 21, 0, 0), + GATE(CLK_GOUT_CMU_DPU_AUD_CPU, "gout_cmu_dpu_aud_cpu", + "mout_cmu_dpu_aud_cpu", + CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_CPU, + 21, 0, 0), + GATE(CLK_GOUT_CMU_DPU_BUS, "gout_cmu_dpu_bus", + "mout_cmu_dpu_bus", + CLK_CON_GAT_GATE_CLKCMU_DPU_BUS, + 21, 0, 0), + + /* FSYS */ + GATE(CLK_GOUT_CMU_FSYS_BUS, "gout_cmu_fsys_bus", + "mout_cmu_fsys_bus", + CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS, + 21, 0, 0), + GATE(CLK_GOUT_CMU_FSYS_MMC_CARD, "gout_cmu_fsys_mmc_card", + "mout_cmu_fsys_mmc_card", + CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD, + 21, 0, 0), + GATE(CLK_GOUT_CMU_FSYS_MMC_EMBD, "gout_cmu_fsys_mmc_embd", + "mout_cmu_fsys_mmc_embd", + CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD, + 21, 0, 0), + GATE(CLK_GOUT_CMU_FSYS_USB20DRD, "gout_cmu_fsys_usb20drd", + "mout_cmu_fsys_usb20drd", + CLK_CON_GAT_GATE_CLKCMU_FSYS_USB20DRD, + 21, 0, 0), + + /* G3D */ + GATE(CLK_GOUT_CMU_G3D_BUS, "gout_cmu_g3d_bus", + "mout_cmu_g3d_bus", + CLK_CON_GAT_GATE_CLKCMU_G3D_BUS, + 21, 0, 0), + + /* MFC */ + GATE(CLK_GOUT_CMU_MFC_BUS, "gout_cmu_mfc_bus", + "mout_cmu_mfc_bus", + CLK_CON_GAT_GATE_CLKCMU_MFC_BUS, + 21, 0, 0), + + /* MIF */ + GATE(CLK_GOUT_CMU_MIF_SWITCH, "gout_cmu_mif_switch", + "mout_cmu_mif_switch", + CLK_CON_GAT_CLKCMU_MIF_SWITCH, + 21, 0, 0), + GATE(CLK_GOUT_CMU_MIF_BUSP, "gout_cmu_mif_busp", + "mout_cmu_mif_busp", + CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP, + 21, 0, 0), + + /* MODEM */ + GATE(CLK_GOUT_CMU_MODEM_SHARED0, "gout_cmu_modem_shared0", + "fout_shared0_pll", + CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED0, + 21, 0, 0), + GATE(CLK_GOUT_CMU_MODEM_SHARED1, "gout_cmu_modem_shared1", + "mout_cmu_modem_shared1", + CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED1, + 21, 0, 0), + GATE(CLK_GOUT_CMU_MODEM_SHARED2, "gout_cmu_modem_shared2", + "fout_shared0_pll", + CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED2, + 21, 0, 0), + + /* PERI */ + GATE(CLK_GOUT_CMU_PERI_BUS, "gout_cmu_peri_bus", + "mout_cmu_peri_bus", + CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, + 21, 0, 0), + GATE(CLK_GOUT_CMU_PERI_IP, "gout_cmu_peri_ip", + "mout_cmu_peri_ip", + CLK_CON_GAT_GATE_CLKCMU_PERI_IP, + 21, 0, 0), + GATE(CLK_GOUT_CMU_PERI_UART, "gout_cmu_peri_uart", + "mout_cmu_peri_uart", + CLK_CON_GAT_GATE_CLKCMU_PERI_UART, + 21, 0, 0), +}; + +static const unsigned long drcg_sysreg[] __initconst = { + EXYNOS5515_DRCG_EN_OFFSET, +}; + +static const struct samsung_cmu_info top_cmu_info __initconst = { + .pll_clks = top_pll_clks, + .nr_pll_clks = ARRAY_SIZE(top_pll_clks), + .mux_clks = top_mux_clks, + .nr_mux_clks = ARRAY_SIZE(top_mux_clks), + .div_clks = top_div_clks, + .nr_div_clks = ARRAY_SIZE(top_div_clks), + .fixed_factor_clks = top_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(top_fixed_factor_clks), + .gate_clks = top_gate_clks, + .nr_gate_clks = ARRAY_SIZE(top_gate_clks), + .nr_clk_ids = CLKS_NR_TOP, + .clk_regs = top_clk_regs, + .nr_clk_regs = ARRAY_SIZE(top_clk_regs), + .sysreg_clk_regs = drcg_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(drcg_sysreg), + .auto_clock_gate = true, + .gate_dbg_offset = EXYNOS5515_GATE_DBG_OFFSET, + .option_offset = CMU_CMU_TOP_CONTROLLER_OPTION, + .drcg_offset = EXYNOS5515_DRCG_EN_OFFSET, +}; + +static void __init exynos5515_cmu_top_init(struct device_node *np) +{ + exynos_arm64_register_cmu(NULL, np, &top_cmu_info); +} + +/* Register CMU_TOP early, as it's a dependency for other early domains */ +CLK_OF_DECLARE(exynos5515_cmu_top, "samsung,exynos5515-cmu-top", + exynos5515_cmu_top_init); + +/* ---- CMU_PERI ------------------------------------------------------------ */ + +/* + * CMU_PERI: 0x10030000 + * SYSREG_PERI: 0x10020000 + */ + +#define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER 0x0600 +#define PLL_CON1_MUX_CLKCMU_PERI_BUS_USER 0x0604 +#define PLL_CON0_MUX_CLKCMU_PERI_IP_USER 0x0610 +#define PLL_CON1_MUX_CLKCMU_PERI_IP_USER 0x0614 +#define PLL_CON0_MUX_CLKCMU_PERI_UART_USER 0x0620 +#define PLL_CON1_MUX_CLKCMU_PERI_UART_USER 0x0624 +#define PERI_CMU_PERI_CONTROLLER_OPTION 0x0800 +#define CLK_CON_MUX_MUX_CLK_PERI_SPI 0x1000 +#define CLK_CON_MUX_MUX_CLK_PERI_USI00_USI 0x1004 +#define CLK_CON_DIV_CLKCMU_OTP 0x1800 +#define CLK_CON_DIV_DIV_CLK_PERI_I2C_0 0x1804 +#define CLK_CON_DIV_DIV_CLK_PERI_I2C_1 0x1808 +#define CLK_CON_DIV_DIV_CLK_PERI_I2C_2 0x180c +#define CLK_CON_DIV_DIV_CLK_PERI_I2C_3 0x1810 +#define CLK_CON_DIV_DIV_CLK_PERI_SPI 0x1814 +#define CLK_CON_DIV_DIV_CLK_PERI_USI00_I2C 0x1818 +#define CLK_CON_DIV_DIV_CLK_PERI_USI00_USI 0x181c +#define CLK_CON_GAT_CLK_BLK_PERI_UID_BUSIF_TMU_IPCLKPORT_PCLK 0x2000 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_D_TZPC_PERI_IPCLKPORT_PCLK 0x2004 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_GPIO_PERI_IPCLKPORT_PCLK 0x2008 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_IPCLK 0x200c +#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_PCLK 0x2010 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_IPCLK 0x2014 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_PCLK 0x2018 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_IPCLK 0x201c +#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_PCLK 0x2020 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_IPCLK 0x2024 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_PCLK 0x2028 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_MCT_IPCLKPORT_PCLK 0x202c +#define CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_I_OSCCLK 0x2030 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_PCLK 0x2034 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_PERI_CMU_PERI_IPCLKPORT_PCLK 0x2038 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_PWM_MOTOR_IPCLKPORT_I_PCLK_S0 0x203c +#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_BUS_IPCLKPORT_CLK 0x2040 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_0_IPCLKPORT_CLK 0x2044 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_1_IPCLKPORT_CLK 0x2048 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_2_IPCLKPORT_CLK 0x204c +#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_3_IPCLKPORT_CLK 0x2050 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_OSCCLK_IPCLKPORT_CLK 0x2054 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_SPI_IPCLKPORT_CLK 0x2058 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_UART_IPCLKPORT_CLK 0x205c +#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_I2C_IPCLKPORT_CLK 0x2060 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_USI_IPCLKPORT_CLK 0x2064 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_SLH_AXI_MI_P_PERI_IPCLKPORT_I_CLK 0x2068 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_SYSREG_PERI_IPCLKPORT_PCLK 0x206c +#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_IPCLK 0x2070 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_PCLK 0x2074 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_IPCLK 0x2078 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_PCLK 0x207c +#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_IPCLK 0x2080 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_PCLK 0x2084 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_IPCLK 0x2088 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_PCLK 0x208c +#define CLK_CON_GAT_CLK_BLK_PERI_UID_WDT0_IPCLKPORT_PCLK 0x2090 +#define CLK_CON_GAT_CLK_BLK_PERI_UID_WDT1_IPCLKPORT_PCLK 0x2094 +#define CLK_CON_GAT_GATE_CLK_PERI_I2C_0 0x2098 +#define CLK_CON_GAT_GATE_CLK_PERI_I2C_1 0x209c +#define CLK_CON_GAT_GATE_CLK_PERI_I2C_2 0x20a0 +#define CLK_CON_GAT_GATE_CLK_PERI_I2C_3 0x20a4 +#define CLK_CON_GAT_GATE_CLK_PERI_USI00_I2C 0x20a8 + +static const unsigned long peri_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, + PLL_CON1_MUX_CLKCMU_PERI_BUS_USER, + PLL_CON0_MUX_CLKCMU_PERI_IP_USER, + PLL_CON1_MUX_CLKCMU_PERI_IP_USER, + PLL_CON0_MUX_CLKCMU_PERI_UART_USER, + PLL_CON1_MUX_CLKCMU_PERI_UART_USER, + PERI_CMU_PERI_CONTROLLER_OPTION, + CLK_CON_MUX_MUX_CLK_PERI_SPI, + CLK_CON_MUX_MUX_CLK_PERI_USI00_USI, + CLK_CON_DIV_CLKCMU_OTP, + CLK_CON_DIV_DIV_CLK_PERI_I2C_0, + CLK_CON_DIV_DIV_CLK_PERI_I2C_1, + CLK_CON_DIV_DIV_CLK_PERI_I2C_2, + CLK_CON_DIV_DIV_CLK_PERI_I2C_3, + CLK_CON_DIV_DIV_CLK_PERI_SPI, + CLK_CON_DIV_DIV_CLK_PERI_USI00_I2C, + CLK_CON_DIV_DIV_CLK_PERI_USI00_USI, + CLK_CON_GAT_CLK_BLK_PERI_UID_BUSIF_TMU_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_D_TZPC_PERI_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_GPIO_PERI_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_IPCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_IPCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_IPCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_IPCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_MCT_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_I_OSCCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_PERI_CMU_PERI_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_PWM_MOTOR_IPCLKPORT_I_PCLK_S0, + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_BUS_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_0_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_1_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_2_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_3_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_OSCCLK_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_SPI_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_UART_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_I2C_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_USI_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_SLH_AXI_MI_P_PERI_IPCLKPORT_I_CLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_SYSREG_PERI_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_IPCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_IPCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_IPCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_IPCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_WDT0_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERI_UID_WDT1_IPCLKPORT_PCLK, + CLK_CON_GAT_GATE_CLK_PERI_I2C_0, + CLK_CON_GAT_GATE_CLK_PERI_I2C_1, + CLK_CON_GAT_GATE_CLK_PERI_I2C_2, + CLK_CON_GAT_GATE_CLK_PERI_I2C_3, + CLK_CON_GAT_GATE_CLK_PERI_USI00_I2C, +}; + +/* Parent clock list for CMU_PERI muxes */ +PNAME(mout_pll_peri_bus_user_p) = { "oscclk", + "mout_cmu_peri_bus" }; + +PNAME(mout_pll_peri_ip_user_p) = { "oscclk", + "mout_cmu_peri_ip" }; + +/* Parent clock list for CMU_PERI muxes: for SPI */ +PNAME(mout_peri_spi_p) = { "oscclk", + "mout_pll_peri_ip_user" }; + +/* Parent clock list for CMU_PERI muxes: for UART */ +PNAME(mout_pll_peri_uart_user_p) = { "oscclk", + "mout_cmu_peri_uart" }; + +/* Parent clock list for CMU_PERI muxes: for USI */ +PNAME(mout_peri_usi00_usi_p) = { "oscclk", + "mout_pll_peri_ip_user" }; + +static const struct samsung_mux_clock peri_mux_clks[] __initconst = { + /* BUS */ + MUX(CLK_MOUT_PLL_PERI_BUS_USER, "mout_pll_peri_bus_user", + mout_pll_peri_bus_user_p, + PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, + 4, 1), + + /* IP */ + MUX(CLK_MOUT_PLL_PERI_IP_USER, "mout_pll_peri_ip_user", + mout_pll_peri_ip_user_p, + PLL_CON0_MUX_CLKCMU_PERI_IP_USER, + 4, 1), + + /* SPI */ + MUX(CLK_MOUT_PERI_SPI, "mout_peri_spi", + mout_peri_spi_p, + CLK_CON_MUX_MUX_CLK_PERI_SPI, + 0, 1), + + /* UART */ + MUX(CLK_MOUT_PLL_PERI_UART_USER, "mout_pll_peri_uart_user", + mout_pll_peri_uart_user_p, + PLL_CON0_MUX_CLKCMU_PERI_UART_USER, + 4, 1), + + /* USI (Universal Serial Interface) */ + MUX(CLK_MOUT_PERI_USI00_USI, "mout_peri_usi00_usi", + mout_peri_usi00_usi_p, + CLK_CON_MUX_MUX_CLK_PERI_USI00_USI, + 0, 1), +}; + +static const struct samsung_div_clock peri_div_clks[] __initconst = { + /* I2C */ + DIV(CLK_DOUT_PERI_I2C_0, "dout_peri_i2c_0", + "gout_peri_i2c_0", + CLK_CON_DIV_DIV_CLK_PERI_I2C_0, + 0, 4), + DIV(CLK_DOUT_PERI_I2C_1, "dout_peri_i2c_1", + "gout_peri_i2c_1", + CLK_CON_DIV_DIV_CLK_PERI_I2C_1, + 0, 4), + DIV(CLK_DOUT_PERI_I2C_2, "dout_peri_i2c_2", + "gout_peri_i2c_2", + CLK_CON_DIV_DIV_CLK_PERI_I2C_2, + 0, 4), + DIV(CLK_DOUT_PERI_I2C_3, "dout_peri_i2c_3", + "gout_peri_i2c_3", + CLK_CON_DIV_DIV_CLK_PERI_I2C_3, + 0, 4), + + /* SPI */ + DIV(CLK_DOUT_PERI_SPI, "dout_peri_spi", + "mout_peri_spi", + CLK_CON_DIV_DIV_CLK_PERI_SPI, + 0, 5), + + /* USI */ + DIV(CLK_DOUT_PERI_USI00_I2C, "dout_peri_usi00_i2c", + "gout_peri_usi00_i2c", + CLK_CON_DIV_DIV_CLK_PERI_USI00_I2C, + 0, 4), + DIV(CLK_DOUT_PERI_USI00_USI, "dout_peri_usi00_usi", + "mout_peri_usi00_usi", + CLK_CON_DIV_DIV_CLK_PERI_USI00_USI, + 0, 5), +}; + +static const struct samsung_fixed_factor_clock peri_fixed_factor_clks[] __initconst = { + /* OTP (One-Time Programmable eFuses) */ + FFACTOR(CLK_DOUT_PERI_OTP, "dout_peri_otp", "oscclk", + 1, 8, 0), +}; + +static const struct samsung_gate_clock peri_gate_clks[] __initconst = { + /* BUS */ + GATE(CLK_GOUT_PERI_BUSIF_TMU_PCLK, "gout_peri_busif_tmu_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_BUSIF_TMU_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_BUS_CLK, "gout_peri_bus_clk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_BUS_IPCLKPORT_CLK, + 21, 0, 0), + + /* CMU */ + GATE(CLK_GOUT_PERI_CMU_PCLK, "gout_peri_cmu_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_PERI_CMU_PERI_IPCLKPORT_PCLK, + 21, 0, 0), + + /* GPIO */ + GATE(CLK_GOUT_PERI_GPIO_PCLK, "gout_peri_gpio_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_GPIO_PERI_IPCLKPORT_PCLK, + 21, 0, 0), + + /* I2C */ + GATE(CLK_GOUT_PERI_I2C_0_IPCLK, "gout_peri_i2c_0_ipclk", + "dout_peri_i2c_0", + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_IPCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_0_PCLK, "gout_peri_i2c_0_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_1_IPCLK, "gout_peri_i2c_1_ipclk", + "dout_peri_i2c_1", + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_IPCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_1_PCLK, "gout_peri_i2c_1_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_2_IPCLK, "gout_peri_i2c_2_ipclk", + "dout_peri_i2c_2", + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_IPCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_2_PCLK, "gout_peri_i2c_2_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_3_IPCLK, "gout_peri_i2c_3_ipclk", + "dout_peri_i2c_3", + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_IPCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_3_PCLK, "gout_peri_i2c_3_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_0_CLK, "gout_peri_i2c_0_clk", + "dout_peri_i2c_0", + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_0_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_1_CLK, "gout_peri_i2c_1_clk", + "dout_peri_i2c_1", + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_1_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_2_CLK, "gout_peri_i2c_2_clk", + "dout_peri_i2c_2", + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_2_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_3_CLK, "gout_peri_i2c_3_clk", + "dout_peri_i2c_3", + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_3_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_0, "gout_peri_i2c_0", + "mout_pll_peri_ip_user", + CLK_CON_GAT_GATE_CLK_PERI_I2C_0, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_1, "gout_peri_i2c_1", + "mout_pll_peri_ip_user", + CLK_CON_GAT_GATE_CLK_PERI_I2C_1, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_2, "gout_peri_i2c_2", + "mout_pll_peri_ip_user", + CLK_CON_GAT_GATE_CLK_PERI_I2C_2, + 21, 0, 0), + GATE(CLK_GOUT_PERI_I2C_3, "gout_peri_i2c_3", + "mout_pll_peri_ip_user", + CLK_CON_GAT_GATE_CLK_PERI_I2C_3, + 21, 0, 0), + + /* MCT (Multi-Core Timer) */ + GATE(CLK_GOUT_PERI_MCT_PCLK, "gout_peri_mct_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_MCT_IPCLKPORT_PCLK, + 21, 0, 0), + + /* OTP */ + GATE(CLK_GOUT_PERI_OTP_OSCCLK, "gout_peri_otp_oscclk", + "oscclk", + CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_I_OSCCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_OTP_PCLK, "gout_peri_otp_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_PCLK, + 21, 0, 0), + + /* OSCCLK */ + GATE(CLK_GOUT_PERI_OSCCLK, "gout_peri_oscclk", + "oscclk", + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_OSCCLK_IPCLKPORT_CLK, + 21, 0, 0), + + /* PWM */ + GATE(CLK_GOUT_PERI_PWM_MOTOR_PCLK, "gout_peri_pwm_motor_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_PWM_MOTOR_IPCLKPORT_I_PCLK_S0, + 21, 0, 0), + + /* SPI */ + GATE(CLK_GOUT_PERI_SPI_CLK, "gout_peri_spi_clk", + "dout_peri_spi", + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_SPI_IPCLKPORT_CLK, + 21, 0, 0), + + /* SYSREG */ + GATE(CLK_GOUT_PERI_SYSREG_PCLK, "gout_peri_sysreg_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_SYSREG_PERI_IPCLKPORT_PCLK, + 21, 0, 0), + + /* TZ */ + GATE(CLK_GOUT_PERI_D_TZPC_PCLK, "gout_peri_d_tzpc_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_D_TZPC_PERI_IPCLKPORT_PCLK, + 21, 0, 0), + + /* UART */ + GATE(CLK_GOUT_PERI_UART_CLK, "gout_peri_uart_clk", + "mout_pll_peri_uart_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_UART_IPCLKPORT_CLK, + 21, 0, 0), + + /* USI */ + GATE(CLK_GOUT_PERI_USI00_I2C_CLK, "gout_peri_usi00_i2c_clk", + "dout_peri_usi00_i2c", + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_I2C_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_USI00_USI_CLK, "gout_peri_usi00_usi_clk", + "dout_peri_usi00_usi", + CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_USI00_I2C_IPCLK, "gout_peri_usi00_i2c_ipclk", + "dout_peri_usi00_i2c", + CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_IPCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_USI00_I2C_PCLK, "gout_peri_usi00_i2c_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_USI00_USI_IPCLK, "gout_peri_usi00_usi_ipclk", + "dout_peri_usi00_usi", + CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_IPCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_USI00_USI_PCLK, "gout_peri_usi00_usi_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_USI_SPI_IPCLK, "gout_peri_usi_spi_ipclk", + "dout_peri_spi", + CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_IPCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_USI_SPI_PCLK, "gout_peri_usi_spi_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_USI_UART_IPCLK, "gout_peri_usi_uart_ipclk", + "mout_pll_peri_uart_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_IPCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_USI_UART_PCLK, "gout_peri_usi_uart_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_USI00_I2C, "gout_peri_usi00_i2c", + "mout_pll_peri_ip_user", + CLK_CON_GAT_GATE_CLK_PERI_USI00_I2C, + 21, 0, 0), + + /* WDT (Watchdog Timer) */ + GATE(CLK_GOUT_PERI_WDT0_PCLK, "gout_peri_wdt0_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_WDT0_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERI_WDT1_PCLK, "gout_peri_wdt1_pclk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_WDT1_IPCLKPORT_PCLK, + 21, 0, 0), + + /* UNKNOWN */ + GATE(CLK_GOUT_PERI_SLH_AXI_MI_P_CLK, "gout_peri_slh_axi_mi_p_clk", + "mout_pll_peri_bus_user", + CLK_CON_GAT_CLK_BLK_PERI_UID_SLH_AXI_MI_P_PERI_IPCLKPORT_I_CLK, + 21, 0, 0), +}; + +static const struct samsung_cmu_info peri_cmu_info __initconst = { + .mux_clks = peri_mux_clks, + .nr_mux_clks = ARRAY_SIZE(peri_mux_clks), + .div_clks = peri_div_clks, + .nr_div_clks = ARRAY_SIZE(peri_div_clks), + .fixed_factor_clks = peri_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(peri_fixed_factor_clks), + .gate_clks = peri_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peri_gate_clks), + .nr_clk_ids = CLKS_NR_PERI, + .clk_regs = peri_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peri_clk_regs), + .sysreg_clk_regs = drcg_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(drcg_sysreg), + .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = EXYNOS5515_GATE_DBG_OFFSET, + .option_offset = PERI_CMU_PERI_CONTROLLER_OPTION, + .drcg_offset = EXYNOS5515_DRCG_EN_OFFSET, +}; + +static void __init exynos5515_cmu_peri_init(struct device_node *np) +{ + exynos_arm64_register_cmu(NULL, np, &peri_cmu_info); +} + +/* Register CMU_PERI early, as it's a dependency for the MCT. */ +CLK_OF_DECLARE(exynos5515_cmu_peri, "samsung,exynos5515-cmu-peri", + exynos5515_cmu_peri_init); + +/* ---- CMU_FSYS ------------------------------------------------------------ */ + +/* + * CMU_FSYS: 0x10400000 + * SYSREG_FSYS: 0x10420000 + */ + +#define PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER 0x0600 +#define PLL_CON1_MUX_CLKCMU_FSYS_BUS_USER 0x0604 +#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER 0x0610 +#define PLL_CON1_MUX_CLKCMU_FSYS_MMC_CARD_USER 0x0614 +#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER 0x0620 +#define PLL_CON1_MUX_CLKCMU_FSYS_MMC_EMBD_USER 0x0624 +#define PLL_CON0_MUX_CLKCMU_FSYS_USB20DRD_USER 0x0630 +#define PLL_CON1_MUX_CLKCMU_FSYS_USB20DRD_USER 0x0634 +#define FSYS_CMU_FSYS_CONTROLLER_OPTION 0x0800 +#define CLK_CON_GAT_CLK_BLK_FSYS_UID_FSYS_CMU_FSYS_IPCLKPORT_PCLK 0x2000 +#define CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_SDCLKIN 0x2004 +#define CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_SDCLKIN 0x2008 +#define CLK_CON_GAT_CLK_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_OSCCLK_IPCLKPORT_CLK 0x200c +#define CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20DRD_REF_CLK_50 0x2010 +#define CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20_PHY_REFCLK_26 0x2014 +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_D_TZPC_FSYS_IPCLKPORT_PCLK 0x2018 +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_GPIO_FSYS_IPCLKPORT_PCLK 0x201c +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_I_ACLK 0x2020 +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_I_ACLK 0x2024 +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_ACLK 0x2028 +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_PCLK 0x202c +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_BUS_IPCLKPORT_CLK 0x2030 +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_MI_P_FSYS_IPCLKPORT_I_CLK 0x2034 +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_SI_D_FSYS_IPCLKPORT_I_CLK 0x2038 +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_SYSREG_FSYS_IPCLKPORT_PCLK 0x203c +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_ACLK_PHYCTRL_20 0x2040 +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_BUS_CLK_EARLY 0x2044 +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_US_64TO128_FSYS_IPCLKPORT_ACLK 0x2048 +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_D_FSYS_IPCLKPORT_ACLK 0x204c +#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_P_FSYS_IPCLKPORT_ACLK 0x2050 + +static const unsigned long fsys_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER, + PLL_CON1_MUX_CLKCMU_FSYS_BUS_USER, + PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER, + PLL_CON1_MUX_CLKCMU_FSYS_MMC_CARD_USER, + PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER, + PLL_CON1_MUX_CLKCMU_FSYS_MMC_EMBD_USER, + PLL_CON0_MUX_CLKCMU_FSYS_USB20DRD_USER, + PLL_CON1_MUX_CLKCMU_FSYS_USB20DRD_USER, + FSYS_CMU_FSYS_CONTROLLER_OPTION, + CLK_CON_GAT_CLK_BLK_FSYS_UID_FSYS_CMU_FSYS_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_SDCLKIN, + CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_SDCLKIN, + CLK_CON_GAT_CLK_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_OSCCLK_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20DRD_REF_CLK_50, + CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20_PHY_REFCLK_26, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_D_TZPC_FSYS_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_GPIO_FSYS_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_I_ACLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_I_ACLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_BUS_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_MI_P_FSYS_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_SI_D_FSYS_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_SYSREG_FSYS_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_ACLK_PHYCTRL_20, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_BUS_CLK_EARLY, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_US_64TO128_FSYS_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_D_FSYS_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_P_FSYS_IPCLKPORT_ACLK, +}; + +/* Parent clock list for CMU_FSYS muxes */ +PNAME(mout_pll_fsys_bus_user_p) = { "oscclk", + "dout_cmu_fsys_bus" }; + +/* Parent clock list for CMU_FSYS muxes: for MMC */ +PNAME(mout_pll_fsys_mmc_card_user_p) = { "oscclk", + "dout_cmu_fsys_mmc_card" }; + +PNAME(mout_pll_fsys_mmc_embd_user_p) = { "oscclk", + "dout_cmu_fsys_mmc_embd" }; + +/* Parent clock list for CMU_FSYS muxes: for USB */ +PNAME(mout_pll_fsys_usb20drd_user_p) = { "oscclk", + "dout_cmu_fsys_usb20drd" }; + +static const struct samsung_mux_clock fsys_mux_clks[] __initconst = { + /* BUS */ + MUX(CLK_MOUT_PLL_FSYS_BUS_USER, "mout_pll_fsys_bus_user", + mout_pll_fsys_bus_user_p, + PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER, + 4, 1), + + /* MMC */ + MUX(CLK_MOUT_PLL_FSYS_MMC_CARD_USER, "mout_pll_fsys_mmc_card_user", + mout_pll_fsys_mmc_card_user_p, + PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER, + 4, 1), + MUX(CLK_MOUT_PLL_FSYS_MMC_EMBD_USER, "mout_pll_fsys_mmc_embd_user", + mout_pll_fsys_mmc_embd_user_p, + PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER, + 4, 1), + + /* USB */ + MUX(CLK_MOUT_PLL_FSYS_USB20DRD_USER, "mout_pll_fsys_usb20drd_user", + mout_pll_fsys_usb20drd_user_p, + PLL_CON0_MUX_CLKCMU_FSYS_USB20DRD_USER, + 4, 1), +}; + +static const struct samsung_gate_clock fsys_gate_clks[] __initconst = { + /* BUS */ + GATE(CLK_GOUT_FSYS_BUS_CLK, "gout_fsys_bus_clk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_BUS_IPCLKPORT_CLK, + 21, 0, 0), + + /* CMU */ + GATE(CLK_GOUT_FSYS_CMU_PCLK, "gout_fsys_cmu_pclk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_CLK_BLK_FSYS_UID_FSYS_CMU_FSYS_IPCLKPORT_PCLK, + 21, 0, 0), + + /* GPIO */ + GATE(CLK_GOUT_FSYS_GPIO_PCLK, "gout_fsys_gpio_pclk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_GPIO_FSYS_IPCLKPORT_PCLK, + 21, 0, 0), + + /* MMC */ + GATE(CLK_GOUT_FSYS_MMC_CARD_SDCLKIN, "gout_fsys_mmc_card_sdclkin", + "mout_pll_fsys_mmc_card_user", + CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_SDCLKIN, + 21, 0, 0), + GATE(CLK_GOUT_FSYS_MMC_EMBD_SDCLKIN, "gout_fsys_mmc_embd_sdclkin", + "mout_pll_fsys_mmc_embd_user", + CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_SDCLKIN, + 21, 0, 0), + GATE(CLK_GOUT_FSYS_MMC_CARD_ACLK, "gout_fsys_mmc_card_aclk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_I_ACLK, + 21, 0, 0), + GATE(CLK_GOUT_FSYS_MMC_EMBD_ACLK, "gout_fsys_mmc_embd_aclk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_I_ACLK, + 21, 0, 0), + + /* OSCCLK */ + GATE(CLK_GOUT_FSYS_OSCCLK, "gout_fsys_oscclk", + "oscclk", + CLK_CON_GAT_CLK_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_OSCCLK_IPCLKPORT_CLK, + 21, 0, 0), + + /* PMU */ + GATE(CLK_GOUT_FSYS_PPMU_ACLK, "gout_fsys_ppmu_aclk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_ACLK, + 21, 0, 0), + GATE(CLK_GOUT_FSYS_PPMU_PCLK, "gout_fsys_ppmu_pclk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_PCLK, + 21, 0, 0), + + /* SYSREG */ + GATE(CLK_GOUT_FSYS_SYSREG_PCLK, "gout_fsys_sysreg_pclk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_SYSREG_FSYS_IPCLKPORT_PCLK, + 21, 0, 0), + + /* TZ */ + GATE(CLK_GOUT_FSYS_D_TZPC_PCLK, "gout_fsys_d_tzpc_pclk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_D_TZPC_FSYS_IPCLKPORT_PCLK, + 21, 0, 0), + + /* USB */ + GATE(CLK_GOUT_FSYS_USB20DRD_REFCLK, + "gout_fsys_usb20drd_refclk", + "mout_pll_fsys_usb20drd_user", + CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20DRD_REF_CLK_50, + 21, 0, 0), + GATE(CLK_GOUT_FSYS_USB20DRD_PHY_REFCLK, + "gout_fsys_usb20drd_phy_refclk", + "oscclk", + CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20_PHY_REFCLK_26, + 21, 0, 0), + GATE(CLK_GOUT_FSYS_USB20DRD_ACLK_PHYCTRL, + "gout_fsys_usb20drd_aclk_phyctrl", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_ACLK_PHYCTRL_20, + 21, 0, 0), + GATE(CLK_GOUT_FSYS_USB20DRD_BUS_CLK_EARLY, + "gout_fsys_usb20drd_bus_clk_early", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_BUS_CLK_EARLY, + 21, 0, 0), + + /* UNKNOWN */ + GATE(CLK_GOUT_FSYS_SLH_AXI_MI_P_CLK, "gout_fsys_slh_axi_mi_p_clk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_MI_P_FSYS_IPCLKPORT_I_CLK, + 21, 0, 0), + GATE(CLK_GOUT_FSYS_SLH_AXI_SI_D_CLK, "gout_fsys_slh_axi_si_d_clk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_SI_D_FSYS_IPCLKPORT_I_CLK, + 21, 0, 0), + GATE(CLK_GOUT_FSYS_US_64TO128_ACLK, "gout_fsys_us_64to128_aclk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_US_64TO128_FSYS_IPCLKPORT_ACLK, + 21, 0, 0), + GATE(CLK_GOUT_FSYS_XIU_D_ACLK, "gout_fsys_xiu_d_aclk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_D_FSYS_IPCLKPORT_ACLK, + 21, 0, 0), + GATE(CLK_GOUT_FSYS_XIU_P_ACLK, "gout_fsys_xiu_p_aclk", + "mout_pll_fsys_bus_user", + CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_P_FSYS_IPCLKPORT_ACLK, + 21, 0, 0), +}; + +static const struct samsung_cmu_info fsys_cmu_info __initconst = { + .mux_clks = fsys_mux_clks, + .nr_mux_clks = ARRAY_SIZE(fsys_mux_clks), + .gate_clks = fsys_gate_clks, + .nr_gate_clks = ARRAY_SIZE(fsys_gate_clks), + .nr_clk_ids = CLKS_NR_FSYS, + .clk_regs = fsys_clk_regs, + .nr_clk_regs = ARRAY_SIZE(fsys_clk_regs), + .sysreg_clk_regs = drcg_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(drcg_sysreg), + .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = EXYNOS5515_GATE_DBG_OFFSET, + .option_offset = FSYS_CMU_FSYS_CONTROLLER_OPTION, + .drcg_offset = EXYNOS5515_DRCG_EN_OFFSET, +}; + +/* ----- platform_driver ----- */ + +static int __init exynos5515_cmu_probe(struct platform_device *pdev) +{ + const struct samsung_cmu_info *info; + struct device *dev = &pdev->dev; + + info = of_device_get_match_data(dev); + exynos_arm64_register_cmu(dev, dev->of_node, info); + + return 0; +} + +static const struct of_device_id exynos5515_cmu_of_match[] = { + { + .compatible = "samsung,exynos5515-cmu-fsys", + .data = &fsys_cmu_info, + }, + { }, +}; + +static struct platform_driver exynos5515_cmu_driver __refdata = { + .driver = { + .name = "exynos5515-cmu", + .of_match_table = exynos5515_cmu_of_match, + .suppress_bind_attrs = true, + }, + .probe = exynos5515_cmu_probe, +}; + +static int __init exynos5515_cmu_init(void) +{ + return platform_driver_register(&exynos5515_cmu_driver); +} + +core_initcall(exynos5515_cmu_init); diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index e74552846ba3..3d837bd74355 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -1591,8 +1591,8 @@ static const struct clk_ops samsung_a9fraco_clk_min_ops = { static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, const struct samsung_pll_clock *pll_clk) { + struct clk_init_data init = {}; struct samsung_clk_pll *pll; - struct clk_init_data init; unsigned int len = 0; int ret; @@ -1726,6 +1726,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, else init.ops = &samsung_pll2650xx_clk_ops; break; + case pll_309: case pll_531x: case pll_4311: init.ops = &samsung_pll531x_clk_ops; diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index d6eb3246611b..2457cf47c109 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -53,6 +53,7 @@ enum samsung_pll_type { pll_1031x, pll_a9fracm, pll_a9fraco, + pll_309, }; #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \ diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c index dd8d1713aaff..ba12179061b3 100644 --- a/drivers/clk/socfpga/clk-gate-a10.c +++ b/drivers/clk/socfpga/clk-gate-a10.c @@ -49,7 +49,7 @@ static void __init __socfpga_gate_init(struct device_node *node, struct socfpga_gate_clk *socfpga_clk; const char *clk_name = node->name; const char *parent_name[SOCFPGA_MAX_PARENTS]; - struct clk_init_data init; + struct clk_init_data init = {}; int rc; socfpga_clk = kzalloc_obj(*socfpga_clk); diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c index 24f56a9edc44..4b23909c5810 100644 --- a/drivers/clk/socfpga/clk-gate-s10.c +++ b/drivers/clk/socfpga/clk-gate-s10.c @@ -128,7 +128,7 @@ struct clk_hw *s10_register_gate(const struct stratix10_gate_clock *clks, void _ { struct clk_hw *hw_clk; struct socfpga_gate_clk *socfpga_clk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *parent_name = clks->parent_name; int ret; @@ -186,7 +186,7 @@ struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, voi { struct clk_hw *hw_clk; struct socfpga_gate_clk *socfpga_clk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *parent_name = clks->parent_name; int ret; @@ -244,7 +244,7 @@ struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks, void { struct clk_hw *hw_clk; struct socfpga_gate_clk *socfpga_clk; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; socfpga_clk = kzalloc_obj(*socfpga_clk); diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c index ced8e0988406..d0f9fa44ad18 100644 --- a/drivers/clk/socfpga/clk-gate.c +++ b/drivers/clk/socfpga/clk-gate.c @@ -143,7 +143,7 @@ void __init socfpga_gate_init(struct device_node *node) struct socfpga_gate_clk *socfpga_clk; const char *clk_name = node->name; const char *parent_name[SOCFPGA_MAX_PARENTS]; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_ops *ops; int rc; diff --git a/drivers/clk/socfpga/clk-periph-a10.c b/drivers/clk/socfpga/clk-periph-a10.c index 4eb5787f0dea..8aefc58ba4ec 100644 --- a/drivers/clk/socfpga/clk-periph-a10.c +++ b/drivers/clk/socfpga/clk-periph-a10.c @@ -65,7 +65,7 @@ static void __init __socfpga_periph_init(struct device_node *node, struct socfpga_periph_clk *periph_clk; const char *clk_name = node->name; const char *parent_name[SOCFPGA_MAX_PARENTS]; - struct clk_init_data init; + struct clk_init_data init = {}; int rc; u32 fixed_div; u32 div_reg[3]; diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c index 5195b9476da1..dc923d0d8786 100644 --- a/drivers/clk/socfpga/clk-periph-s10.c +++ b/drivers/clk/socfpga/clk-periph-s10.c @@ -103,7 +103,7 @@ struct clk_hw *s10_register_periph(const struct stratix10_perip_c_clock *clks, { struct clk_hw *hw_clk; struct socfpga_periph_clk *periph_clk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *name = clks->name; const char *parent_name = clks->parent_name; int ret; @@ -139,7 +139,7 @@ struct clk_hw *n5x_register_periph(const struct n5x_perip_c_clock *clks, { struct clk_hw *hw_clk; struct socfpga_periph_clk *periph_clk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *name = clks->name; const char *parent_name = clks->parent_name; int ret; @@ -174,7 +174,7 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c { struct clk_hw *hw_clk; struct socfpga_periph_clk *periph_clk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *name = clks->name; const char *parent_name = clks->parent_name; int ret; @@ -220,7 +220,7 @@ struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock { struct clk_hw *hw_clk; struct socfpga_periph_clk *periph_clk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *name = clks->name; int ret; diff --git a/drivers/clk/socfpga/clk-periph.c b/drivers/clk/socfpga/clk-periph.c index 3821db6777e7..8fa3d8e20042 100644 --- a/drivers/clk/socfpga/clk-periph.c +++ b/drivers/clk/socfpga/clk-periph.c @@ -55,7 +55,7 @@ static void __init __socfpga_periph_init(struct device_node *node, struct socfpga_periph_clk *periph_clk; const char *clk_name = node->name; const char *parent_name[SOCFPGA_MAX_PARENTS]; - struct clk_init_data init; + struct clk_init_data init = {}; int rc; u32 fixed_div; u32 div_reg[3]; diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c index c56f276e8d51..63b8b75045ae 100644 --- a/drivers/clk/socfpga/clk-pll-a10.c +++ b/drivers/clk/socfpga/clk-pll-a10.c @@ -71,7 +71,7 @@ static void __init __socfpga_pll_init(struct device_node *node, struct socfpga_pll *pll_clk; const char *clk_name = node->name; const char *parent_name[SOCFGPA_MAX_PARENTS]; - struct clk_init_data init; + struct clk_init_data init = {}; struct device_node *clkmgr_np; int rc; int i = 0; diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c index ee236e87da33..1dca54b48375 100644 --- a/drivers/clk/socfpga/clk-pll-s10.c +++ b/drivers/clk/socfpga/clk-pll-s10.c @@ -192,7 +192,7 @@ struct clk_hw *s10_register_pll(const struct stratix10_pll_clock *clks, { struct clk_hw *hw_clk; struct socfpga_pll *pll_clk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *name = clks->name; int ret; @@ -232,7 +232,7 @@ struct clk_hw *agilex_register_pll(const struct stratix10_pll_clock *clks, { struct clk_hw *hw_clk; struct socfpga_pll *pll_clk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *name = clks->name; int ret; @@ -271,7 +271,7 @@ struct clk_hw *n5x_register_pll(const struct stratix10_pll_clock *clks, { struct clk_hw *hw_clk; struct socfpga_pll *pll_clk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *name = clks->name; int ret; @@ -310,7 +310,7 @@ struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks, { struct clk_hw *hw_clk; struct socfpga_pll *pll_clk; - struct clk_init_data init; + struct clk_init_data init = {}; const char *name = clks->name; int ret; diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c index f85adb16d414..aa13cc9d6db1 100644 --- a/drivers/clk/socfpga/clk-pll.c +++ b/drivers/clk/socfpga/clk-pll.c @@ -78,7 +78,7 @@ static void __init __socfpga_pll_init(struct device_node *node, struct socfpga_pll *pll_clk; const char *clk_name = node->name; const char *parent_name[SOCFPGA_MAX_PARENTS]; - struct clk_init_data init; + struct clk_init_data init = {}; struct device_node *clkmgr_np; int rc; diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c index 61a8c3d4c1e4..85cfb9b5ec35 100644 --- a/drivers/clk/spear/clk-aux-synth.c +++ b/drivers/clk/spear/clk-aux-synth.c @@ -138,8 +138,8 @@ struct clk *clk_register_aux(const char *aux_name, const char *gate_name, const struct aux_clk_masks *masks, struct aux_rate_tbl *rtbl, u8 rtbl_cnt, spinlock_t *lock, struct clk **gate_clk) { + struct clk_init_data init = {}; struct clk_aux *aux; - struct clk_init_data init; struct clk *clk; if (!aux_name || !parent_name || !reg || !rtbl || !rtbl_cnt) { diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c index 3549f1cfdae1..1b5e184d9668 100644 --- a/drivers/clk/spear/clk-frac-synth.c +++ b/drivers/clk/spear/clk-frac-synth.c @@ -125,7 +125,7 @@ struct clk *clk_register_frac(const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, struct frac_rate_tbl *rtbl, u8 rtbl_cnt, spinlock_t *lock) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_frac *frac; struct clk *clk; diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c index 1a431d7ec20c..411cacdfc11f 100644 --- a/drivers/clk/spear/clk-gpt-synth.c +++ b/drivers/clk/spear/clk-gpt-synth.c @@ -114,7 +114,7 @@ struct clk *clk_register_gpt(const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, struct gpt_rate_tbl *rtbl, u8 rtbl_cnt, spinlock_t *lock) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_gpt *gpt; struct clk *clk; diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c index faba727e2f84..21fcc522c738 100644 --- a/drivers/clk/spear/clk-vco-pll.c +++ b/drivers/clk/spear/clk-vco-pll.c @@ -284,7 +284,7 @@ struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name, struct clk_vco *vco; struct clk_pll *pll; struct clk *vco_clk, *tpll_clk, *tvco_gate_clk; - struct clk_init_data vco_init, pll_init; + struct clk_init_data vco_init = {}, pll_init = {}; const char **vco_parent_name; if (!vco_name || !pll_name || !parent_name || !mode_reg || !cfg_reg || diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c index 211535fd8ac9..46e5c7be43e8 100644 --- a/drivers/clk/st/clk-flexgen.c +++ b/drivers/clk/st/clk-flexgen.c @@ -209,7 +209,7 @@ static struct clk *clk_register_flexgen(const char *name, unsigned long flexgen_flags, bool mode) { struct flexgen *fgxbar; struct clk *clk; - struct clk_init_data init; + struct clk_init_data init = {}; u32 xbar_shift; void __iomem *xbar_reg, *fdiv_reg; diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index 3fcc1da20c04..705133b959d7 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -444,9 +444,9 @@ static struct clk * __init st_clk_register_quadfs_pll( struct clkgen_quadfs_data *quadfs, void __iomem *reg, spinlock_t *lock) { + struct clk_init_data init = {}; struct st_clk_quadfs_pll *pll; struct clk *clk; - struct clk_init_data init; /* * Sanity check required pointers. @@ -885,8 +885,8 @@ static struct clk * __init st_clk_register_quadfs_fsynth( unsigned long flags, spinlock_t *lock) { struct st_clk_quadfs_fsynth *fs; + struct clk_init_data init = {}; struct clk *clk; - struct clk_init_data init; /* * Sanity check required pointers, note that nsdiv3 is optional. diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c index 17551c6a879a..aaa28aaff627 100644 --- a/drivers/clk/st/clkgen-pll.c +++ b/drivers/clk/st/clkgen-pll.c @@ -652,9 +652,9 @@ static struct clk * __init clkgen_pll_register(const char *parent_name, void __iomem *reg, unsigned long pll_flags, const char *clk_name, spinlock_t *lock) { + struct clk_init_data init = {}; struct clkgen_pll *pll; struct clk *clk; - struct clk_init_data init; pll = kzalloc_obj(*pll); if (!pll) diff --git a/drivers/clk/starfive/clk-starfive-jh7110-isp.c b/drivers/clk/starfive/clk-starfive-jh7110-isp.c index f3fa069db193..c02c8b29a123 100644 --- a/drivers/clk/starfive/clk-starfive-jh7110-isp.c +++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c @@ -130,7 +130,7 @@ static int jh7110_ispcrg_probe(struct platform_device *pdev) /* enable power domain and clocks */ pm_runtime_enable(priv->dev); - ret = pm_runtime_get_sync(priv->dev); + ret = pm_runtime_resume_and_get(priv->dev); if (ret < 0) return dev_err_probe(priv->dev, ret, "failed to turn on power\n"); diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c index 03c17cd2032f..847c0a39e5ab 100644 --- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c +++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c @@ -390,6 +390,9 @@ static int jh7110_pll0_clk_notifier_cb(struct notifier_block *nb, if (action == PRE_RATE_CHANGE) { struct clk *osc = clk_get(priv->dev, "osc"); + if (IS_ERR(osc)) + return notifier_from_errno(PTR_ERR(osc)); + priv->original_clk = clk_get_parent(cpu_root); ret = clk_set_parent(cpu_root, osc); clk_put(osc); diff --git a/drivers/clk/starfive/clk-starfive-jh7110-vout.c b/drivers/clk/starfive/clk-starfive-jh7110-vout.c index bad20d5d794a..aeba42cd3c44 100644 --- a/drivers/clk/starfive/clk-starfive-jh7110-vout.c +++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c @@ -40,10 +40,12 @@ static const struct jh71x0_clk_data jh7110_voutclk_data[] = { JH71X0_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", 0, JH7110_VOUTCLK_VOUT_TOP_AXI), JH71X0_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", 0, JH7110_VOUTCLK_VOUT_TOP_AXI), JH71X0_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", 0, JH7110_VOUTCLK_VOUT_TOP_AHB), - JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", 0, 2, + JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2, JH7110_VOUTCLK_DC8200_PIX, JH7110_VOUTCLK_HDMITX0_PIXELCLK), - JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", 0, 2, + JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2, JH7110_VOUTCLK_DC8200_PIX, JH7110_VOUTCLK_HDMITX0_PIXELCLK), /* LCD */ diff --git a/drivers/clk/stm32/clk-stm32mp1.c b/drivers/clk/stm32/clk-stm32mp1.c index 2d9ccd96ec98..b265e3f3e94c 100644 --- a/drivers/clk/stm32/clk-stm32mp1.c +++ b/drivers/clk/stm32/clk-stm32mp1.c @@ -902,8 +902,8 @@ static struct clk_hw *clk_register_pll(struct device *dev, const char *name, unsigned long flags, spinlock_t *lock) { + struct clk_init_data init = {}; struct stm32_pll_obj *element; - struct clk_init_data init; struct clk_hw *hw; int err; @@ -1041,8 +1041,8 @@ static struct clk_hw *clk_register_cktim(struct device *dev, const char *name, void __iomem *timpre, spinlock_t *lock) { + struct clk_init_data init = {}; struct timer_cker *tim_ker; - struct clk_init_data init; struct clk_hw *hw; int err; diff --git a/drivers/clk/stm32/clk-stm32mp21.c b/drivers/clk/stm32/clk-stm32mp21.c index bdb17419908c..961a228d8c64 100644 --- a/drivers/clk/stm32/clk-stm32mp21.c +++ b/drivers/clk/stm32/clk-stm32mp21.c @@ -17,8 +17,8 @@ #include #include -/* Max clock binding value */ -#define STM32MP21_LAST_CLK CK_SCMI_KER_ETR +/* Number of RCC clock bindings (highest RCC clock ID + 1) */ +#define STM32MP21_LAST_CLK (CK_KER_STM + 1) /* Clock security definition */ #define SECF_NONE -1 diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c index db0e36d8838e..349230e28c1c 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c @@ -43,27 +43,24 @@ static SUNXI_CCU_M_DATA_WITH_MUX(r_apb1_clk, "r-apb1", 24, 3, /* mux */ 0); -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_cpu_timer0, "r-timer0", - r_ahb_apb_parents, 0x100, - 0, 0, /* no M */ - 1, 3, /* P */ - 4, 3, /* mux */ - BIT(0), +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(r_cpu_timer0, "r-timer0", + r_ahb_apb_parents, 0x100, + 1, 3, /* P */ + 4, 3, /* mux */ + BIT(0), + 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(r_cpu_timer1, "r-timer1", + r_ahb_apb_parents, 0x104, + 1, 3, /* P */ + 4, 3, /* mux */ + BIT(0), + 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(r_cpu_timer2, "r-timer2", + r_ahb_apb_parents, 0x108, + 1, 3, /* P */ + 4, 3, /* mux */ + BIT(0), 0); -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_cpu_timer1, "r-timer1", - r_ahb_apb_parents, 0x104, - 0, 0, /* no M */ - 1, 3, /* P */ - 4, 3, /* mux */ - BIT(0), - 0); -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_cpu_timer2, "r-timer2", - r_ahb_apb_parents, 0x108, - 0, 0, /* no M */ - 1, 3, /* P */ - 4, 3, /* mux */ - BIT(0), - 0); static SUNXI_CCU_GATE_HW(bus_r_timer_clk, "bus-r-timer", &r_ahb_clk.common.hw, 0x11c, BIT(0), 0); diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c index 20dad06b37ca..0714090cc3b0 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -380,14 +380,13 @@ static const struct clk_parent_data mbus_parents[] = { { .hw = &pll_periph1_150M_clk.hw }, { .fw_name = "hosc" }, }; -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(mbus_clk, "mbus", mbus_parents, - 0x540, - 0, 5, /* M */ - 0, 0, /* no P */ - 24, 3, /* mux */ - BIT(31), /* gate */ - CLK_IS_CRITICAL, - CCU_FEATURE_UPDATE_BIT); +static SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(mbus_clk, "mbus", mbus_parents, + 0x540, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_IS_CRITICAL, + CCU_FEATURE_UPDATE_BIT); static const struct clk_hw *mbus_hws[] = { &mbus_clk.common.hw }; @@ -513,58 +512,47 @@ static const struct clk_parent_data hstimer_parents[] = { { .fw_name = "losc" }, { .hw = &pll_periph0_200M_clk.hw }, }; -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer0_clk, "hstimer0", - hstimer_parents, 0x730, - 0, 0, /* M */ - 0, 3, /* P */ - 24, 3, /* mux */ - BIT(31), /* gate */ - 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(hstimer0_clk, "hstimer0", + hstimer_parents, 0x730, + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer1_clk, "hstimer1", - hstimer_parents, - 0x734, - 0, 0, /* M */ - 0, 3, /* P */ - 24, 3, /* mux */ - BIT(31), /* gate */ - 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(hstimer1_clk, "hstimer1", + hstimer_parents, 0x734, + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer2_clk, "hstimer2", - hstimer_parents, - 0x738, - 0, 0, /* M */ - 0, 3, /* P */ - 24, 3, /* mux */ - BIT(31), /* gate */ - 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(hstimer2_clk, "hstimer2", + hstimer_parents, 0x738, + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer3_clk, "hstimer3", - hstimer_parents, - 0x73c, - 0, 0, /* M */ - 0, 3, /* P */ - 24, 3, /* mux */ - BIT(31), /* gate */ - 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(hstimer3_clk, "hstimer3", + hstimer_parents, 0x73c, + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer4_clk, "hstimer4", - hstimer_parents, - 0x740, - 0, 0, /* M */ - 0, 3, /* P */ - 24, 3, /* mux */ - BIT(31), /* gate */ - 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(hstimer4_clk, "hstimer4", + hstimer_parents, 0x740, + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer5_clk, "hstimer5", - hstimer_parents, - 0x744, - 0, 0, /* M */ - 0, 3, /* P */ - 24, 3, /* mux */ - BIT(31), /* gate */ - 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(hstimer5_clk, "hstimer5", + hstimer_parents, 0x744, + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); static SUNXI_CCU_GATE_HWS(bus_hstimer_clk, "bus-hstimer", ahb_hws, 0x74c, BIT(0), 0); @@ -584,14 +572,13 @@ static const struct clk_parent_data iommu_parents[] = { { .fw_name = "hosc" }, }; -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(iommu_clk, "iommu", iommu_parents, - 0x7b0, - 0, 5, /* M */ - 0, 0, /* no P */ - 24, 3, /* mux */ - BIT(31), /* gate */ - CLK_SET_RATE_PARENT, - CCU_FEATURE_UPDATE_BIT); +static SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(iommu_clk, "iommu", iommu_parents, + 0x7b0, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT, + CCU_FEATURE_UPDATE_BIT); static SUNXI_CCU_GATE_HWS(bus_iommu_clk, "bus-iommu", apb0_hws, 0x7bc, BIT(0), 0); @@ -603,14 +590,13 @@ static const struct clk_parent_data dram_parents[] = { { .hw = &pll_periph0_400M_clk.hw }, { .hw = &pll_periph0_150M_clk.hw }, }; -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(dram_clk, "dram", dram_parents, - 0x800, - 0, 5, /* M */ - 0, 0, /* no P */ - 24, 3, /* mux */ - BIT(31), /* gate */ - CLK_IS_CRITICAL, - CCU_FEATURE_UPDATE_BIT); +static SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(dram_clk, "dram", dram_parents, + 0x800, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_IS_CRITICAL, + CCU_FEATURE_UPDATE_BIT); static SUNXI_CCU_GATE_HWS(mbus_dma_clk, "mbus-dma", mbus_hws, 0x804, BIT(0), 0); diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c index 43d8eca6abee..248e58c9562d 100644 --- a/drivers/clk/sunxi-ng/ccu_common.c +++ b/drivers/clk/sunxi-ng/ccu_common.c @@ -35,7 +35,7 @@ void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock) else addr = common->base + common->reg; - WARN_ON(readl_relaxed_poll_timeout(addr, reg, reg & lock, 100, 70000)); + WARN_ON(readl_relaxed_poll_timeout_atomic(addr, reg, reg & lock, 100, 70000)); } EXPORT_SYMBOL_NS_GPL(ccu_helper_wait_for_lock, "SUNXI_CCU"); diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h index a30a92780a05..6d3541a3b519 100644 --- a/drivers/clk/sunxi-ng/ccu_div.h +++ b/drivers/clk/sunxi-ng/ccu_div.h @@ -212,16 +212,17 @@ struct ccu_div { SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \ _mshift, _mwidth, 0, _flags) -#define SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ - _mshift, _mwidth, \ - _muxshift, _muxwidth, \ - _gate, _flags) \ +#define SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _muxshift, _muxwidth, \ + _gate, _flags, _features) \ struct ccu_div _struct = { \ .enable = _gate, \ .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \ .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ .common = { \ .reg = _reg, \ + .features = _features, \ .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ _parents, \ &ccu_div_ops, \ @@ -229,6 +230,15 @@ struct ccu_div { }, \ } +#define SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _muxshift, _muxwidth, \ + _gate, _flags) \ + SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _muxshift, _muxwidth, \ + _gate, _flags, 0) + #define SUNXI_CCU_M_DATA_WITH_MUX(_struct, _name, _parents, _reg, \ _mshift, _mwidth, \ _muxshift, _muxwidth, \ diff --git a/drivers/clk/sunxi/clk-sun4i-tcon-ch1.c b/drivers/clk/sunxi/clk-sun4i-tcon-ch1.c index b61eba112a7f..b7f55864ea2a 100644 --- a/drivers/clk/sunxi/clk-sun4i-tcon-ch1.c +++ b/drivers/clk/sunxi/clk-sun4i-tcon-ch1.c @@ -225,7 +225,7 @@ static void __init tcon_ch1_setup(struct device_node *node) { const char *parents[TCON_CH1_SCLK2_PARENTS]; const char *clk_name = node->name; - struct clk_init_data init; + struct clk_init_data init = {}; struct tcon_ch1_clk *tclk; struct resource res; struct clk *clk; diff --git a/drivers/clk/tegra/clk-audio-sync.c b/drivers/clk/tegra/clk-audio-sync.c index 0bbfcf46bedd..0fb4377c80bf 100644 --- a/drivers/clk/tegra/clk-audio-sync.c +++ b/drivers/clk/tegra/clk-audio-sync.c @@ -47,7 +47,7 @@ struct clk *tegra_clk_register_sync_source(const char *name, unsigned long max_rate) { struct tegra_clk_sync_source *sync; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk *clk; sync = kzalloc_obj(*sync); diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c index 067a8555c4e7..15b976162b59 100644 --- a/drivers/clk/tegra/clk-bpmp.c +++ b/drivers/clk/tegra/clk-bpmp.c @@ -32,7 +32,7 @@ struct tegra_bpmp_clk { unsigned int id; unsigned int num_parents; - unsigned int *parents; + unsigned int parents[] __counted_by(num_parents); }; static inline struct tegra_bpmp_clk *to_tegra_bpmp_clk(struct clk_hw *hw) @@ -518,20 +518,14 @@ tegra_bpmp_clk_register(struct tegra_bpmp *bpmp, unsigned int i; int err; - clk = devm_kzalloc(bpmp->dev, sizeof(*clk), GFP_KERNEL); + clk = devm_kzalloc(bpmp->dev, struct_size(clk, parents, info->num_parents), GFP_KERNEL); if (!clk) return ERR_PTR(-ENOMEM); + clk->num_parents = info->num_parents; clk->id = info->id; clk->bpmp = bpmp; - clk->parents = devm_kcalloc(bpmp->dev, info->num_parents, - sizeof(*clk->parents), GFP_KERNEL); - if (!clk->parents) - return ERR_PTR(-ENOMEM); - - clk->num_parents = info->num_parents; - /* hardware clock initialization */ memset(&init, 0, sizeof(init)); init.name = info->name; diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c index 27f43c3da156..2dc771343345 100644 --- a/drivers/clk/tegra/clk-divider.c +++ b/drivers/clk/tegra/clk-divider.c @@ -145,8 +145,8 @@ struct clk *tegra_clk_register_divider(const char *name, u8 frac_width, spinlock_t *lock) { struct tegra_clk_frac_div *divider; + struct clk_init_data init = {}; struct clk *clk; - struct clk_init_data init; divider = kzalloc_obj(*divider); if (!divider) { diff --git a/drivers/clk/tegra/clk-periph-fixed.c b/drivers/clk/tegra/clk-periph-fixed.c index bb33e32cad4a..9ea9d41f4796 100644 --- a/drivers/clk/tegra/clk-periph-fixed.c +++ b/drivers/clk/tegra/clk-periph-fixed.c @@ -77,7 +77,7 @@ struct clk *tegra_clk_register_periph_fixed(const char *name, { const struct tegra_clk_periph_regs *regs; struct tegra_clk_periph_fixed *fixed; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk *clk; regs = get_reg_bank(num); diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c index fa39d6487515..d821e1b9f77e 100644 --- a/drivers/clk/tegra/clk-periph-gate.c +++ b/drivers/clk/tegra/clk-periph-gate.c @@ -139,7 +139,7 @@ struct clk *tegra_clk_register_periph_gate(const char *name, { struct tegra_clk_periph_gate *gate; struct clk *clk; - struct clk_init_data init; + struct clk_init_data init = {}; const struct tegra_clk_periph_regs *pregs; pregs = get_reg_bank(clk_num); diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index 6ebeaa7cb656..7af832d9af9b 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -166,7 +166,7 @@ static struct clk *_tegra_clk_register_periph(const char *name, unsigned long flags) { struct clk *clk; - struct clk_init_data init; + struct clk_init_data init = {}; const struct tegra_clk_periph_regs *bank; bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV); diff --git a/drivers/clk/tegra/clk-pll-out.c b/drivers/clk/tegra/clk-pll-out.c index 2299545fc386..285b0af811fb 100644 --- a/drivers/clk/tegra/clk-pll-out.c +++ b/drivers/clk/tegra/clk-pll-out.c @@ -90,8 +90,8 @@ struct clk *tegra_clk_register_pll_out(const char *name, spinlock_t *lock) { struct tegra_clk_pll_out *pll_out; + struct clk_init_data init = {}; struct clk *clk; - struct clk_init_data init; pll_out = kzalloc_obj(*pll_out); if (!pll_out) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index adfb74f111ef..fc3abe86414d 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1903,7 +1903,7 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll, const char *name, const char *parent_name, unsigned long flags, const struct clk_ops *ops) { - struct clk_init_data init; + struct clk_init_data init = {}; init.name = name; init.ops = ops; diff --git a/drivers/clk/tegra/clk-sdmmc-mux.c b/drivers/clk/tegra/clk-sdmmc-mux.c index 14b5439a100a..74fe06fa546a 100644 --- a/drivers/clk/tegra/clk-sdmmc-mux.c +++ b/drivers/clk/tegra/clk-sdmmc-mux.c @@ -236,7 +236,7 @@ struct clk *tegra_clk_register_sdmmc_mux_div(const char *name, unsigned long flags, void *lock) { struct clk *clk; - struct clk_init_data init; + struct clk_init_data init = {}; const struct tegra_clk_periph_regs *bank; struct tegra_sdmmc_mux *sdmmc_mux; diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c index 370445e3d5ac..7aa3c3774445 100644 --- a/drivers/clk/tegra/clk-super.c +++ b/drivers/clk/tegra/clk-super.c @@ -204,8 +204,8 @@ struct clk *tegra_clk_register_super_mux(const char *name, u8 width, u8 pllx_index, u8 div2_index, spinlock_t *lock) { struct tegra_clk_super_mux *super; + struct clk_init_data init = {}; struct clk *clk; - struct clk_init_data init; super = kzalloc_obj(*super); if (!super) @@ -240,8 +240,8 @@ struct clk *tegra_clk_register_super_clk(const char *name, spinlock_t *lock) { struct tegra_clk_super_mux *super; + struct clk_init_data init = {}; struct clk *clk; - struct clk_init_data init; super = kzalloc_obj(*super); if (!super) diff --git a/drivers/clk/tegra/clk-tegra-super-cclk.c b/drivers/clk/tegra/clk-tegra-super-cclk.c index e7aeb67606b1..1047a1104ec1 100644 --- a/drivers/clk/tegra/clk-tegra-super-cclk.c +++ b/drivers/clk/tegra/clk-tegra-super-cclk.c @@ -135,8 +135,8 @@ struct clk *tegra_clk_register_super_cclk(const char *name, spinlock_t *lock) { struct tegra_clk_super_mux *super; + struct clk_init_data init = {}; struct clk *clk; - struct clk_init_data init; u32 val; if (WARN_ON(cclk_super)) diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c index 94ac24ea1e6a..0fc74808fe39 100644 --- a/drivers/clk/tegra/clk-tegra124-emc.c +++ b/drivers/clk/tegra/clk-tegra124-emc.c @@ -485,8 +485,8 @@ static const struct clk_ops tegra_clk_emc_ops = { struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np, spinlock_t *lock) { + struct clk_init_data init = {}; struct tegra_clk_emc *tegra; - struct clk_init_data init; struct device_node *node; u32 node_ram_code; struct clk *clk; diff --git a/drivers/clk/tegra/clk-tegra20-emc.c b/drivers/clk/tegra/clk-tegra20-emc.c index 44465726a8a6..5cd026e8f305 100644 --- a/drivers/clk/tegra/clk-tegra20-emc.c +++ b/drivers/clk/tegra/clk-tegra20-emc.c @@ -245,8 +245,8 @@ bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw) struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter) { + struct clk_init_data init = {}; struct tegra_clk_emc *emc; - struct clk_init_data init; struct clk *clk; emc = kzalloc_obj(*emc); diff --git a/drivers/clk/tegra/clk-tegra210-emc.c b/drivers/clk/tegra/clk-tegra210-emc.c index 9f140d94bef7..2e559d95d40e 100644 --- a/drivers/clk/tegra/clk-tegra210-emc.c +++ b/drivers/clk/tegra/clk-tegra210-emc.c @@ -274,8 +274,8 @@ static const struct clk_ops tegra210_clk_emc_ops = { struct clk *tegra210_clk_register_emc(struct device_node *np, void __iomem *regs) { + struct clk_init_data init = {}; struct tegra210_clk_emc *emc; - struct clk_init_data init; struct clk *clk; emc = kzalloc_obj(*emc); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 73efd2ff37c9..afa93ba505ab 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -255,7 +255,7 @@ struct tegra_clk_pll; * @set_gain: Callback to adjust N div for SDM enabled * PLL's based on fractional divider value. * @calc_rate: Callback used to change how out of table - * rates (dividers and multipler) are calculated. + * rates (dividers and multiplier) are calculated. * @adjust_vco: Callback to adjust the programming range of the * divider range (if SDM is present) * @set_defaults: Callback which will try to initialize PLL diff --git a/drivers/clk/tenstorrent/atlantis-prcm.c b/drivers/clk/tenstorrent/atlantis-prcm.c index 6d4386eeb7da..6d28aa2ba881 100644 --- a/drivers/clk/tenstorrent/atlantis-prcm.c +++ b/drivers/clk/tenstorrent/atlantis-prcm.c @@ -205,14 +205,9 @@ static int atlantis_clk_gate_endisable(struct clk_hw *hw, int enable) { struct atlantis_clk_gate *gate = hw_to_atlantis_clk_gate(hw); - if (enable) - return regmap_set_bits(gate->common.regmap, - gate->config.reg_offset, - gate->config.enable); - else - return regmap_clear_bits(gate->common.regmap, - gate->config.reg_offset, - gate->config.enable); + return regmap_assign_bits(gate->common.regmap, + gate->config.reg_offset, + gate->config.enable, enable); } static int atlantis_clk_gate_enable(struct clk_hw *hw) @@ -397,22 +392,21 @@ static int atlantis_clk_gate_shared_enable(struct clk_hw *hw) scoped_guard(spinlock_irqsave, gate->config.refcount_lock) { - need_enable = (*gate->config.share_count)++ == 0; + need_enable = (*gate->config.share_count) == 0; if (need_enable) { regmap_set_bits(gate->common.regmap, gate->config.reg_offset, gate->config.enable); - } - } - if (need_enable) { - if (!regmap_test_bits(gate->common.regmap, - gate->config.reg_offset, - gate->config.enable)) { - pr_warn("%s: gate enable %d failed to enable\n", - clk_hw_get_name(hw), gate->config.enable); - return -EIO; + if (!regmap_test_bits(gate->common.regmap, + gate->config.reg_offset, + gate->config.enable)) { + pr_warn("%s: gate enable %d failed to enable\n", + clk_hw_get_name(hw), gate->config.enable); + return -EIO; + } } + (*gate->config.share_count)++; } return 0; @@ -789,13 +783,14 @@ static int atlantis_prcm_clocks_register(struct device *dev, { struct clk_hw_onecell_data *clk_data; int i, ret; - size_t num_clks = data->num; clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num), GFP_KERNEL); if (!clk_data) return -ENOMEM; + clk_data->num = data->num; + for (i = 0; i < data->num; i++) { struct clk_hw *hw = data->hws[i]; struct atlantis_clk_common *common = @@ -809,8 +804,6 @@ static int atlantis_prcm_clocks_register(struct device *dev, clk_data->hws[common->clkid] = hw; } - clk_data->num = num_clks; - return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); } diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c index 8885d28face5..0d729c9980a5 100644 --- a/drivers/clk/ti/adpll.c +++ b/drivers/clk/ti/adpll.c @@ -925,6 +925,7 @@ static void ti_adpll_remove(struct platform_device *pdev) { struct ti_adpll_data *d = dev_get_drvdata(&pdev->dev); + of_clk_del_provider(d->np); ti_adpll_free_resources(d); } diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c index c897ad7e681e..aedbe78bf1e4 100644 --- a/drivers/clk/ti/clockdomain.c +++ b/drivers/clk/ti/clockdomain.c @@ -104,7 +104,7 @@ int omap2_init_clk_clkdm(struct clk_hw *hw) if (!clk->clkdm_name) return 0; - clk_name = __clk_get_name(hw->clk); + clk_name = clk_hw_get_name(hw); clkdm = ti_clk_ll_ops->clkdm_lookup(clk->clkdm_name); if (clkdm) { diff --git a/drivers/clk/uniphier/clk-uniphier-cpugear.c b/drivers/clk/uniphier/clk-uniphier-cpugear.c index a2f01a4da127..165c6832b722 100644 --- a/drivers/clk/uniphier/clk-uniphier-cpugear.c +++ b/drivers/clk/uniphier/clk-uniphier-cpugear.c @@ -79,7 +79,7 @@ struct clk_hw *uniphier_clk_register_cpugear(struct device *dev, const struct uniphier_clk_cpugear_data *data) { struct uniphier_clk_cpugear *gear; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; gear = devm_kzalloc(dev, sizeof(*gear), GFP_KERNEL); diff --git a/drivers/clk/uniphier/clk-uniphier-fixed-factor.c b/drivers/clk/uniphier/clk-uniphier-fixed-factor.c index a6a37a6bca3a..c86683fce205 100644 --- a/drivers/clk/uniphier/clk-uniphier-fixed-factor.c +++ b/drivers/clk/uniphier/clk-uniphier-fixed-factor.c @@ -13,8 +13,8 @@ struct clk_hw *uniphier_clk_register_fixed_factor(struct device *dev, const char *name, const struct uniphier_clk_fixed_factor_data *data) { + struct clk_init_data init = {}; struct clk_fixed_factor *fix; - struct clk_init_data init; int ret; fix = devm_kzalloc(dev, sizeof(*fix), GFP_KERNEL); diff --git a/drivers/clk/uniphier/clk-uniphier-fixed-rate.c b/drivers/clk/uniphier/clk-uniphier-fixed-rate.c index 3bc55ab75314..63f49d3bab80 100644 --- a/drivers/clk/uniphier/clk-uniphier-fixed-rate.c +++ b/drivers/clk/uniphier/clk-uniphier-fixed-rate.c @@ -13,8 +13,8 @@ struct clk_hw *uniphier_clk_register_fixed_rate(struct device *dev, const char *name, const struct uniphier_clk_fixed_rate_data *data) { + struct clk_init_data init = {}; struct clk_fixed_rate *fixed; - struct clk_init_data init; int ret; /* allocate fixed-rate clock */ diff --git a/drivers/clk/uniphier/clk-uniphier-gate.c b/drivers/clk/uniphier/clk-uniphier-gate.c index e58093e79dd7..9f49e6bb6b20 100644 --- a/drivers/clk/uniphier/clk-uniphier-gate.c +++ b/drivers/clk/uniphier/clk-uniphier-gate.c @@ -61,8 +61,8 @@ struct clk_hw *uniphier_clk_register_gate(struct device *dev, const char *name, const struct uniphier_clk_gate_data *data) { + struct clk_init_data init = {}; struct uniphier_clk_gate *gate; - struct clk_init_data init; int ret; gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL); diff --git a/drivers/clk/uniphier/clk-uniphier-mux.c b/drivers/clk/uniphier/clk-uniphier-mux.c index 1998e9d4cfc0..a63ad4df8e65 100644 --- a/drivers/clk/uniphier/clk-uniphier-mux.c +++ b/drivers/clk/uniphier/clk-uniphier-mux.c @@ -58,8 +58,8 @@ struct clk_hw *uniphier_clk_register_mux(struct device *dev, const char *name, const struct uniphier_clk_mux_data *data) { + struct clk_init_data init = {}; struct uniphier_clk_mux *mux; - struct clk_init_data init; int ret; mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); diff --git a/drivers/clk/ux500/clk-prcc.c b/drivers/clk/ux500/clk-prcc.c index dce235df2576..dde72d2fd0ac 100644 --- a/drivers/clk/ux500/clk-prcc.c +++ b/drivers/clk/ux500/clk-prcc.c @@ -97,8 +97,8 @@ static struct clk *clk_reg_prcc(const char *name, unsigned long flags, const struct clk_ops *clk_prcc_ops) { + struct clk_init_data clk_prcc_init = {}; struct clk_prcc *clk; - struct clk_init_data clk_prcc_init; struct clk *clk_reg; if (!name) { diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c index ac96c46bd1bb..d89f3b634f8b 100644 --- a/drivers/clk/ux500/clk-prcmu.c +++ b/drivers/clk/ux500/clk-prcmu.c @@ -200,8 +200,8 @@ static struct clk_hw *clk_reg_prcmu(const char *name, unsigned long flags, const struct clk_ops *clk_prcmu_ops) { + struct clk_init_data clk_prcmu_init = {}; struct clk_prcmu *clk; - struct clk_init_data clk_prcmu_init; int ret; if (!name) { @@ -357,8 +357,8 @@ struct clk_hw *clk_reg_prcmu_clkout(const char *name, u8 source, u8 divider) { + struct clk_init_data clk_prcmu_clkout_init = {}; struct clk_prcmu_clkout *clk; - struct clk_init_data clk_prcmu_clkout_init; u8 clkout_id; int ret; diff --git a/drivers/clk/ux500/clk-sysctrl.c b/drivers/clk/ux500/clk-sysctrl.c index ba3258c88d28..2127a949e56c 100644 --- a/drivers/clk/ux500/clk-sysctrl.c +++ b/drivers/clk/ux500/clk-sysctrl.c @@ -127,8 +127,8 @@ static struct clk *clk_reg_sysctrl(struct device *dev, unsigned long flags, const struct clk_ops *clk_sysctrl_ops) { + struct clk_init_data clk_sysctrl_init = {}; struct clk_sysctrl *clk; - struct clk_init_data clk_sysctrl_init; struct clk *clk_reg; int i; diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index 6bd3db54dd22..37334afee040 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c @@ -360,8 +360,8 @@ struct clk *icst_clk_setup(struct device *dev, { struct clk *clk; struct clk_icst *icst; - struct clk_init_data init; struct icst_params *pclone; + struct clk_init_data init = {}; icst = kzalloc_obj(*icst); if (!icst) @@ -516,16 +516,19 @@ static void __init of_syscon_icst_setup(struct device_node *np) map = syscon_node_to_regmap(parent); if (IS_ERR(map)) { pr_err("no regmap for syscon ICST clock parent\n"); + of_node_put(parent); return; } if (of_property_read_u32(np, "reg", &icst_desc.vco_offset) && of_property_read_u32(np, "vco-offset", &icst_desc.vco_offset)) { pr_err("no VCO register offset for ICST clock\n"); + of_node_put(parent); return; } if (of_property_read_u32(np, "lock-offset", &icst_desc.lock_offset)) { pr_err("no lock register offset for ICST clock\n"); + of_node_put(parent); return; } @@ -552,6 +555,7 @@ static void __init of_syscon_icst_setup(struct device_node *np) ctype = ICST_INTEGRATOR_CP_CM_MEM; } else { pr_err("unknown ICST clock %pOF\n", np); + of_node_put(parent); return; } diff --git a/drivers/clk/versatile/clk-sp810.c b/drivers/clk/versatile/clk-sp810.c index b0e69686f7a9..28e5c0cf1fda 100644 --- a/drivers/clk/versatile/clk-sp810.c +++ b/drivers/clk/versatile/clk-sp810.c @@ -86,7 +86,7 @@ static void __init clk_sp810_of_setup(struct device_node *node) const char *parent_names[2]; int num = ARRAY_SIZE(parent_names); char name[12]; - struct clk_init_data init; + struct clk_init_data init = {}; static int instance; int i; bool deprecated; diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c index 9adbf5c33bd1..72e872ec6b7c 100644 --- a/drivers/clk/versatile/clk-vexpress-osc.c +++ b/drivers/clk/versatile/clk-vexpress-osc.c @@ -64,7 +64,7 @@ static const struct clk_ops vexpress_osc_ops = { static int vexpress_osc_probe(struct platform_device *pdev) { - struct clk_init_data init; + struct clk_init_data init = {}; struct vexpress_osc *osc; u32 range[2]; int ret; diff --git a/drivers/clk/x86/clk-pmc-atom.c b/drivers/clk/x86/clk-pmc-atom.c index 08c83e0abc41..43dda274e329 100644 --- a/drivers/clk/x86/clk-pmc-atom.c +++ b/drivers/clk/x86/clk-pmc-atom.c @@ -151,8 +151,8 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id, const char **parent_names, int num_parents) { + struct clk_init_data init = {}; struct clk_plt *pclk; - struct clk_init_data init; int ret; pclk = devm_kzalloc(&pdev->dev, sizeof(*pclk), GFP_KERNEL); diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index edf8c0eaca27..71abd46b3593 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -881,10 +881,10 @@ static int clk_wzrd_dynamic_reconfig_f(struct clk_hw *hw, unsigned long rate, struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); void __iomem *div_addr = divider->base + divider->offset; - rate_div = DIV_ROUND_DOWN_ULL(parent_rate * 1000, rate); + rate_div = DIV_ROUND_DOWN_ULL((u64)parent_rate * 1000, rate); clockout0_div = rate_div / 1000; - pre = DIV_ROUND_CLOSEST((parent_rate * 1000), rate); + pre = DIV_ROUND_CLOSEST_ULL((u64)parent_rate * 1000, rate); f = (u32)(pre - (clockout0_div * 1000)); f = f & WZRD_CLKOUT_FRAC_MASK; f = f << WZRD_CLKOUT_DIVIDE_WIDTH; @@ -936,9 +936,9 @@ static struct clk_hw *clk_wzrd_register_divf(struct device *dev, u32 div_type, spinlock_t *lock) { + struct clk_init_data init = {}; struct clk_wzrd_divider *div; struct clk_hw *hw; - struct clk_init_data init; int ret; div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); @@ -980,9 +980,9 @@ static struct clk_hw *clk_wzrd_ver_register_divider(struct device *dev, u32 div_type, spinlock_t *lock) { + struct clk_init_data init = {}; struct clk_wzrd_divider *div; struct clk_hw *hw; - struct clk_init_data init; int ret; div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); @@ -1026,9 +1026,9 @@ static struct clk_hw *clk_wzrd_register_divider(struct device *dev, u32 div_type, spinlock_t *lock) { + struct clk_init_data init = {}; struct clk_wzrd_divider *div; struct clk_hw *hw; - struct clk_init_data init; int ret; div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); @@ -1091,7 +1091,7 @@ static int clk_wzrd_clk_notifier(struct notifier_block *nb, unsigned long event, } } -static int __maybe_unused clk_wzrd_suspend(struct device *dev) +static int clk_wzrd_suspend(struct device *dev) { struct clk_wzrd *clk_wzrd = dev_get_drvdata(dev); @@ -1101,7 +1101,7 @@ static int __maybe_unused clk_wzrd_suspend(struct device *dev) return 0; } -static int __maybe_unused clk_wzrd_resume(struct device *dev) +static int clk_wzrd_resume(struct device *dev) { int ret; struct clk_wzrd *clk_wzrd = dev_get_drvdata(dev); @@ -1117,7 +1117,7 @@ static int __maybe_unused clk_wzrd_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(clk_wzrd_dev_pm_ops, clk_wzrd_suspend, +static DEFINE_SIMPLE_DEV_PM_OPS(clk_wzrd_dev_pm_ops, clk_wzrd_suspend, clk_wzrd_resume); static const struct versal_clk_data versal_data = { @@ -1378,7 +1378,7 @@ static struct platform_driver clk_wzrd_driver = { .driver = { .name = "clk-wizard", .of_match_table = clk_wzrd_ids, - .pm = &clk_wzrd_dev_pm_ops, + .pm = pm_sleep_ptr(&clk_wzrd_dev_pm_ops), }, .probe = clk_wzrd_probe, }; diff --git a/drivers/clk/xilinx/xlnx_vcu.c b/drivers/clk/xilinx/xlnx_vcu.c index f14bda375e35..ccd9d7c0b180 100644 --- a/drivers/clk/xilinx/xlnx_vcu.c +++ b/drivers/clk/xilinx/xlnx_vcu.c @@ -406,9 +406,9 @@ static struct clk_hw *xvcu_register_pll(struct device *dev, const char *name, const char *parent, unsigned long flags) { + struct clk_init_data init = {}; struct vcu_pll *pll; struct clk_hw *hw; - struct clk_init_data init; int ret; init.name = name; diff --git a/drivers/clk/zte/Kconfig b/drivers/clk/zte/Kconfig new file mode 100644 index 000000000000..0ccc6edf3c5b --- /dev/null +++ b/drivers/clk/zte/Kconfig @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# ZTE Clock Drivers +# + +config COMMON_CLK_ZTE + tristate "Clock driver for ZTE SoCs" + depends on HAS_IOMEM + depends on ARCH_ZTE || COMPILE_TEST + default ARCH_ZTE + select MFD_SYSCON + help + This option selects common clock infrastructure for ZTE based SoCs. + You will need to enable one or more SoC specific drivers to make use + of this. + + Enable this if you are building a kernel for a ZTE designed board. + +config CLK_ZTE_ZX297520V3 + tristate "Clock driver for ZTE zx297520v3 based SoCs" + depends on COMMON_CLK_ZTE && (MFD_ZTE_ZX297520V3_CRM || COMPILE_TEST) + default SOC_ZX297520V3 + help + This driver supports ZTE zx297520v3 basic clocks. + + Enable this if you want to build a kernel that is able to run on + boards based on this SoC. You can safely enable multiple clock + drivers. The one(s) matching the device tree will be used. diff --git a/drivers/clk/zte/Makefile b/drivers/clk/zte/Makefile new file mode 100644 index 000000000000..2c073512e919 --- /dev/null +++ b/drivers/clk/zte/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_COMMON_CLK_ZTE) += clk-zte.o +obj-$(CONFIG_CLK_ZTE_ZX297520V3) += clk-zx297520v3.o + +clk-zte-y += clk-zx.o pll-zx.o clk-regmap.o diff --git a/drivers/clk/zte/clk-regmap.c b/drivers/clk/zte/clk-regmap.c new file mode 100644 index 000000000000..022b2be7bb3d --- /dev/null +++ b/drivers/clk/zte/clk-regmap.c @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 BayLibre, SAS. + * Copyright (c) 2026 Stefan Dösinger + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk-zx.h" + +struct zte_clk_regmap { + struct clk_hw hw; + struct regmap *map; + u16 reg; + u8 shift; + u8 size; +}; + +static inline struct zte_clk_regmap *to_zte_clk_regmap(struct clk_hw *hw) +{ + return container_of(hw, struct zte_clk_regmap, hw); +} + +static int zte_clk_regmap_gate_enable(struct clk_hw *hw) +{ + struct zte_clk_regmap *clk = to_zte_clk_regmap(hw); + + return regmap_set_bits(clk->map, clk->reg, BIT(clk->shift)); +} + +static void zte_clk_regmap_gate_disable(struct clk_hw *hw) +{ + struct zte_clk_regmap *clk = to_zte_clk_regmap(hw); + + regmap_clear_bits(clk->map, clk->reg, BIT(clk->shift)); +} + +static int zte_clk_regmap_gate_is_enabled(struct clk_hw *hw) +{ + struct zte_clk_regmap *clk = to_zte_clk_regmap(hw); + + return regmap_test_bits(clk->map, clk->reg, BIT(clk->shift)); +} + +static const struct clk_ops zte_clk_regmap_gate_ops = { + .enable = zte_clk_regmap_gate_enable, + .disable = zte_clk_regmap_gate_disable, + .is_enabled = zte_clk_regmap_gate_is_enabled, +}; + +struct clk_hw *zx_clk_register_gate(struct device *dev, struct regmap *regmap, + const struct zx_gate_desc *desc, struct clk_hw * const *clocks) +{ + struct clk_parent_data parent = zx_get_parent(&desc->parent, clocks); + struct clk_init_data init = {}; + struct zte_clk_regmap *clk; + int res; + + clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL); + if (!clk) + return ERR_PTR(-ENOMEM); + + init.name = desc->name; + init.ops = &zte_clk_regmap_gate_ops; + init.parent_data = &parent; + init.num_parents = 1; + init.flags = CLK_SET_RATE_PARENT | desc->flags; + clk->hw.init = &init; + clk->map = regmap; + clk->reg = desc->reg; + clk->shift = desc->shift; + clk->size = 1; + + res = devm_clk_hw_register(dev, &clk->hw); + if (res) + return ERR_PTR(res); + + return &clk->hw; +} + +static unsigned long zte_clk_regmap_div_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct zte_clk_regmap *clk = to_zte_clk_regmap(hw); + unsigned int val; + int ret; + + ret = regmap_read(clk->map, clk->reg, &val); + if (ret) + return 0; /* Gives a hint that something is wrong */ + + val >>= clk->shift; + val &= clk_div_mask(clk->size); + + return divider_recalc_rate(hw, prate, val, NULL, 0, clk->size); +} + +static int zte_clk_regmap_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct zte_clk_regmap *clk = to_zte_clk_regmap(hw); + + return divider_determine_rate(hw, req, NULL, clk->size, 0); +} + +static int zte_clk_regmap_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct zte_clk_regmap *clk = to_zte_clk_regmap(hw); + unsigned int val; + int ret; + + ret = divider_get_val(rate, parent_rate, NULL, clk->size, 0); + if (ret < 0) + return ret; + + val = (unsigned int)ret << clk->shift; + + return regmap_update_bits(clk->map, clk->reg, clk_div_mask(clk->size) << clk->shift, val); +} + +static const struct clk_ops zte_clk_regmap_divider_ops = { + .recalc_rate = zte_clk_regmap_div_recalc_rate, + .determine_rate = zte_clk_regmap_div_determine_rate, + .set_rate = zte_clk_regmap_div_set_rate, +}; + +struct clk_hw *zx_clk_register_divider(struct device *dev, struct regmap *regmap, + const struct zx_div_desc *desc, + struct clk_hw * const *clocks) +{ + struct clk_parent_data parent = zx_get_parent(&desc->parent, clocks); + struct clk_init_data init = {}; + struct zte_clk_regmap *clk; + int res; + + clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL); + if (!clk) + return ERR_PTR(-ENOMEM); + + init.name = desc->name; + init.ops = &zte_clk_regmap_divider_ops; + init.parent_data = &parent; + init.num_parents = 1; + init.flags = CLK_SET_RATE_PARENT; + clk->hw.init = &init; + clk->map = regmap; + clk->reg = desc->reg; + clk->shift = desc->shift; + clk->size = desc->size; + + res = devm_clk_hw_register(dev, &clk->hw); + if (res) + return ERR_PTR(res); + + return &clk->hw; +} + +static u8 zte_clk_regmap_mux_get_parent(struct clk_hw *hw) +{ + struct zte_clk_regmap *clk = to_zte_clk_regmap(hw); + unsigned int val; + int ret; + + ret = regmap_read(clk->map, clk->reg, &val); + if (ret) + return 0xff; + + val >>= clk->shift; + val &= GENMASK(clk->size - 1, 0); + + return clk_mux_val_to_index(hw, NULL, 0, val); +} + +static int zte_clk_regmap_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct zte_clk_regmap *clk = to_zte_clk_regmap(hw); + unsigned int val = clk_mux_index_to_val(NULL, 0, index); + + return regmap_update_bits(clk->map, clk->reg, + GENMASK(clk->size - 1, 0) << clk->shift, + val << clk->shift); +} + +static int zte_clk_regmap_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + return clk_mux_determine_rate_flags(hw, req, 0); +} + +static const struct clk_ops zte_clk_regmap_mux_ops = { + .get_parent = zte_clk_regmap_mux_get_parent, + .set_parent = zte_clk_regmap_mux_set_parent, + .determine_rate = zte_clk_regmap_mux_determine_rate, +}; + +struct clk_hw *zx_clk_register_mux(struct device *dev, struct regmap *regmap, + const struct zx_mux_desc *desc, struct clk_hw * const *clocks) +{ + struct clk_parent_data parents[CLK_ZX_MAX_PARENTS]; + struct clk_init_data init = {}; + struct zte_clk_regmap *clk; + unsigned int i; + int res; + + if (WARN_ON(desc->num_parents > ARRAY_SIZE(parents))) + return ERR_PTR(-EINVAL); + + for (i = 0; i < desc->num_parents; ++i) + parents[i] = zx_get_parent(&desc->parents[i], clocks); + + clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL); + if (!clk) + return ERR_PTR(-ENOMEM); + + init.name = desc->name; + init.ops = &zte_clk_regmap_mux_ops; + init.parent_data = parents; + init.num_parents = desc->num_parents; + clk->hw.init = &init; + clk->map = regmap; + clk->reg = desc->reg; + clk->shift = desc->shift; + clk->size = desc->size; + + res = devm_clk_hw_register(dev, &clk->hw); + if (res) + return ERR_PTR(res); + + return &clk->hw; +} diff --git a/drivers/clk/zte/clk-zx.c b/drivers/clk/zte/clk-zx.c new file mode 100644 index 000000000000..aef0f7c753e6 --- /dev/null +++ b/drivers/clk/zte/clk-zx.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Stefan Dösinger + */ + +#include +#include +#include +#include +#include +#include + +#include "clk-zx.h" + +static struct clk_hw *zx_clk_register_fixed_div(struct device *dev, + const struct zx_fixed_divider_desc *desc, + struct clk_hw * const *clocks) +{ + const struct zx_parent_desc *p = &desc->parent; + + switch (p->type) { + case ZX_PARENT_FW: + return devm_clk_hw_register_fixed_factor_fwname(dev, NULL, desc->name, p->fw_name, + CLK_SET_RATE_PARENT, 1, desc->div); + + case ZX_PARENT_ID: + return devm_clk_hw_register_fixed_factor_parent_hw(dev, desc->name, clocks[p->id], + CLK_SET_RATE_PARENT, 1, + desc->div); + } + WARN_ON_ONCE(1); + return ERR_PTR(-EINVAL); +} + +static int zx_clk_validate(struct device *dev, struct device_node *of_node, + const struct zx_clk_data *data) +{ + const struct zx_parent_desc *parents; + unsigned int i, p, num_parents; + struct clk *clk; + + /* + * Sanity check: Make sure all parents are there and write a clear message rather than + * leave potential orphans. + * + * This check is unusual in clock drivers. It is in this driver because the clock tree is + * based on manual reverse engineering rather than generated from a SoC datasheet. + */ + for (i = 0; i < data->num_clocks; ++i) { + switch (data->clocks[i].type) { + case ZX_CLOCK_PLL: + parents = data->clocks[i].pll.parents; + num_parents = data->clocks[i].pll.num_parents; + break; + + case ZX_CLOCK_FIXED_DIV: + parents = &data->clocks[i].fixed_div.parent; + num_parents = 1; + break; + + case ZX_CLOCK_MUX: + parents = data->clocks[i].mux.parents; + num_parents = data->clocks[i].mux.num_parents; + break; + + case ZX_CLOCK_DIV: + parents = &data->clocks[i].div.parent; + num_parents = 1; + break; + + case ZX_CLOCK_GATE: + parents = &data->clocks[i].gate.parent; + num_parents = 1; + break; + + default: + return dev_err_probe(dev, -EINVAL, "Invalid clock entry %u\n", i); + } + + for (p = 0; p < num_parents; ++p) { + switch (parents[p].type) { + case ZX_PARENT_FW: + clk = of_clk_get_by_name(of_node, parents[p].fw_name); + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), + "Input clk %s failure\n", + parents[p].fw_name); + clk_put(clk); + break; + + case ZX_PARENT_ID: + if (parents[p].id >= i) + return dev_err_probe(dev, -EINVAL, + "Clock %u has parent %u\n", + i, parents[p].id); + break; + + default: + return dev_err_probe(dev, -EINVAL, + "Clock %u has unexpected parent of type %u\n", + i, parents[p].type); + } + } + } + + return 0; +} + +int zx_clk_common_probe(struct device *dev, struct device_node *of_node, + const struct zx_clk_data *data) +{ + struct clk_hw_onecell_data *exports; + struct clk_hw **clocks; + struct regmap *map; + unsigned int i; + int res; + + res = zx_clk_validate(dev, of_node, data); + if (res) + return res; + + map = device_node_to_regmap(of_node); + if (IS_ERR(map)) + return PTR_ERR(map); + + clocks = devm_kcalloc(dev, data->num_clocks, sizeof(*clocks), GFP_KERNEL); + if (!clocks) + return -ENOMEM; + + if (data->init) { + res = data->init(map); + if (res) + return res; + } + + for (i = 0; i < data->num_clocks; ++i) { + struct clk_hw *hw; + + switch (data->clocks[i].type) { + case ZX_CLOCK_PLL: + hw = zx_clk_register_pll(dev, map, &data->clocks[i].pll, clocks); + break; + + case ZX_CLOCK_FIXED_DIV: + hw = zx_clk_register_fixed_div(dev, &data->clocks[i].fixed_div, clocks); + break; + + case ZX_CLOCK_MUX: + hw = zx_clk_register_mux(dev, map, &data->clocks[i].mux, clocks); + break; + + case ZX_CLOCK_DIV: + hw = zx_clk_register_divider(dev, map, &data->clocks[i].div, clocks); + break; + + case ZX_CLOCK_GATE: + hw = zx_clk_register_gate(dev, map, &data->clocks[i].gate, clocks); + break; + + default: + return -EINVAL; + } + + if (IS_ERR(hw)) + return dev_err_probe(dev, PTR_ERR(hw), "Failed to register clk %u\n", i); + + clocks[i] = hw; + } + + exports = devm_kzalloc(dev, struct_size(exports, hws, data->num_exports), GFP_KERNEL); + if (!exports) + return -ENOMEM; + exports->num = data->num_exports; + + for (i = 0; i < data->num_exports; ++i) { + if (data->exports[i] >= data->num_clocks) + return dev_err_probe(dev, -EINVAL, + "Export %u points to out of range clock %u\n", + i, data->exports[i]); + + exports->hws[i] = clocks[data->exports[i]]; + } + + devm_kfree(dev, clocks); + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, exports); +} +EXPORT_SYMBOL_NS_GPL(zx_clk_common_probe, "ZTE_CLK"); + +MODULE_AUTHOR("Stefan Dösinger "); +MODULE_DESCRIPTION("ZTE common clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/zte/clk-zx.h b/drivers/clk/zte/clk-zx.h new file mode 100644 index 000000000000..8137185f497f --- /dev/null +++ b/drivers/clk/zte/clk-zx.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2026 Stefan Dösinger + */ + +#ifndef __DRV_CLK_ZX_H +#define __DRV_CLK_ZX_H + +#include +#include +#include +#include + +#define CLK_ZX_PLL_PREPARE_IS_ENABLE 1 +#define CLK_ZX_MAX_PARENTS 8 + +enum zx_parent_type { + ZX_PARENT_FW, + ZX_PARENT_ID, +}; + +struct zx_parent_desc { + enum zx_parent_type type; + union { + const char *fw_name; + unsigned int id; + }; +}; + +#define PARENT_FW(_name) { .type = ZX_PARENT_FW, .fw_name = (_name) } + +#define PARENT_ID(_id) { .type = ZX_PARENT_ID, .id = (_id) } + +static inline struct clk_parent_data zx_get_parent(const struct zx_parent_desc *p, + struct clk_hw * const *clocks) +{ + struct clk_parent_data ret = {}; + + switch (p->type) { + case ZX_PARENT_FW: + ret.fw_name = p->fw_name; + ret.index = -1; + return ret; + + case ZX_PARENT_ID: + ret.hw = clocks[p->id]; + ret.index = -1; + return ret; + } + + WARN_ON_ONCE(1); + return ret; +} + +struct zx_pll_desc { + const char *name; + const struct zx_parent_desc *parents; + unsigned int num_parents; + unsigned long rate; + u16 reg; + u16 flags; +}; + +struct zx_fixed_divider_desc { + const char *name; + struct zx_parent_desc parent; + unsigned int div; +}; + +struct zx_mux_desc { + const char *name; + const struct zx_parent_desc *parents; + unsigned int num_parents; + u16 reg; + u8 shift, size; +}; + +struct zx_div_desc { + const char *name; + struct zx_parent_desc parent; + u16 reg; + u8 shift, size; +}; + +struct zx_gate_desc { + const char *name; + struct zx_parent_desc parent; + unsigned long flags; + u16 reg; + u8 shift; +}; + +enum zx_clock_type { + ZX_CLOCK_INVALID = 0, + ZX_CLOCK_PLL, + ZX_CLOCK_FIXED_DIV, + ZX_CLOCK_MUX, + ZX_CLOCK_DIV, + ZX_CLOCK_GATE, +}; + +struct zx_clock { + enum zx_clock_type type; + union { + struct zx_pll_desc pll; + struct zx_fixed_divider_desc fixed_div; + struct zx_mux_desc mux; + struct zx_div_desc div; + struct zx_gate_desc gate; + }; +}; + +struct clk_hw *zx_clk_register_pll(struct device *dev, struct regmap *regmap, + const struct zx_pll_desc *desc, + struct clk_hw * const *clocks); +struct clk_hw *zx_clk_register_mux(struct device *dev, struct regmap *regmap, + const struct zx_mux_desc *desc, + struct clk_hw * const *clocks); +struct clk_hw *zx_clk_register_divider(struct device *dev, struct regmap *regmap, + const struct zx_div_desc *desc, + struct clk_hw * const *clocks); +struct clk_hw *zx_clk_register_gate(struct device *dev, struct regmap *regmap, + const struct zx_gate_desc *desc, + struct clk_hw * const *clocks); + +struct zx_clk_data { + int (*init)(struct regmap *map); + const struct zx_clock *clocks; + unsigned int num_clocks; + const unsigned int *exports; + unsigned int num_exports; +}; + +int zx_clk_common_probe(struct device *dev, struct device_node *of_node, + const struct zx_clk_data *data); + +#endif /* __DRV_CLK_ZX_H */ diff --git a/drivers/clk/zte/clk-zx297520v3.c b/drivers/clk/zte/clk-zx297520v3.c new file mode 100644 index 000000000000..e0f78f841bde --- /dev/null +++ b/drivers/clk/zte/clk-zx297520v3.c @@ -0,0 +1,1657 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Stefan Dösinger + * + * There are no public datasheets for zx297520v3. The controls on this clock controller have been + * extracted from ZTE's kernel and U-Boot sources and a LOT of manual testing. Some clocks can be + * found in the power management (evb_cpurpm.img) and LTE (cpko.ko) blobs shipped with the routers. + * + * Because ZTE's sources are wrong or misleading in some parts and testing can be misinterpreted, + * this file contains a LOT of comments on how particular clocks were tested and how the impact of + * changes to them can be observed. + */ + +#include +#include +#include +#include +#include +#include + +#include "clk-zx.h" + +MODULE_IMPORT_NS("ZTE_CLK"); + +/* + * AXI speed is either determined by a fixed selection in matrix+0x0, bits 0:2 or by a voting system + * with ballots in matrix+0x120, 0x124, 0x128. The voting system is enabled by setting matrix 0x12c + * to 1. Otherwise the selection in 0x0 applies. + * + * The fastest selected speed wins. This holds true for values 0 (26 MHz) and 7 (6.5 MHz) too, so it + * isn't a case of lowest selector wins. I haven't tested what happens if mpll is changed to output + * 5x the normal clock, so 7 beats 0. Presumably value 0 would still win the election. + * + * AXI speed 6.5 is a child of matrix-osc26m, not a PLL. This can be seen by gating it off in + * topcrm+0x140. + * + * The system initializes with voting disabled and all preferences set to the lowest setting, 7. + * The zx297520v3_matrix_init function transfers the global mux to our vote and enables voting. + * + * Because rprocs may change their selection without notice, all possible parents of the AXI mux are + * marked critical. This can however obscure bugs in the clock tree. Define ZX297520V3_AXI_CANDIDATE + * to 0 to disable this protection for testing and either not run anything on the rprocs or make + * sure Linux votes for the fastest rate. + */ +#define ZX297520V3_AXI_CANDIDATE CLK_IS_CRITICAL + +/* + * Top and matrix clocks are chaotic - I haven't found a consistent pattern behind their register + * and bit locations. Generally there are two gates (pclk, wclk), one mux, two resets and sometimes + * one divider, but exceptions apply. For some devices there is only a reset and some general + * (parent) clocks need setup. This structure plus macro handles the somewhat regular parts. + * + * There are some patterns that can be observed. + * mux 0x3c, div 0x48, gate 0x54 + * mux 0x40, div 0x4c, gate 0x5c + * mux 0x44, div 0x50, gate 0x60 + * + * For a 0 - 0xc - 0x18 pattern. Muxes from 0x3c to 0x44, dividers from 0x48 to 0x50, gates 0x54 to + * 0x60. The pattern is broken for timer t17 though. + * + * Gates have 4 bits per clock - usually, but not always, bit 0 for wclk, bit 1 for pclk, bit 2 for + * something the ZTE kernel calls "gate" (the bits we use here are called "en"), which presumably + * enables automatic clock gating. Bit 3, if settable, seems unused. E.g. offset 0x54 accepts all + * bits in 0xF77F7F7F - suggesting RTC, I2C0 have an extra gate bit. + * + * The default mpll settings multiply the 26 MHz reference clock times 24. A mux selection of 26 MHz + * could mean using the 26 MHz oscillator directly, or passing it through the PLL and divide by 24. + * + * If a UART is set to mpll-d6 (default 104 MHz), changing the mpll multipliers does affect UART + * timing as it should. This does not happen when the UART is set to 26 MHz input or timers that + * read 26 MHz input. This suggests 26 MHz clocks use the reference clock directly. + * + * The general clock flow on this board goes from osc26m into the PLLs. The PLL output is + * branched into a small number of divided frequencies (mpll, mpll-d4, mpll-d5, mpll-d6, mpll-d8, + * gpll, gpll-d2, gpll-d4) at a high level. These divided frequencies as well as osc26m go + * through a series of gates at offset 0x140 in topcrm. The output of these gates provide wclks for + * everything. + * + * At least 3 of those gate outputs (mpll, dpll, gpll-d2) are further divided behind those gates, + * presumably in the matrix controller. There are multiple paths how 104 and 78 MHz are derived, + * some specific to topcrm (0x140 bits 1 and 4), some specific to matrix (0x140 bit 9). There are + * likely 3 "copies" of the 78 MHz clock and two 50 MHz ones. + * + * Pclk is not gated by the 0x140 gates at all. Likewise osc32k is fed to the timers without + * passing through this gate, even for consumers on matrix/LSP. Topcrm osc26m wclks are not gated + * either, but top-consumed PLL clocks are. + */ + +enum top_clock_ids { + ZX_CLK_MPLL, + ZX_CLK_UPLL, + ZX_CLK_DPLL2, + ZX_CLK_DPLL2_D2, + ZX_CLK_DPLL, + ZX_CLK_GPLL, + + ZX_CLK_OSC26M_D2, + ZX_CLK_TOP_MPLL_D2_PREGATE, + ZX_CLK_TOP_MPLL_D4_PREGATE, + ZX_CLK_TOP_MPLL_D5_PREGATE, + ZX_CLK_TOP_MPLL_D6_PREGATE, + ZX_CLK_TOP_MPLL_D8_PREGATE, + ZX_CLK_TOP_UPLL_D12_PREGATE, + ZX_CLK_TOP_GPLL_D2_PREGATE, + ZX_CLK_TOP_GPLL_D4_PREGATE, + + ZX_CLK_TOP_MPLL_D2, + ZX_CLK_TOP_MPLL_D8, + ZX_CLK_TOP_MPLL_D6, + ZX_CLK_TOP_MPLL_D4, + ZX_CLK_TOMATRIX_MPLL_D5, + ZX_CLK_TOMATRIX_MPLL, + ZX_CLK_TOMATRIX_DPLL, + ZX_CLK_TOP_UPLL_D12, + ZX_CLK_TOP_UPLL, + ZX_CLK_TOP_GPLL_D4, + ZX_CLK_TOMATRIX_GPLL_D2, + ZX_CLK_TOMATRIX_GPLL, + ZX_CLK_TOMATRIX_OSC26M, + + ZX_CLK_TOP_MPLL_D2_D4, + ZX_CLK_TOP_MPLL_D2_D13, + ZX_CLK_TOP_UPLL_D12_D2, + ZX_CLK_TOP_GPLL_D4_D2, + + ZX_CLK_M0_MUX, + ZX_CLK_AHB_MUX, + ZX_CLK_TIMER_T08_MUX, + ZX_CLK_TIMER_T09_MUX, + ZX_CLK_TIMER_T12_MUX, + ZX_CLK_TIMER_T13_MUX, + ZX_CLK_TIMER_T14_MUX, + ZX_CLK_TIMER_T15_MUX, + ZX_CLK_TIMER_T16_MUX, + ZX_CLK_TIMER_T17_MUX, + ZX_CLK_WDT_T18_MUX, + ZX_CLK_I2C0_MUX, + ZX_CLK_UART0_MUX, + ZX_CLK_OUT0_MUX, + ZX_CLK_OUT1_MUX, + ZX_CLK_OUT2_MUX, + ZX_CLK_RMIIPHY_MUX, + + ZX_CLK_TIMER_T08_DIV, + ZX_CLK_TIMER_T09_DIV, + ZX_CLK_TIMER_T12_DIV, + ZX_CLK_TIMER_T13_DIV, + ZX_CLK_TIMER_T14_DIV, + ZX_CLK_TIMER_T15_DIV, + ZX_CLK_TIMER_T16_DIV, + ZX_CLK_TIMER_T17_DIV, + ZX_CLK_WDT_T18_DIV, + ZX_CLK_USIM1_DIV, + + ZX_CLK_AHB_PCLK, + ZX_CLK_AHB_WCLK, + ZX_CLK_SRAM1_PCLK, + ZX_CLK_SRAM2_PCLK, + ZX_CLK_PMM_WCLK, + ZX_CLK_PMM_PCLK, + ZX_CLK_TIMER_T08_WCLK, + ZX_CLK_TIMER_T08_PCLK, + ZX_CLK_TIMER_T09_WCLK, + ZX_CLK_TIMER_T09_PCLK, + ZX_CLK_TIMER_T12_WCLK, + ZX_CLK_TIMER_T12_PCLK, + ZX_CLK_TIMER_T13_WCLK, + ZX_CLK_TIMER_T13_PCLK, + ZX_CLK_TIMER_T14_WCLK, + ZX_CLK_TIMER_T14_PCLK, + ZX_CLK_TIMER_T15_WCLK, + ZX_CLK_TIMER_T15_PCLK, + ZX_CLK_TIMER_T16_WCLK, + ZX_CLK_TIMER_T16_PCLK, + ZX_CLK_TIMER_T17_WCLK, + ZX_CLK_TIMER_T17_PCLK, + ZX_CLK_WDT_T18_WCLK, + ZX_CLK_WDT_T18_PCLK, + ZX_CLK_I2C0_WCLK, + ZX_CLK_I2C0_PCLK, + ZX_CLK_UART0_WCLK, + ZX_CLK_UART0_PCLK, + ZX_CLK_USB_WCLK, + ZX_CLK_USB_PCLK, + ZX_CLK_HSIC_WCLK, + ZX_CLK_HSIC_PCLK, + ZX_CLK_RTC_WCLK, + ZX_CLK_RTC_PCLK, + ZX_CLK_USIM1_WCLK, + ZX_CLK_USIM1_PCLK, + ZX_CLK_LPM_GSM_WCLK, + ZX_CLK_LPM_GSM_PCLK, + ZX_CLK_LPM_LTE_WCLK, + ZX_CLK_LPM_LTE_PCLK, + ZX_CLK_LPM_TD_WCLK, + ZX_CLK_LPM_TD_PCLK, + ZX_CLK_LPM_W_WCLK, + ZX_CLK_LPM_W_PCLK, + ZX_CLK_OUT0_WCLK, + ZX_CLK_OUT1_WCLK, + ZX_CLK_OUT2_WCLK, + ZX_CLK_OUT32K_WCLK, + ZX_CLK_RMIIPHY_WCLK, + ZX_CLK_GSM_32K, + ZX_CLK_GSM_26M, + ZX_CLK_GSM_48M, + ZX_CLK_GSM_104M, + ZX_CLK_GSM_156M, + ZX_CLK_ABB_WCLK, +}; + +/* Used for gates where we don't know the parent input(s). Assume general oscillator */ +static const struct zx_parent_desc clk_unknown = PARENT_FW("osc26m"); + +/* For clocks that are known to use the ungated osc26m input */ +static const struct zx_parent_desc clk_main[] = { + PARENT_FW("osc26m"), +}; + +static const struct zx_parent_desc dpll_parents[] = { + PARENT_ID(ZX_CLK_DPLL2_D2), + PARENT_FW("osc26m"), +}; + +/* + * AHB: The clock mux works and impact can be tested e.g. with iperf speed testing of the USB + * network connection. Values 2 and 3 give the same speed and depend on the same bit (3) in 0x140. + * The mpll-d6 rate is gated off by the same bit in 0x140 as m0's mpll-d6, but the d8 is different. + * This may indicate that one of the two uses a different clock rate than documented in ZTE's + * kernel. The M0 speed is easy to measure, so I am confident in the M0's 78 MHz rate. AHB looks + * like 78 rather than 52, but confidence is lower because RAM read tests are influenced by CPU + * overhead too. + */ + +static const struct zx_parent_desc ahb_sel[] = { + PARENT_FW("osc26m"), + PARENT_ID(ZX_CLK_TOP_MPLL_D6), /* 104 MHz */ + PARENT_ID(ZX_CLK_TOP_MPLL_D8), /* 78 MHz */ + PARENT_ID(ZX_CLK_TOP_MPLL_D8), /* 78 MHz */ +}; + +static const struct zx_parent_desc timer_top_sel[] = { + PARENT_FW("osc32k"), + PARENT_FW("osc26m"), +}; + +static const struct zx_parent_desc uart_top_sel[] = { + PARENT_FW("osc26m"), + PARENT_ID(ZX_CLK_TOP_MPLL_D6), /* 104 MHz, sharing M0's and ahb's 0x140 gate */ +}; + +/* + * The Cortex M0 coprocessor. It is responsible for booting the board and runs some power management + * helper code on the stock firmware. The M0 rproc itself is not critical, but most of topcrm's + * registers become unreadable if this is gated off or become slow when clocked at 32 kHz, e.g. GPIO + * becomes borderline unusable at 32 kHz. + * + * There is no dedicated M0 gate. Disabling ahb-wclk looks like the M0 stops from A53's point of + * view, but it merely breaks the A53's ability to communicate with it, and M0's ability to + * communicate with the standard UART on LSP. M0 keeps running with both ahb-wclk and ahb-pclk + * gated off and can re-enable the gates. + */ +static const struct zx_parent_desc m0_sel[] = { + PARENT_FW("osc26m"), + PARENT_ID(ZX_CLK_TOP_MPLL_D6), /* 104 MHz */ + PARENT_ID(ZX_CLK_TOP_MPLL_D2_D4), /* 78 MHz, but different gate than the ahb 78 MHz */ + PARENT_FW("osc32k"), /* Yes, tested. It is SLLLLOOOOOWWW. */ +}; + +/* + * Clk-out0/1/2/32k: These clocks are exposed on GPIOs 15, 16, 17 and 18 respectively. They are used + * in ZTE's camera and sound code, by directly poking into the clock registers from the device + * drivers. Until the respective devices are supported they can safely be switched off. + * + * For clk-out1 ZTE's camera code says the following: + * + * 0 -> 20 MHz + * 1 -> 40 MHz + * 2 -> 13 MHz + * 3 -> 26 MHz + * + * 0 and 1 read from upll. I confirmed their rates (upll-d24 and upll-d12) by setting upll to a very + * low frequency and sampling the clock by GPIO reads. The outputs of 2 and 3 are way too high to + * test that way. Neither is reading from any PLL, they keep oscillating when all PLLs are disabled. + * I am fairly sure that 3 is just direct osc26m because it perfectly matches what out2 is + * showing in its 26 MHz setting. + * + * Clk-out2 is similar, but it has only one control bit in top 0x34 bit 8. Neither setting selects + * a PLL output. When setting *0x34 = 0x080, clk-out1 and clk-out2 are in lockstep, presumably + * running at 13 MHz. 0x1c0 also runs in lockstep, presumably 26 MHz. + * + * clk-out0 has a mux in bit 5. Value 0 most likely selects osc26m. I am not entirely sure about + * value 1 (which is the default), but the m0 mux has an impact on it. It looks like a debug pin + * that exposes some core clock. + */ +static const struct zx_parent_desc out0_sel[] = { + PARENT_FW("osc26m"), + PARENT_ID(ZX_CLK_M0_MUX), +}; + +static const struct zx_parent_desc out1_sel[] = { + PARENT_ID(ZX_CLK_TOP_UPLL_D12_D2), /* 20 MHz */ + PARENT_ID(ZX_CLK_TOP_UPLL_D12), /* 40 MHz */ + PARENT_ID(ZX_CLK_OSC26M_D2), /* 13 MHz */ + PARENT_FW("osc26m"), +}; + +static const struct zx_parent_desc out2_sel[] = { + PARENT_ID(ZX_CLK_OSC26M_D2), /* 13 MHz */ + PARENT_FW("osc26m"), +}; + +/* + * Clk-o is similar to clk-out*, providing a clock on GPIO 20, presumably for driving a (R)MII phy. + * The 50 MHz value is documented in a stray comment in ZTE's GMAC driver. I tested it similarly to + * the above pins. Mux setting 0 gives half the count as setting 1 and setting 1 gives gpll divided + * by 4 - matching the 50 MHz suggested by the ZTE comment at the default gpll settings. Gating gpll + * stops the clock for values 0 and 1. + * + * Settings 2 and 3 are possible, but seem to return garbage. It is generally pulsing up and down, + * except if both gpll and upll are stopped. I suspect it just reads random electrical fluctuation + * from other places in the board. Yes, I had a pull-down enabled when testing this. + * + * I am not aware of any board that uses this though. The Ethernet-equipped ones I have all run the + * PHY with its own oscillator. + */ +static const struct zx_parent_desc rmii_sel[] = { + PARENT_ID(ZX_CLK_TOP_GPLL_D4_D2), /* 25 MHz */ + PARENT_ID(ZX_CLK_TOP_GPLL_D4), /* 50 MHz */ +}; + +#define PLL(_name, _parents, _rate, _reg, _flags) \ + { \ + .type = ZX_CLOCK_PLL, \ + .pll = { \ + .name = _name, \ + .parents = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .rate = _rate, \ + .reg = _reg, \ + .flags = _flags, \ + }, \ + } + +#define FIXED_DIV(_name, _parent, _div) \ + { \ + .type = ZX_CLOCK_FIXED_DIV, \ + .fixed_div = { \ + .name = _name, \ + .parent = _parent, \ + .div = _div, \ + }, \ + } + +#define MUX(_name, _parents, _reg, _shift, _size) \ + { \ + .type = ZX_CLOCK_MUX, \ + .mux = { \ + .name = _name, \ + .parents = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .reg = _reg, \ + .shift = _shift, \ + .size = _size, \ + }, \ + } + +#define DIV(_name, _parent, _reg, _shift, _size) \ + { \ + .type = ZX_CLOCK_DIV, \ + .div = { \ + .name = _name, \ + .parent = _parent, \ + .reg = _reg, \ + .shift = _shift, \ + .size = _size, \ + }, \ + } + +#define GATE(_name, _parent, _reg, _shift, _flags) \ + { \ + .type = ZX_CLOCK_GATE, \ + .gate = { \ + .name = _name, \ + .parent = _parent, \ + .reg = _reg, \ + .flags = _flags, \ + .shift = _shift, \ + }, \ + } + +static const struct zx_clock zx297520v3_top_clocks[] = { + /* + * Default setting: 0x48040c11. 624/312/156. Only a single possible parent. This is the + * PLL for pretty much everything, including CPU, RAM and USB. + * + * Changing this PLL makes it possible to overclock the CPU or do more fine grained + * underclocking than the CPU's mux allows. It does run into two problems though: The USB + * device uses this PLL's output directly and is *very* sensitive to differences. DRAM + * is also fed by this clock and needs to be re-trained on larger changes, which needs to + * be done by the stage 1 boot loader. + */ + [ZX_CLK_MPLL] = PLL("mpll", clk_main, 0, 0x8, 0), + + /* + * ZTE's code calls this PLL "upll". The only possible consumers I found are clk-out1, + * which outputs this clock on GPIO 16 and HSIC. HSIC doesn't have anything connected to + * it on the devices I tested. The device that consumes clk-out1 seems to be an SPI + * camera, which I haven't seen in any device so far. ZTE manipulates this PLL directly out + * of the camera code, so it is unlikely to have another consumer. + * + * Long story short, shut it off. + */ + [ZX_CLK_UPLL] = PLL("upll", clk_main, 0, 0x10, 0), + + /* + * Default value 0x4834902d. Feeds dpll. 46.08 MHz. Bit 25 can be set, so two parents are + * possible. It looks like both values select the 26 MHz oscillator though. + * + * Since dpll's prepare may depend on this clock generating a usable signal, it needs to be + * enabled when prepared. + * + * It isn't named anywhere in ZTE's code, but cpko.ko has the string "dpll2" somewhere in + * its clock tables. + */ + [ZX_CLK_DPLL2] = PLL("dpll2", clk_main, 0, 0x100, CLK_ZX_PLL_PREPARE_IS_ENABLE), + [ZX_CLK_DPLL2_D2] = FIXED_DIV("dpll2-d2", PARENT_ID(ZX_CLK_DPLL2), 2), + + /* + * The documentation says 491.52 MHz and measurement with the LSP TDM device supports this. + * The default value is 0x480c2011, but not all boot loaders set it up. To get to 491.52 + * with these settings it needs a 23.04 MHz reference clock, which matches dpll2-d2. If + * dpll2 is disabled, dpll loses its lock. We set the frequency on this PLL if we find it is + * not prepared by the boot loader. + * + * The proprietary LTE driver and/or rproc prepare and unprepare it. TDM and I2S can use it. + * + * It accepts parent values 0, 1, 2 and 3. Parent 0 is dpll2-d2. The others look like + * osc26m. With a parent != 0 dpll never loses its lock even when all other PLLs are off + * and the TDM counter register increases at a rate consistent with a 26.0/23.04 clock + * increase. + */ + [ZX_CLK_DPLL] = PLL("dpll", dpll_parents, 491520000, 0x18, 0), + + /* + * "g" is either for "general" or "gigahertz". The VCO runs at 1 GHz. Output clocks are 200, + * 100, 50, 25, ... MHz. It is used optionally by SDIO and QSPI and can drive a GPIO clock + * output for RMII, so it doesn't seem very general. + */ + [ZX_CLK_GPLL] = PLL("gpll", clk_main, 0, 0x110, 0), + + /* osc26m division for clk_outX */ + [ZX_CLK_OSC26M_D2] = FIXED_DIV("osc26m-d2", clk_main[0], 2), + + /* Pre-0x140 distribution fixed divs */ + [ZX_CLK_TOP_MPLL_D2_PREGATE] = FIXED_DIV("mpll-d2", PARENT_ID(ZX_CLK_MPLL), 2), + [ZX_CLK_TOP_MPLL_D4_PREGATE] = FIXED_DIV("mpll-d4", PARENT_ID(ZX_CLK_MPLL), 4), + [ZX_CLK_TOP_MPLL_D5_PREGATE] = FIXED_DIV("mpll-d5", PARENT_ID(ZX_CLK_MPLL), 5), + [ZX_CLK_TOP_MPLL_D6_PREGATE] = FIXED_DIV("mpll-d6", PARENT_ID(ZX_CLK_MPLL), 6), + [ZX_CLK_TOP_MPLL_D8_PREGATE] = FIXED_DIV("mpll-d8", PARENT_ID(ZX_CLK_MPLL), 8), + [ZX_CLK_TOP_UPLL_D12_PREGATE] = FIXED_DIV("upll-d12", PARENT_ID(ZX_CLK_UPLL), 12), + [ZX_CLK_TOP_GPLL_D2_PREGATE] = FIXED_DIV("gpll-d2", PARENT_ID(ZX_CLK_GPLL), 2), + [ZX_CLK_TOP_GPLL_D4_PREGATE] = FIXED_DIV("gpll-d4", PARENT_ID(ZX_CLK_GPLL), 4), + + /* + * topcrm distribution gates. These are complicated, but shed a lot of light on the board's + * clock distribution. + * + * Settable mask: 0x017333FF. Generally one nibble per PLL, except for MPLL that has more. + * One for osc26m work clock. pclk and osc32k are not gated globally here or anywhere else + * as far as I can see. + * + * If you want to test your understanding of this board, try to manually configure it into a + * setup where bit 24 or bit 9 are off without crashing it. + */ + + /* Bit 0: No known consumer */ + /* Bit 1: M0's 78 MHz selection, but somehow also involved in USB too */ + [ZX_CLK_TOP_MPLL_D2] = GATE("top-mpll-d2", PARENT_ID(ZX_CLK_TOP_MPLL_D2_PREGATE), + 0x140, 1, 0), + /* Bit 2: No known consumer, named "mpll_48m_clk" in ZTE's cpko.ko blob */ + [ZX_CLK_TOP_MPLL_D8] = GATE("top-mpll-d8", PARENT_ID(ZX_CLK_TOP_MPLL_D8_PREGATE), + 0x140, 3, 0), + [ZX_CLK_TOP_MPLL_D6] = GATE("top-mpll-d6", PARENT_ID(ZX_CLK_TOP_MPLL_D6_PREGATE), + 0x140, 4, 0), + [ZX_CLK_TOP_MPLL_D4] = GATE("top-mpll-d4", PARENT_ID(ZX_CLK_TOP_MPLL_D4_PREGATE), + 0x140, 5, 0), + [ZX_CLK_TOMATRIX_MPLL_D5] = GATE("matrix-mpll-d5", PARENT_ID(ZX_CLK_TOP_MPLL_D5_PREGATE), + 0x140, 6, ZX297520V3_AXI_CANDIDATE), + /* Bit 7: No known consumer */ + /* Bit 8: Has a consumer, LTE depends on it. But unknown what and how. */ + /* + * Bit 9: Big MPLL provider for Matrix. It is an AXI voting candidate, but it is protected + * in Matrix's 0x118 gates. + */ + [ZX_CLK_TOMATRIX_MPLL] = GATE("matrix-mpll", PARENT_ID(ZX_CLK_MPLL), 0x140, 9, 0), + /* Bit 10: Always 0 */ + /* Bit 11: Always 0 */ + + /* Bit 12: No known consumer. Existing patterns indicate a dpll consumer in top itself */ + [ZX_CLK_TOMATRIX_DPLL] = GATE("matrix-dpll", PARENT_ID(ZX_CLK_DPLL), 0x140, 13, 0), + /* Bit 14: Always 0 */ + /* Bit 15: Always 0 */ + + [ZX_CLK_TOP_UPLL_D12] = GATE("top-upll-d12", PARENT_ID(ZX_CLK_TOP_UPLL_D12_PREGATE), + 0x140, 16, 0), + [ZX_CLK_TOP_UPLL] = GATE("top-upll", PARENT_ID(ZX_CLK_UPLL), 0x140, 17, 0), + /* Bit 18: Always 0 */ + /* Bit 19: Always 0 */ + + [ZX_CLK_TOP_GPLL_D4] = GATE("top-gpll-d4", PARENT_ID(ZX_CLK_TOP_GPLL_D4_PREGATE), + 0x140, 20, 0), + [ZX_CLK_TOMATRIX_GPLL_D2] = GATE("matrix-gpll-d2", PARENT_ID(ZX_CLK_TOP_GPLL_D2_PREGATE), + 0x140, 21, 0), + [ZX_CLK_TOMATRIX_GPLL] = GATE("matrix-gpll", PARENT_ID(ZX_CLK_GPLL), 0x140, 22, 0), + /* Bit 23: Always 0 */ + + /* + * Bit 24 covers all 26 MHz on matrix, but not pclks. Osc26m consumers on topcrm do not + * use this, they get the ungated osc26m. It is an AXI voting candidate, but does not + * need protection because it is the slowest speed. It will only be used if every processor, + * including us, votes for it. + */ + [ZX_CLK_TOMATRIX_OSC26M] = GATE("matrix-osc26m", clk_main[0], 0x140, 24, 0), + + /* + * Post-140 divisions. They enter through the same bit and can be selected by different mux + * values of their consumers or get piped to multiple consumers with different documented + * rates - in particular, USB wclk (24 MHz according to ZTE) shares bit 1 with M0's 78 MHz. + */ + [ZX_CLK_TOP_MPLL_D2_D4] = FIXED_DIV("top-mpll-d2-d4", PARENT_ID(ZX_CLK_TOP_MPLL_D2), 4), + [ZX_CLK_TOP_MPLL_D2_D13] = FIXED_DIV("top-mpll-d2-d13", PARENT_ID(ZX_CLK_TOP_MPLL_D2), + 13), + [ZX_CLK_TOP_UPLL_D12_D2] = FIXED_DIV("top-upll-d12-d2", PARENT_ID(ZX_CLK_TOP_UPLL_D12), + 2), + [ZX_CLK_TOP_GPLL_D4_D2] = FIXED_DIV("top-gpll-d4-d2", PARENT_ID(ZX_CLK_TOP_GPLL_D4), 2), + + /* Device-specific Muxes */ + [ZX_CLK_M0_MUX] = MUX("m0-mux", m0_sel, 0x38, 0, 2), + [ZX_CLK_AHB_MUX] = MUX("ahb-mux", ahb_sel, 0x3c, 4, 2), + [ZX_CLK_TIMER_T08_MUX] = MUX("timer-t08-mux", timer_top_sel, 0x40, 1, 1), + [ZX_CLK_TIMER_T09_MUX] = MUX("timer-t09-mux", timer_top_sel, 0x40, 0, 1), + [ZX_CLK_TIMER_T12_MUX] = MUX("timer-t12-mux", timer_top_sel, 0x3c, 0, 1), + [ZX_CLK_TIMER_T13_MUX] = MUX("timer-t13-mux", timer_top_sel, 0x44, 0, 1), + [ZX_CLK_TIMER_T14_MUX] = MUX("timer-t14-mux", timer_top_sel, 0x44, 1, 1), + [ZX_CLK_TIMER_T15_MUX] = MUX("timer-t15-mux", timer_top_sel, 0x3c, 3, 1), + [ZX_CLK_TIMER_T16_MUX] = MUX("timer-t16-mux", timer_top_sel, 0x44, 2, 1), + [ZX_CLK_TIMER_T17_MUX] = MUX("timer-t17-mux", timer_top_sel, 0x120, 0, 1), + [ZX_CLK_WDT_T18_MUX] = MUX("wdt-t18-mux", timer_top_sel, 0x3c, 6, 1), + [ZX_CLK_I2C0_MUX] = MUX("i2c0-mux", uart_top_sel, 0x3c, 1, 1), + [ZX_CLK_UART0_MUX] = MUX("uart0-mux", uart_top_sel, 0x40, 2, 1), + [ZX_CLK_OUT0_MUX] = MUX("out0-mux", out0_sel, 0x34, 5, 1), + [ZX_CLK_OUT1_MUX] = MUX("out1-mux", out1_sel, 0x34, 6, 2), + [ZX_CLK_OUT2_MUX] = MUX("out2-mux", out2_sel, 0x34, 8, 1), + [ZX_CLK_RMIIPHY_MUX] = MUX("rmiiphy-mux", rmii_sel, 0x11c, 0, 2), + + /* Device-specific dividers */ + [ZX_CLK_TIMER_T08_DIV] = DIV("timer-t08-div", PARENT_ID(ZX_CLK_TIMER_T08_MUX), + 0x4c, 8, 4), + [ZX_CLK_TIMER_T09_DIV] = DIV("timer-t09-div", PARENT_ID(ZX_CLK_TIMER_T09_MUX), + 0x4c, 0, 4), + [ZX_CLK_TIMER_T12_DIV] = DIV("timer-t12-div", PARENT_ID(ZX_CLK_TIMER_T12_MUX), + 0x48, 0, 4), + [ZX_CLK_TIMER_T13_DIV] = DIV("timer-t13-div", PARENT_ID(ZX_CLK_TIMER_T13_MUX), + 0x50, 0, 4), + [ZX_CLK_TIMER_T14_DIV] = DIV("timer-t14-div", PARENT_ID(ZX_CLK_TIMER_T14_MUX), + 0x50, 4, 4), + [ZX_CLK_TIMER_T15_DIV] = DIV("timer-t15-div", PARENT_ID(ZX_CLK_TIMER_T15_MUX), + 0x48, 4, 4), + [ZX_CLK_TIMER_T16_DIV] = DIV("timer-t16-div", PARENT_ID(ZX_CLK_TIMER_T16_MUX), + 0x50, 8, 4), + [ZX_CLK_TIMER_T17_DIV] = DIV("timer-t17-div", PARENT_ID(ZX_CLK_TIMER_T17_MUX), + 0x124, 0, 4), + [ZX_CLK_WDT_T18_DIV] = DIV("wdt-t18-div", PARENT_ID(ZX_CLK_WDT_T18_MUX), + 0x48, 8, 4), + [ZX_CLK_USIM1_DIV] = DIV("usim1-div", clk_unknown, + 0x48, 12, 1), + + /* Device specific gates */ + + /* + * AHB clock gates: Disabling these cuts off the A53 from register access into 0x130000/ + * 0x140000, including the topcrm region, so it can't be re-enabled. Mark them critical for + * that reason. + * + * Gating this off does not stop the M0 rproc, nor does it stop M0 from accessing topcrm. It + * does however gate off M0 from the AXI interconnect, so it can't read RAM, Matrix, etc. So + * these bits here merely gate the bus, not the actual devices. + */ + [ZX_CLK_AHB_PCLK] = GATE("ahb-pclk", PARENT_ID(ZX_CLK_AHB_MUX), 0x54, 12, + CLK_IS_CRITICAL), + [ZX_CLK_AHB_WCLK] = GATE("ahb-wclk", PARENT_ID(ZX_CLK_M0_MUX), 0x54, 13, + CLK_IS_CRITICAL), + + /* SRAM1 and 2 clocks. Leave them on for now, as turning them off carelessly hangs the M0 */ + [ZX_CLK_SRAM1_PCLK] = GATE("sram1-pclk", clk_main[0], 0x54, 18, CLK_IS_CRITICAL), + [ZX_CLK_SRAM2_PCLK] = GATE("sram2-pclk", clk_main[0], 0x54, 16, CLK_IS_CRITICAL), + + /* + * Pinmux (AON, TOP, IOCFG but not PDCFG). Critical as well until we have a driver that + * consumes it. I don't think we'll realistically shut this off ever. + * + * Setting either bit 0 or 1 in register 0x58 makes the device work. + */ + [ZX_CLK_PMM_WCLK] = GATE("pmm-wclk", clk_main[0], 0x58, 0, CLK_IS_CRITICAL), + [ZX_CLK_PMM_PCLK] = GATE("pmm-pclk", clk_main[0], 0x58, 1, CLK_IS_CRITICAL), + + /* + * Timers. We don't use any of them, just shut them off. The timers are named and sorted + * by the IO address of the main timer controls. Some of the controls are documented in + * ZTE's kernel, the others I found by trial and error. Timers in register 0x54 have the + * pclk first, the others have the wclk first. + * + * Timer T17 is used by the ZSP firmware. The rproc driver will enable it as needed. + */ + [ZX_CLK_TIMER_T08_WCLK] = GATE("timer-t08-wclk", PARENT_ID(ZX_CLK_TIMER_T08_DIV), + 0x5c, 8, 0), + [ZX_CLK_TIMER_T08_PCLK] = GATE("timer-t08-pclk", clk_main[0], 0x5c, 9, 0), + [ZX_CLK_TIMER_T09_WCLK] = GATE("timer-t09-wclk", PARENT_ID(ZX_CLK_TIMER_T09_DIV), + 0x5c, 4, 0), + [ZX_CLK_TIMER_T09_PCLK] = GATE("timer-t09-pclk", clk_main[0], 0x5c, 5, 0), + [ZX_CLK_TIMER_T12_WCLK] = GATE("timer-t12-wclk", PARENT_ID(ZX_CLK_TIMER_T12_DIV), + 0x54, 5, 0), + [ZX_CLK_TIMER_T12_PCLK] = GATE("timer-t12-pclk", clk_main[0], 0x54, 4, 0), + [ZX_CLK_TIMER_T13_WCLK] = GATE("timer-t13-wclk", PARENT_ID(ZX_CLK_TIMER_T13_DIV), + 0x60, 0, 0), + [ZX_CLK_TIMER_T13_PCLK] = GATE("timer-t13-pclk", clk_main[0], 0x60, 1, 0), + [ZX_CLK_TIMER_T14_WCLK] = GATE("timer-t14-wclk", PARENT_ID(ZX_CLK_TIMER_T14_DIV), + 0x60, 4, 0), + [ZX_CLK_TIMER_T14_PCLK] = GATE("timer-t14-pclk", clk_main[0], 0x60, 5, 0), + [ZX_CLK_TIMER_T15_WCLK] = GATE("timer-t15-wclk", PARENT_ID(ZX_CLK_TIMER_T15_DIV), + 0x54, 21, 0), + [ZX_CLK_TIMER_T15_PCLK] = GATE("timer-t15-pclk", clk_main[0], 0x54, 20, 0), + [ZX_CLK_TIMER_T16_WCLK] = GATE("timer-t16-wclk", PARENT_ID(ZX_CLK_TIMER_T16_DIV), + 0x60, 8, 0), + [ZX_CLK_TIMER_T16_PCLK] = GATE("timer-t16-pclk", clk_main[0], 0x60, 9, 0), + [ZX_CLK_TIMER_T17_WCLK] = GATE("timer-t17-wclk", PARENT_ID(ZX_CLK_TIMER_T17_DIV), + 0x128, 0, 0), + [ZX_CLK_TIMER_T17_PCLK] = GATE("timer-t17-pclk", clk_main[0], 0x128, 1, 0), + + /* + * This watchdog is set up by ZTE's bootloader and in ZTE's OS the m0 firmware will feed the + * dog. The m0 firmware in turn wants to be fed in its own way. Since we normally don't run + * any m0 firmware we shut it off by default and expose it to userspace via the watchdog + * driver. + */ + [ZX_CLK_WDT_T18_WCLK] = GATE("wdt-t18-wclk", PARENT_ID(ZX_CLK_WDT_T18_DIV), + 0x54, 25, 0), + [ZX_CLK_WDT_T18_PCLK] = GATE("wdt-t18-pclk", clk_main[0], 0x54, 24, 0), + + [ZX_CLK_I2C0_WCLK] = GATE("i2c0-wclk", PARENT_ID(ZX_CLK_I2C0_MUX), 0x54, 9, 0), + [ZX_CLK_I2C0_PCLK] = GATE("i2c0-pclk", clk_main[0], 0x54, 8, 0), + [ZX_CLK_UART0_WCLK] = GATE("uart0-wclk", PARENT_ID(ZX_CLK_UART0_MUX), 0x5c, 12, 0), + [ZX_CLK_UART0_PCLK] = GATE("uart0-pclk", clk_main[0], 0x5c, 13, 0), + + /* + * ZTE says the USB input is a 24 MHz clock based on mpll. Testing shows that upll is not + * involved. The USB register space can be accessed with ahb-pclk gated, but not with + * ahb-wclk gated. ZTE also lists ahb-wclk as parent for the second clock. + * + * There doesn't seem to be a separate PHY clock. usb-wclk stops controller registers from + * updating, but doesn't cause the USB device to disconnect like asserting the PHY reset + * does. Bit 0 in this register can't be set, so no PHY clock is hiding there either. + */ + [ZX_CLK_USB_WCLK] = GATE("usb-wclk", PARENT_ID(ZX_CLK_TOP_MPLL_D2_D13), 0x6c, 3, 0), + [ZX_CLK_USB_PCLK] = GATE("usb-pclk", PARENT_ID(ZX_CLK_AHB_WCLK), 0x6c, 4, 0), + /* + * The HSIC hardware is listed in ZTE's code with a physical address of 0x01600000. Unlike + * the USB controller, it does consume upll. ZTE says 240 MHz, but 480 is the usual one for + * HSIC. + */ + [ZX_CLK_HSIC_WCLK] = GATE("hsic-wclk", PARENT_ID(ZX_CLK_TOP_UPLL), 0x6c, 1, 0), + [ZX_CLK_HSIC_PCLK] = GATE("hsic-pclk", PARENT_ID(ZX_CLK_AHB_WCLK), 0x6c, 2, 0), + + /* + * How does this RTC work? I don't know, the ZTE kernel does not talk to it. The actual RTC + * is on the I2C-connected PMIC. + */ + [ZX_CLK_RTC_WCLK] = GATE("rtc-wclk", clk_unknown, 0x54, 1, 0), + [ZX_CLK_RTC_PCLK] = GATE("rtc-pclk", clk_main[0], 0x54, 0, 0), + + [ZX_CLK_USIM1_WCLK] = GATE("usim1-wclk", PARENT_ID(ZX_CLK_USIM1_DIV), 0x54, 29, 0), + [ZX_CLK_USIM1_PCLK] = GATE("usim1-pclk", clk_main[0], 0x54, 28, 0), + + /* + * LTE: gate only as far as I can see. I looked for resets and did not find any. There may + * be mux/div, but without understanding the behavior of this hardware it is impossible to + * tell. They are sorted by physical MMIO address of the devices, which happens to be the + * inverse order of the bits. + * + * Like PMM in this register, either bit enables register access, whether they control pclk + * or wclk cannot be distinguished. + * + * The work parent of GSM, TD and W is without doubt osc26m. The mmio space has registers + * that count up at an integer fraction of 26000000. Gating PLLs does not affect them, + * including gating mpll. + * + * LPM_LTE has some interaction with LTE_MODEM_WCLK. If LTE_MODEM_WCLK is disabled, LPM_LTE + * stops counting, and just flips between two states. This makes it look like LPM_LTE in + * topcrm has a clock parent in matrixcrm, which wouldn't make much sense. I think this + * behavior is a result of the devices interacting rather than a clock parentage. + * + * As for what these devices do? I am not sure. They generate a lot of IRQs, but the IRQs + * are independent of actual radio activity. The ZSP firmware programs them + */ + [ZX_CLK_LPM_GSM_WCLK] = GATE("lpm-gsm-wclk", clk_main[0], 0x58, 10, 0), + [ZX_CLK_LPM_GSM_PCLK] = GATE("lpm-gsm-pclk", clk_main[0], 0x58, 11, 0), + [ZX_CLK_LPM_LTE_WCLK] = GATE("lpm-lte-wclk", clk_unknown, 0x58, 8, 0), + [ZX_CLK_LPM_LTE_PCLK] = GATE("lpm-lte-pclk", clk_main[0], 0x58, 9, 0), + [ZX_CLK_LPM_TD_WCLK] = GATE("lpm-td-wclk", clk_main[0], 0x58, 6, 0), + [ZX_CLK_LPM_TD_PCLK] = GATE("lpm-td-pclk", clk_main[0], 0x58, 7, 0), + [ZX_CLK_LPM_W_WCLK] = GATE("lpm-w-wclk", clk_main[0], 0x58, 4, 0), + [ZX_CLK_LPM_W_PCLK] = GATE("lpm-w-pclk", clk_main[0], 0x58, 5, 0), + + [ZX_CLK_OUT0_WCLK] = GATE("out0-wclk", PARENT_ID(ZX_CLK_OUT0_MUX), 0x34, 0, 0), + [ZX_CLK_OUT1_WCLK] = GATE("out1-wclk", PARENT_ID(ZX_CLK_OUT1_MUX), 0x90, 2, 0), + [ZX_CLK_OUT2_WCLK] = GATE("out2-wclk", PARENT_ID(ZX_CLK_OUT2_MUX), 0x94, 2, 0), + [ZX_CLK_OUT32K_WCLK] = GATE("out32k-wclk", PARENT_FW("osc32k"), 0x34, 1, 0), + [ZX_CLK_RMIIPHY_WCLK] = GATE("rmiiphy-wclk", PARENT_ID(ZX_CLK_RMIIPHY_MUX), + 0x11c, 2, 0), + + /* + * GSM clocks - they feed the 2G/3G radio components and SIM controller. + * + * The names are from the clock table in cpko.ko. The parents of gsm-104m and gsm-156m are + * experimentally verified. The gsm-48m parent is likely bit 2 in topcrm+0x140. I have not + * found an consumer that I understand well enough to say if it is running or not, so I have + * not been able to confirm this yet. + */ + [ZX_CLK_GSM_32K] = GATE("gsm-32k", PARENT_FW("osc32k"), 0x68, 0, 0), + [ZX_CLK_GSM_26M] = GATE("gsm-26m", PARENT_FW("osc26m"), 0x68, 1, 0), + [ZX_CLK_GSM_48M] = GATE("gsm-48m", clk_unknown, 0x68, 2, 0), + [ZX_CLK_GSM_104M] = GATE("gsm-104m", PARENT_ID(ZX_CLK_TOP_MPLL_D6), 0x68, 3, 0), + [ZX_CLK_GSM_156M] = GATE("gsm-156m", PARENT_ID(ZX_CLK_TOP_MPLL_D4), 0x68, 4, 0), + + /* Analog Baseband, probably. cpko.ko enables it for LTE, and LTE scans come back empty + * without it. The MMIO location of the device is unknown. It is likely connected only to + * ZSP and inaccessible to the main CPU. + */ + [ZX_CLK_ABB_WCLK] = GATE("abb-wclk", clk_unknown, 0x144, 1, 0), +}; + +static const unsigned int zx297520v3_top_exports[] = { + [ZX297520V3_M0_WCLK] = ZX_CLK_M0_MUX, + [ZX297520V3_SRAM1_PCLK] = ZX_CLK_SRAM1_PCLK, + [ZX297520V3_SRAM2_PCLK] = ZX_CLK_SRAM2_PCLK, + [ZX297520V3_UART0_WCLK] = ZX_CLK_UART0_WCLK, + [ZX297520V3_UART0_PCLK] = ZX_CLK_UART0_PCLK, + [ZX297520V3_I2C0_WCLK] = ZX_CLK_I2C0_WCLK, + [ZX297520V3_I2C0_PCLK] = ZX_CLK_I2C0_PCLK, + [ZX297520V3_RTC_WCLK] = ZX_CLK_RTC_WCLK, + [ZX297520V3_RTC_PCLK] = ZX_CLK_RTC_PCLK, + [ZX297520V3_LPM_GSM_WCLK] = ZX_CLK_LPM_GSM_WCLK, + [ZX297520V3_LPM_GSM_PCLK] = ZX_CLK_LPM_GSM_PCLK, + [ZX297520V3_LPM_LTE_WCLK] = ZX_CLK_LPM_LTE_WCLK, + [ZX297520V3_LPM_LTE_PCLK] = ZX_CLK_LPM_LTE_PCLK, + [ZX297520V3_LPM_TD_WCLK] = ZX_CLK_LPM_TD_WCLK, + [ZX297520V3_LPM_TD_PCLK] = ZX_CLK_LPM_TD_PCLK, + [ZX297520V3_LPM_W_WCLK] = ZX_CLK_LPM_W_WCLK, + [ZX297520V3_LPM_W_PCLK] = ZX_CLK_LPM_W_PCLK, + [ZX297520V3_TIMER_T08_WCLK] = ZX_CLK_TIMER_T08_WCLK, + [ZX297520V3_TIMER_T08_PCLK] = ZX_CLK_TIMER_T08_PCLK, + [ZX297520V3_TIMER_T09_WCLK] = ZX_CLK_TIMER_T09_WCLK, + [ZX297520V3_TIMER_T09_PCLK] = ZX_CLK_TIMER_T09_PCLK, + [ZX297520V3_MPLL] = ZX_CLK_TOMATRIX_MPLL, + [ZX297520V3_MPLL_D5] = ZX_CLK_TOMATRIX_MPLL_D5, + [ZX297520V3_DPLL] = ZX_CLK_TOMATRIX_DPLL, + [ZX297520V3_GPLL] = ZX_CLK_TOMATRIX_GPLL, + [ZX297520V3_GPLL_D2] = ZX_CLK_TOMATRIX_GPLL_D2, + [ZX297520V3_GATED_OSC26M] = ZX_CLK_TOMATRIX_OSC26M, + [ZX297520V3_PMM_WCLK] = ZX_CLK_PMM_WCLK, + [ZX297520V3_PMM_PCLK] = ZX_CLK_PMM_PCLK, + [ZX297520V3_OUT0_WCLK] = ZX_CLK_OUT0_WCLK, + [ZX297520V3_OUT1_WCLK] = ZX_CLK_OUT1_WCLK, + [ZX297520V3_OUT2_WCLK] = ZX_CLK_OUT2_WCLK, + [ZX297520V3_OUT32K_WCLK] = ZX_CLK_OUT32K_WCLK, + [ZX297520V3_RMIIPHY_WCLK] = ZX_CLK_RMIIPHY_WCLK, + [ZX297520V3_TIMER_T12_WCLK] = ZX_CLK_TIMER_T12_WCLK, + [ZX297520V3_TIMER_T12_PCLK] = ZX_CLK_TIMER_T12_PCLK, + [ZX297520V3_TIMER_T13_WCLK] = ZX_CLK_TIMER_T13_WCLK, + [ZX297520V3_TIMER_T13_PCLK] = ZX_CLK_TIMER_T13_PCLK, + [ZX297520V3_TIMER_T14_WCLK] = ZX_CLK_TIMER_T14_WCLK, + [ZX297520V3_TIMER_T14_PCLK] = ZX_CLK_TIMER_T14_PCLK, + [ZX297520V3_TIMER_T15_WCLK] = ZX_CLK_TIMER_T15_WCLK, + [ZX297520V3_TIMER_T15_PCLK] = ZX_CLK_TIMER_T15_PCLK, + [ZX297520V3_TIMER_T16_WCLK] = ZX_CLK_TIMER_T16_WCLK, + [ZX297520V3_TIMER_T16_PCLK] = ZX_CLK_TIMER_T16_PCLK, + [ZX297520V3_TIMER_T17_WCLK] = ZX_CLK_TIMER_T17_WCLK, + [ZX297520V3_TIMER_T17_PCLK] = ZX_CLK_TIMER_T17_PCLK, + [ZX297520V3_WDT_T18_WCLK] = ZX_CLK_WDT_T18_WCLK, + [ZX297520V3_WDT_T18_PCLK] = ZX_CLK_WDT_T18_PCLK, + [ZX297520V3_USIM1_WCLK] = ZX_CLK_USIM1_WCLK, + [ZX297520V3_USIM1_PCLK] = ZX_CLK_USIM1_PCLK, + [ZX297520V3_AHB_WCLK] = ZX_CLK_AHB_WCLK, + [ZX297520V3_AHB_PCLK] = ZX_CLK_AHB_PCLK, + [ZX297520V3_USB_WCLK] = ZX_CLK_USB_WCLK, + [ZX297520V3_USB_PCLK] = ZX_CLK_USB_PCLK, + [ZX297520V3_HSIC_WCLK] = ZX_CLK_HSIC_WCLK, + [ZX297520V3_HSIC_PCLK] = ZX_CLK_HSIC_PCLK, + [ZX297520V3_GSM_32K] = ZX_CLK_GSM_32K, + [ZX297520V3_GSM_26M] = ZX_CLK_GSM_26M, + [ZX297520V3_GSM_48M] = ZX_CLK_GSM_48M, + [ZX297520V3_GSM_104M] = ZX_CLK_GSM_104M, + [ZX297520V3_GSM_156M] = ZX_CLK_GSM_156M, + [ZX297520V3_ABB_WCLK] = ZX_CLK_ABB_WCLK, +}; + +static const struct zx_clk_data zx297520v3_topclk_data = { + .clocks = zx297520v3_top_clocks, + .num_clocks = ARRAY_SIZE(zx297520v3_top_clocks), + .exports = zx297520v3_top_exports, + .num_exports = ARRAY_SIZE(zx297520v3_top_exports), +}; + +enum matrix_clock_ids { + ZX_CLK_MATRIX_OSC26M_D4, + ZX_CLK_MATRIX_MPLL_D2_PREGATE, + ZX_CLK_MATRIX_MPLL_D4_PREGATE, + ZX_CLK_MATRIX_MPLL_D6_PREGATE, + ZX_CLK_MATRIX_MPLL_D8_PREGATE, + ZX_CLK_MATRIX_MPLL_D12_PREGATE, + ZX_CLK_MATRIX_MPLL_D16_PREGATE, + ZX_CLK_MATRIX_GPLL_D2_D2_PREGATE, + ZX_CLK_MATRIX_GPLL_D2_D4_PREGATE, + ZX_CLK_MATRIX_DPLL_D2_PREGATE, + ZX_CLK_MATRIX_DPLL_D4_PREGATE, + + ZX_CLK_MATRIX_MPLL_D16, + ZX_CLK_MATRIX_MPLL_D12, + ZX_CLK_MATRIX_MPLL_D8, + ZX_CLK_MATRIX_MPLL_D6, + ZX_CLK_MATRIX_MPLL_D4, + ZX_CLK_MATRIX_MPLL_D2, + ZX_CLK_MATRIX_DPLL_D4, + ZX_CLK_MATRIX_DPLL_D2, + ZX_CLK_MATRIX_GPLL_D2_D4, + ZX_CLK_MATRIX_GPLL_D2_D2, + + ZX_CLK_CPU_MUX, + ZX_CLK_ZSP_MUX, + ZX_CLK_DDR_CTRL_MUX, + ZX_CLK_SD0_MUX, + ZX_CLK_SD1_MUX, + ZX_CLK_NAND_MUX, + ZX_CLK_EDCP_MUX, + ZX_CLK_TDM_MUX, + ZX_CLK_AXI_MUX, + + ZX_CLK_SYS_TIMER_WCLK, + ZX_CLK_CPU_WCLK, + ZX_CLK_CPU_PCLK, + ZX_CLK_ZSP_WCLK, + ZX_CLK_ZSP_PCLK, + ZX_CLK_DDR_CTRL_PCLK, + ZX_CLK_DDR_CTRL_WCLK, + ZX_CLK_SD0_PCLK, + ZX_CLK_SD0_WCLK, + ZX_CLK_SD0_CDET, + ZX_CLK_SD1_PCLK, + ZX_CLK_SD1_WCLK, + ZX_CLK_SD1_CDET, + ZX_CLK_NAND_WCLK, + ZX_CLK_NAND_PCLK, + ZX_CLK_LTE_MODEM_WCLK, + ZX_CLK_LTE_MODEM_PCLK, + ZX_CLK_EDCP_PCLK, + ZX_CLK_EDCP_WCLK, + ZX_CLK_RFFE_WCLK, + ZX_CLK_SSC_WCLK, + ZX_CLK_SSC_PCLK, + ZX_CLK_PDCFG_WCLK, + ZX_CLK_PDCFG_PCLK, + ZX_CLK_MBOX_PCLK, + ZX_CLK_SRAM0_PCLK, + ZX_CLK_GSM_CFG_PCLK, + ZX_CLK_GMAC_WCLK, + ZX_CLK_GMAC_PCLK, + ZX_CLK_GMAC_AHB, + ZX_CLK_AXI_WCLK, + ZX_CLK_DMA_PCLK, + ZX_CLK_VOU_WCLK, + ZX_CLK_VOU_PCLK, + ZX_CLK_TOLSP_MPLL_D5_WCLK, + ZX_CLK_TOLSP_MPLL_D4_WCLK, + ZX_CLK_TOLSP_MPLL_D6_WCLK, + ZX_CLK_TOLSP_MPLL_D8_WCLK, + ZX_CLK_TOLSP_MPLL_D12_WCLK, + ZX_CLK_TOLSP_OSC26M_WCLK, + ZX_CLK_TOLSP_OSC32K_WCLK, + ZX_CLK_TOLSP_PCLK, + ZX_CLK_TOLSP_TDM_WCLK, + ZX_CLK_TOLSP_DPLL_D4_WCLK, +}; + +/* + * For devices which have a working driver the work clock can be figured out by gating off registers + * in topcrm+0x140. This is used for devices where I can't interpret the register contents yet. + */ +static const struct zx_parent_desc matrix_unk = PARENT_FW("wclk-osc26m"); + +static const struct zx_parent_desc cpu_sel[] = { + PARENT_FW("wclk-osc26m"), + PARENT_FW("mpll"), /* 624 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D2), /* 312 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D4), /* 156 MHz */ +}; + +/* + * Figuring these values out is a bit tricky. The best liveness check of the ZSP is reading its TCM + * at 0x81000000. If it is clocked up and out of reset reading it will succeed. Otherwise, reading + * will stall. Value 1 depends on topcrm+0x140, bit 13, but not any matrixcrm+0x118 gate, so it is + * likely dpll without a div. Mux value 2 depends on 0x118 bit 5, so mpll-d2. Mux value 3 depends on + * 0x118 bit 4, so mpll-d4. Mux value 0 in turn depends on topcrm+0x140, bit 24 (osc26m), so it + * follows the usual pattern that mux 0 is osc26m. + * + * If the firmware is running and fed with initialization data it will start writing status messages + * on UART1. An interruption of these messages or a failure to respond to rpmsg is not proof that + * the ZSP's clock has been disabled. The firmware's workings depend on regular timer and LTE device + * IRQs, so one of these devices might have been stopped instead. + */ +static const struct zx_parent_desc zsp_sel[] = { + PARENT_FW("wclk-osc26m"), + PARENT_FW("dpll"), /* 491.52 MHz, boot default */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D2), /* 312 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D4), /* 156 MHz */ +}; + +/* + * We can't realistically change DDR speed while running an OS out of DDR (it reads garbage for a + * short while on transition), but we need to know if we have to keep gpll alive. 32 MB devices use + * 200 MHz, while 64/128 MB ones use 156 MHz. + */ +static const struct zx_parent_desc ddr_ctrl_sel[] = { + PARENT_ID(ZX_CLK_MATRIX_MPLL_D4), /* 156 MHz */ + PARENT_FW("gpll"), /* 200 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D6), /* 104 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D8), /* 78 MHz */ +}; + +static const struct zx_parent_desc sd0_sel[] = { + PARENT_FW("wclk-osc26m"), + PARENT_ID(ZX_CLK_MATRIX_MPLL_D4), /* 156 MHz */ + PARENT_FW("gpll-d2"), /* 100 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D8), /* 78 MHz */ + PARENT_ID(ZX_CLK_MATRIX_GPLL_D2_D2), /* 50 MHz */ + PARENT_ID(ZX_CLK_MATRIX_GPLL_D2_D4), /* 25 MHz */ +}; + +static const struct zx_parent_desc sd1_sel[] = { + PARENT_FW("wclk-osc26m"), + PARENT_FW("gpll-d2"), /* 100 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D8), /* 78 MHz */ + PARENT_ID(ZX_CLK_MATRIX_GPLL_D2_D2), /* 50 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D16), /* 39 MHz */ + PARENT_ID(ZX_CLK_MATRIX_GPLL_D2_D4), /* 25 MHz */ +}; + +/* + * ZTE's kernel puts the high frequency first, but this is against the usual convention on this SoC. + * I don't have any device that has a raw NAND controller though. + */ +static const struct zx_parent_desc nand_sel[] = { + PARENT_FW("wclk-osc26m"), + PARENT_ID(ZX_CLK_MATRIX_MPLL_D4), /* 156 MHz */ +}; + +static const struct zx_parent_desc edcp_sel[] = { + PARENT_FW("wclk-osc26m"), + PARENT_ID(ZX_CLK_MATRIX_MPLL_D4), /* 156 MHz */ + PARENT_FW("mpll-d5"), /* 124.8 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D6), /* 104 MHz */ +}; + +/* + * The 122.88 MHz selection of value 1 is given in ZTE's kernel and matches up to observation: Print + * the TDM counter at regular intervals and look at its increase at values 0/1/2. It increases by + * about 310*26 for value 0, 310*122.88 for value 1 and 310*104 for value 2. + * + * Mux value 1 is gated off by matrix+0x118 bit 8. Values 2 and 3 are both gated off by 0x118 bit 3, + * suggesting that they select the same parent. + */ +static const struct zx_parent_desc tdm_sel[] = { + PARENT_FW("wclk-osc26m"), + PARENT_ID(ZX_CLK_MATRIX_DPLL_D4), /* 122.88 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D6), /* 104 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D6), +}; + +/* + * ZTE's firmware uses 0x128 as the PHY's vote and names 0x120 as "PS" and 0x124 as "AP" vote. + * However, their cpufreq driver ultimately uses the "PS" define and thus writes to 0x120, which can + * be observed in the running system. + */ +#define ZX297520V3_AXI_AP_VOTE 0x120 +static const struct zx_parent_desc axi_sel[] = { + PARENT_FW("wclk-osc26m"), + PARENT_ID(ZX_CLK_MATRIX_MPLL_D4), /* 156 MHz */ + PARENT_FW("mpll-d5"), /* 124.8 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D6), /* 104 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D8), /* 78 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D12), /* 52 MHz */ + PARENT_ID(ZX_CLK_MATRIX_MPLL_D16), /* 39 MHz */ + PARENT_ID(ZX_CLK_MATRIX_OSC26M_D4), /* 6.5 MHz */ +}; + +static const struct zx_clock zx297520v3_matrix_clocks[] = { + [ZX_CLK_MATRIX_OSC26M_D4] = FIXED_DIV("matrix-osc26m-d4", PARENT_FW("wclk-osc26m"), 4), + [ZX_CLK_MATRIX_MPLL_D2_PREGATE] = FIXED_DIV("matrix-mpll-d2-pregate", PARENT_FW("mpll"), 2), + [ZX_CLK_MATRIX_MPLL_D4_PREGATE] = FIXED_DIV("matrix-mpll-d4-pregate", PARENT_FW("mpll"), 4), + /* div 5: provided as a separate line from topcrm */ + [ZX_CLK_MATRIX_MPLL_D6_PREGATE] = FIXED_DIV("matrix-mpll-d6-pregate", PARENT_FW("mpll"), 6), + [ZX_CLK_MATRIX_MPLL_D8_PREGATE] = FIXED_DIV("matrix-mpll-d8-pregate", PARENT_FW("mpll"), 8), + [ZX_CLK_MATRIX_MPLL_D12_PREGATE] = FIXED_DIV("matrix-mpll-d12-pregate", PARENT_FW("mpll"), + 12), + [ZX_CLK_MATRIX_MPLL_D16_PREGATE] = FIXED_DIV("matrix-mpll-d16-pregate", PARENT_FW("mpll"), + 16), + + [ZX_CLK_MATRIX_GPLL_D2_D2_PREGATE] = FIXED_DIV("matrix-gpll-d2-d2-pregate", + PARENT_FW("gpll-d2"), 2), + [ZX_CLK_MATRIX_GPLL_D2_D4_PREGATE] = FIXED_DIV("matrix-gpll-d2-d4-pregate", + PARENT_FW("gpll-d2"), 4), + + [ZX_CLK_MATRIX_DPLL_D2_PREGATE] = FIXED_DIV("matrix-dpll-d2-pregate", PARENT_FW("dpll"), 2), + [ZX_CLK_MATRIX_DPLL_D4_PREGATE] = FIXED_DIV("matrix-dpll-d4-pregate", PARENT_FW("dpll"), 4), + + /* + * Matrix distribution gates: Every matrix-generated subdivision of the input PLLs + * has a gate in 0x118. The original inputs from topcrm (mpll 624, mpll 124.8, gpll 200, + * gpll 100, dpll 491.52) do not. + * + * Bit 8 is consumed by TDM and the frequency dpll/4 holds up to observation. Bit 9 is + * consumed by an unknown device and the frequency is guessed from the pattern that lower + * bits gate lower frequencies. + */ + [ZX_CLK_MATRIX_MPLL_D16] = GATE("matrix-mpll-d16", + PARENT_ID(ZX_CLK_MATRIX_MPLL_D16_PREGATE), 0x118, 0, + ZX297520V3_AXI_CANDIDATE), + [ZX_CLK_MATRIX_MPLL_D12] = GATE("matrix-mpll-d12", + PARENT_ID(ZX_CLK_MATRIX_MPLL_D12_PREGATE), 0x118, 1, + ZX297520V3_AXI_CANDIDATE), + [ZX_CLK_MATRIX_MPLL_D8] = GATE("matrix-mpll-d8", + PARENT_ID(ZX_CLK_MATRIX_MPLL_D8_PREGATE), 0x118, 2, + ZX297520V3_AXI_CANDIDATE), + [ZX_CLK_MATRIX_MPLL_D6] = GATE("matrix-mpll-d6", + PARENT_ID(ZX_CLK_MATRIX_MPLL_D6_PREGATE), 0x118, 3, + ZX297520V3_AXI_CANDIDATE), + [ZX_CLK_MATRIX_MPLL_D4] = GATE("matrix-mpll-d4", + PARENT_ID(ZX_CLK_MATRIX_MPLL_D4_PREGATE), 0x118, 4, + ZX297520V3_AXI_CANDIDATE), + [ZX_CLK_MATRIX_MPLL_D2] = GATE("matrix-mpll-d2", + PARENT_ID(ZX_CLK_MATRIX_MPLL_D2_PREGATE), 0x118, 5, 0), + + [ZX_CLK_MATRIX_DPLL_D4] = GATE("matrix-dpll-d4", + PARENT_ID(ZX_CLK_MATRIX_DPLL_D4_PREGATE), 0x118, 8, 0), + [ZX_CLK_MATRIX_DPLL_D2] = GATE("matrix-dpll-d2", + PARENT_ID(ZX_CLK_MATRIX_DPLL_D2_PREGATE), 0x118, 9, 0), + + [ZX_CLK_MATRIX_GPLL_D2_D4] = GATE("matrix-gpll-d2-d4", + PARENT_ID(ZX_CLK_MATRIX_GPLL_D2_D4_PREGATE), + 0x118, 12, 0), + [ZX_CLK_MATRIX_GPLL_D2_D2] = GATE("matrix-gpll-d2-d2", + PARENT_ID(ZX_CLK_MATRIX_GPLL_D2_D2_PREGATE), + 0x118, 13, 0), + + [ZX_CLK_CPU_MUX] = MUX("cpu-mux", cpu_sel, 0x20, 0, 2), + [ZX_CLK_ZSP_MUX] = MUX("zsp-mux", zsp_sel, 0x30, 0, 2), + [ZX_CLK_DDR_CTRL_MUX] = MUX("ddr-ctrl-mux", ddr_ctrl_sel, 0x50, 0, 2), + [ZX_CLK_SD0_MUX] = MUX("sd0-mux", sd0_sel, 0x50, 4, 3), + [ZX_CLK_SD1_MUX] = MUX("sd1-mux", sd1_sel, 0x50, 8, 3), + [ZX_CLK_NAND_MUX] = MUX("nand-mux", nand_sel, 0x50, 12, 2), + [ZX_CLK_EDCP_MUX] = MUX("edcp-mux", edcp_sel, 0x50, 16, 2), + [ZX_CLK_TDM_MUX] = MUX("tdm-mux", tdm_sel, 0x50, 24, 2), + [ZX_CLK_AXI_MUX] = MUX("axi-mux", axi_sel, ZX297520V3_AXI_AP_VOTE, 0, 3), + + /* + * This bit cuts off the clock signal to the ARM architected timer, which the kernel uses + * as its main timer. It isn't critical per se - there are plenty of proprietary timers + * available that could be used - but the arm arch timer binding does not accept a clock, so + * this CCF driver won't know if the timer is in use. + * + * This clock is fed by the osc26m gate in topcrm+0x140 - this critical clock here protects + * its parent. + * + * Registers 0x148, 0x14c, 0x150, 0x154 allow setting and clearing the timer counter. To + * set the timer, load a value into 0x148 (high 32 bits) and 0x14c (low 32 bits), then + * toggle 0x150 to 1. 0x150 will automatically reset to 0. 0x154 sets the timer to some + * "clear" value, but this value isn't 0. + */ + [ZX_CLK_SYS_TIMER_WCLK] = GATE("sys-timer-wclk", PARENT_FW("wclk-osc26m"), 0x144, 1, + CLK_IS_CRITICAL), + + /* + * Both 0x24 and 0x28 bits 1 and 2 stop the CPU. There is also a bit in topcrm+0x138, which + * ZTE's uboot calls "A53 reset", which also stops the CPU. I can't really tell the + * difference between matrix+0x28 and top+0x138. The clock (matrix+0x24) can be disabled + * and enabled from the Cortex M0 and it will nicely stop and restart the A53, retaining + * all state. + */ + [ZX_CLK_CPU_WCLK] = GATE("cpu-wclk", PARENT_ID(ZX_CLK_CPU_MUX), 0x24, 1, + CLK_IS_CRITICAL), + [ZX_CLK_CPU_PCLK] = GATE("cpu-pclk", clk_main[0], 0x24, 2, CLK_IS_CRITICAL), + + /* + * There are a lot more controls in matrix+0x100. 13-16 appear to be 4 different AXI + * channels for different priorities. Bit 19 appears to be the DDR PHY wclk. + * + * The important task is to keep gpll enabled if the bootloader selected a gpll-based rate + * for RAM. + */ + [ZX_CLK_DDR_CTRL_PCLK] = GATE("ddr-ctrl-pclk", clk_main[0], 0x100, 17, CLK_IS_CRITICAL), + [ZX_CLK_DDR_CTRL_WCLK] = GATE("ddr-ctrl-wclk", PARENT_ID(ZX_CLK_DDR_CTRL_MUX), 0x100, 18, + CLK_IS_CRITICAL), + + [ZX_CLK_ZSP_PCLK] = GATE("zsp-pclk", clk_main[0], 0x34, 0, 0), + [ZX_CLK_ZSP_WCLK] = GATE("zsp-wclk", PARENT_ID(ZX_CLK_ZSP_MUX), 0x34, 1, 0), + + /* Both SDIO controllers depend on the ahb-pclk for register access. */ + [ZX_CLK_SD0_PCLK] = GATE("sd0-pclk", PARENT_FW("ahb"), 0x54, 12, 0), + [ZX_CLK_SD0_WCLK] = GATE("sd0-wclk", PARENT_ID(ZX_CLK_SD0_MUX), 0x54, 13, 0), + [ZX_CLK_SD0_CDET] = GATE("sd0-cdet", PARENT_FW("osc32k"), 0x54, 14, 0), + [ZX_CLK_SD1_PCLK] = GATE("sd1-pclk", PARENT_FW("ahb"), 0x54, 4, 0), + [ZX_CLK_SD1_WCLK] = GATE("sd1-wclk", PARENT_ID(ZX_CLK_SD1_MUX), 0x54, 5, 0), + /* + * I don't know how the cdet clock works. Card detection in the way the dwc,mmc driver uses + * it appears broken no matter this clock's setting. + */ + [ZX_CLK_SD1_CDET] = GATE("sd1-cdet", PARENT_FW("osc32k"), 0x54, 6, 0), + + /* This is some "denali" NAND, not the qspi connected one */ + [ZX_CLK_NAND_WCLK] = GATE("nand-wclk", PARENT_ID(ZX_CLK_NAND_MUX), 0x54, 20, 0), + [ZX_CLK_NAND_PCLK] = GATE("nand-pclk", clk_main[0], 0x54, 21, 0), + + /* + * There is a set of gates for an unknown device at matrix+0x60. It is some LTE related + * device and the pclk gates off mmio areas 0xf8000000 and 0xfc000000. These areas are only + * accessible to M0 and ZSP, not the AP. + * + * If it is fed an incorrect clock, e.g. because dpll is not locked and outputs 26 MHz, it + * will spam IRQs at SPI 68. This is likely a distress notification that some + * internal PLL did not lock or similar. ZTE's kernel has two defines for SPI 68: + * "LTE_TPU_INT_PS_INT" and "VOU_OSD_INT". The latter is unlikely because VOU related clocks + * sit in matrix+0x168. + * + * The address space in 0xfc000000 appears to contain a number of different devices, so I + * have named the clock LTE_MODEM_{W/P}CLK. It is not known how this mmio area and clock + * relates to SPI 68 or the ABB clock in topcrm+0x144. Because it is not accessible to the + * AP at all, I don't think we need to care beyond turning on the clocks before booting the + * ZSP. + * + * Bit 9 in register 0x118 turns the IRQs off, so it is the immediate wclk parent. It isn't + * clear what divisor of dpll it is using though. Following the pattern that lower + * frequencies are gated by lower bits, it would indicate dpll/2 or dpll/3. + */ + [ZX_CLK_LTE_MODEM_WCLK] = GATE("lte-modem-wclk", PARENT_ID(ZX_CLK_MATRIX_DPLL_D2), + 0x60, 0, 0), + [ZX_CLK_LTE_MODEM_PCLK] = GATE("lte-modem-pclk", clk_main[0], + 0x60, 2, 0), + + [ZX_CLK_EDCP_PCLK] = GATE("edcp-pclk", clk_main[0], 0x64, 1, 0), + [ZX_CLK_EDCP_WCLK] = GATE("edcp-wclk", PARENT_ID(ZX_CLK_EDCP_MUX), 0x64, 2, 0), + + /* + * This seems to be another SPI-Like device. cpko.ko uses it to send calibration blobs to + * the LTE radio hardware. After initialization the ZSP firmware takes over control of this + * device. + * + * Testing reveals the parent as matrix's 104 MHz mpll fraction. + */ + [ZX_CLK_RFFE_WCLK] = GATE("rffe-wclk", PARENT_ID(ZX_CLK_MATRIX_MPLL_D6), 0x84, 0, 0), + [ZX_CLK_SSC_WCLK] = GATE("ssc-wclk", PARENT_ID(ZX_CLK_MATRIX_MPLL_D6), 0x84, 1, 0), + [ZX_CLK_SSC_PCLK] = GATE("ssc-pclk", clk_main[0], 0x84, 2, 0), + + /* + * PDCFG. Like PMM, either clock bit will allow the device to function. Probably there is + * no wclk line at all and the two bits are just an artifact of generally having two bits + * per device. + */ + [ZX_CLK_PDCFG_WCLK] = GATE("pdcfg-wclk", matrix_unk, 0x88, 0, CLK_IS_CRITICAL), + [ZX_CLK_PDCFG_PCLK] = GATE("pdcfg-pclk", clk_main[0], 0x88, 1, CLK_IS_CRITICAL), + [ZX_CLK_MBOX_PCLK] = GATE("mbox-pclk", clk_main[0], 0x88, 2, 0), + [ZX_CLK_SRAM0_PCLK] = GATE("sram0-pclk", clk_main[0], 0x88, 4, 0), + [ZX_CLK_GSM_CFG_PCLK] = GATE("gsm-cfg-pclk", clk_main[0], 0x88, 8, 0), + + /* + * ZTE's driver has a statement to the effect of *(top->base+0x11c) = 5, with a comment + * suggesting that this sets a 50 MHz clock. The clock code itself lists GMAC clocks in + * matrix+0x110 and lists the parents of these clocks as 50 MHz gpll output, but + * the downstream ZTE GMAC driver never enables the clocks. It turns out ZTE's code is + * highly misleading. + * + * The GMAC's work clock is definitely not any gpll output because it keeps working fine + * with gpll disabled. Gating off matrix-osc26m breaks GMAC, so it must be its parent. + * + * The GMAC Gates are left enabled by the boot loader and are required for the GMAC to work. + * + * As for the 50 MHz comment: See rmiiphy-wclk. + * + * The gmac-ahb clock is a child of topcrm's ahb-pclk and is required for DMA transfers in + * and out of GMAC. Without it, GMAC still receives ethernet frames, but can't drain them + * to memory and will eventually set the RX FIFO overflow flag. + */ + [ZX_CLK_GMAC_WCLK] = GATE("gmac-wclk", PARENT_FW("wclk-osc26m"), 0x110, 0, 0), + [ZX_CLK_GMAC_PCLK] = GATE("gmac-pclk", clk_main[0], 0x110, 1, 0), + [ZX_CLK_GMAC_AHB] = GATE("gmac-ahb", PARENT_FW("ahb"), 0x110, 2, 0), + + /* + * Is there an AXI bus gate? The symptom of cutting off the AXI mux selection in top+0x140 + * is that matrixcrm becomes unreadable from m0 and A53 hangs. Inside matrix itself only 3 + * bits fit that bill: 0x8c bits 5, 6, 7. It seems a bit self-defeating to have a clock + * gate that shuts off access to itself though. I expect a clock gate for the bus + * somewhere, and the mux exists, so exposing one AXI clock in the bindings is the correct + * thing to do. It also serves to tell the kernel to keep the mux's parent enabled. + * + * Register 0x8c has 12 settable bits (0xfff). Ultimately it doesn't matter much which + * do-not-remove bit we don't remove. Other bits in this register behave like gates (e.g + * bits 11:8 cut off USB temporarily), so I think we are looking in the right place. + * + * If an explanation for the remaining bits surfaces and they are further gates and/or + * resets, add them to the bindings. + */ + [ZX_CLK_AXI_WCLK] = GATE("axi-wclk", PARENT_ID(ZX_CLK_AXI_MUX), 0x8c, 5, + CLK_IS_CRITICAL), + + [ZX_CLK_DMA_PCLK] = GATE("dma-pclk", clk_main[0], 0x94, 3, 0), + + /* + * There are a lot more VOU related controls in these registers, but turning off the main + * clock seems to shut off the entire VOU MMIO range. + */ + [ZX_CLK_VOU_WCLK] = GATE("vou-wclk", matrix_unk, 0x168, 0, 0), + [ZX_CLK_VOU_PCLK] = GATE("vou-pclk", clk_main[0], 0x168, 1, 0), + + /* + * LSP uplink clocks. The pclk is fairly obvious (disabling it shuts off the entire LSP + * register area). The wclk speeds were deduced by setting timers and qspi muxes to a + * specific speed and seeing which bit in matrix+0x7c needs to be enabled for the device + * to work. + * + * Due to the timers I am certain about the 26 MHz and 32 kHz clocks. I cannot directly + * observe the qspi mux frequency, so the clock rates depend on ZTE's qspi mux selection + * being correct. + * + * Two additional bits are specific to sound components - the mux for the LSP's TDM IP is + * in matrixcrm and gets passed down. I2S has a mux in LSP, which can select the dpll-d4 + * clock. + */ + [ZX_CLK_TOLSP_MPLL_D5_WCLK] = GATE("lsp-mpll-d5", PARENT_FW("mpll-d5"), 0x7c, 0, 0), + [ZX_CLK_TOLSP_MPLL_D4_WCLK] = GATE("lsp-mpll-d4", PARENT_ID(ZX_CLK_MATRIX_MPLL_D4), + 0x7c, 1, 0), + [ZX_CLK_TOLSP_MPLL_D6_WCLK] = GATE("lsp-mpll-d6", PARENT_ID(ZX_CLK_MATRIX_MPLL_D6), + 0x7c, 2, 0), + [ZX_CLK_TOLSP_MPLL_D8_WCLK] = GATE("lsp-mpll-d8", PARENT_ID(ZX_CLK_MATRIX_MPLL_D8), + 0x7c, 3, 0), + [ZX_CLK_TOLSP_MPLL_D12_WCLK] = GATE("lsp-mpll-d12", PARENT_ID(ZX_CLK_MATRIX_MPLL_D12), + 0x7c, 4, 0), + [ZX_CLK_TOLSP_OSC26M_WCLK] = GATE("lsp-osc26m", PARENT_FW("wclk-osc26m"), 0x7c, 5, 0), + [ZX_CLK_TOLSP_OSC32K_WCLK] = GATE("lsp-osc32k", PARENT_FW("osc32k"), 0x7c, 6, 0), + [ZX_CLK_TOLSP_PCLK] = GATE("lsp-pclk", clk_main[0], 0x7c, 7, 0), + [ZX_CLK_TOLSP_TDM_WCLK] = GATE("lsp-tdm-wclk", PARENT_ID(ZX_CLK_TDM_MUX), 0x7c, 8, 0), + [ZX_CLK_TOLSP_DPLL_D4_WCLK] = GATE("lsp-dpll-d4", PARENT_ID(ZX_CLK_MATRIX_DPLL_D4), + 0x7c, 9, 0), +}; + +static int zx297520v3_matrix_init(struct regmap *map) +{ + u32 axi_val; + int res; + + /* Read the global AXI speed selection, insert it into our ballot and enable voting */ + res = regmap_read(map, 0x0, &axi_val); + if (res) + return res; + + axi_val &= 0x7; + res = regmap_write(map, ZX297520V3_AXI_AP_VOTE, axi_val); + if (res) + return res; + + return regmap_write(map, 0x12c, 1); +} + +static const unsigned int zx297520v3_matrix_exports[] = { + [ZX297520V3_SYS_TIMER_WCLK] = ZX_CLK_SYS_TIMER_WCLK, + [ZX297520V3_CPU_WCLK] = ZX_CLK_CPU_WCLK, + [ZX297520V3_CPU_PCLK] = ZX_CLK_CPU_PCLK, + [ZX297520V3_ZSP_WCLK] = ZX_CLK_ZSP_WCLK, + [ZX297520V3_ZSP_PCLK] = ZX_CLK_ZSP_PCLK, + [ZX297520V3_DDR_CTRL_PCLK] = ZX_CLK_DDR_CTRL_PCLK, + [ZX297520V3_DDR_CTRL_WCLK] = ZX_CLK_DDR_CTRL_WCLK, + [ZX297520V3_EDCP_WCLK] = ZX_CLK_EDCP_WCLK, + [ZX297520V3_EDCP_PCLK] = ZX_CLK_EDCP_PCLK, + [ZX297520V3_SD0_WCLK] = ZX_CLK_SD0_WCLK, + [ZX297520V3_SD0_PCLK] = ZX_CLK_SD0_PCLK, + [ZX297520V3_SD0_CDET] = ZX_CLK_SD0_CDET, + [ZX297520V3_SD1_WCLK] = ZX_CLK_SD1_WCLK, + [ZX297520V3_SD1_PCLK] = ZX_CLK_SD1_PCLK, + [ZX297520V3_SD1_CDET] = ZX_CLK_SD1_CDET, + [ZX297520V3_NAND_WCLK] = ZX_CLK_NAND_WCLK, + [ZX297520V3_NAND_PCLK] = ZX_CLK_NAND_PCLK, + [ZX297520V3_DMA_PCLK] = ZX_CLK_DMA_PCLK, + [ZX297520V3_MBOX_PCLK] = ZX_CLK_MBOX_PCLK, + [ZX297520V3_PDCFG_WCLK] = ZX_CLK_PDCFG_WCLK, + [ZX297520V3_PDCFG_PCLK] = ZX_CLK_PDCFG_PCLK, + [ZX297520V3_RFFE_WCLK] = ZX_CLK_RFFE_WCLK, + [ZX297520V3_SSC_WCLK] = ZX_CLK_SSC_WCLK, + [ZX297520V3_SSC_PCLK] = ZX_CLK_SSC_PCLK, + [ZX297520V3_AXI_WCLK] = ZX_CLK_AXI_WCLK, + [ZX297520V3_GMAC_WCLK] = ZX_CLK_GMAC_WCLK, + [ZX297520V3_GMAC_PCLK] = ZX_CLK_GMAC_PCLK, + [ZX297520V3_GMAC_AHB] = ZX_CLK_GMAC_AHB, + [ZX297520V3_VOU_WCLK] = ZX_CLK_VOU_WCLK, + [ZX297520V3_VOU_PCLK] = ZX_CLK_VOU_PCLK, + [ZX297520V3_LSP_MPLL_D5_WCLK] = ZX_CLK_TOLSP_MPLL_D5_WCLK, + [ZX297520V3_LSP_MPLL_D4_WCLK] = ZX_CLK_TOLSP_MPLL_D4_WCLK, + [ZX297520V3_LSP_MPLL_D6_WCLK] = ZX_CLK_TOLSP_MPLL_D6_WCLK, + [ZX297520V3_LSP_MPLL_D8_WCLK] = ZX_CLK_TOLSP_MPLL_D8_WCLK, + [ZX297520V3_LSP_MPLL_D12_WCLK] = ZX_CLK_TOLSP_MPLL_D12_WCLK, + [ZX297520V3_LSP_OSC26M_WCLK] = ZX_CLK_TOLSP_OSC26M_WCLK, + [ZX297520V3_LSP_OSC32K_WCLK] = ZX_CLK_TOLSP_OSC32K_WCLK, + [ZX297520V3_LSP_PCLK] = ZX_CLK_TOLSP_PCLK, + [ZX297520V3_LSP_TDM_WCLK] = ZX_CLK_TOLSP_TDM_WCLK, + [ZX297520V3_LSP_DPLL_D4_WCLK] = ZX_CLK_TOLSP_DPLL_D4_WCLK, + [ZX297520V3_SRAM0_PCLK] = ZX_CLK_SRAM0_PCLK, + [ZX297520V3_GSM_CFG_PCLK] = ZX_CLK_GSM_CFG_PCLK, + [ZX297520V3_LTE_MODEM_WCLK] = ZX_CLK_LTE_MODEM_WCLK, + [ZX297520V3_LTE_MODEM_PCLK] = ZX_CLK_LTE_MODEM_PCLK, +}; + +static const struct zx_clk_data zx297520v3_matrixclk_data = { + .init = zx297520v3_matrix_init, + .clocks = zx297520v3_matrix_clocks, + .num_clocks = ARRAY_SIZE(zx297520v3_matrix_clocks), + .exports = zx297520v3_matrix_exports, + .num_exports = ARRAY_SIZE(zx297520v3_matrix_exports), +}; + +/* + * LSP clock entries have a common pattern: Bit 0 for pclk, Bit 1 for wclk. Bit 4 (and sometimes + * more) for wclk mux. + * + * Bit 8 and 9 are resets handled by the reset-zte-zx297520v3 driver. + * + * Bits 15:12 can be a divisor, but not all clocks have it. Some clocks have a divisor in 19:16. + * + * The ID given in this table is the first register in the device's MMIO space. ZTE's drivers + * usually call this a version register, but it looks more like a device identifier. + * + * It looks like the registers map to devices like this: + * + * CRM Reg function div dev offset(lsp + xxxx) ID + * 0x0: Read-only, probably device identifier 0x00752100 + * 0x4: timer_l1 Y 0x1000 0x02020000 + * 0x8: watchdog_l2 Y 0x2000 0x02020000 + * 0xc: watchdog_l3 Y 0x3000 0x02020000 + * 0x10: pwm N 0x4000 0x01020000 + * 0x14: i2s0 Yh 0x5000 0x01030000 + * 0x18: always 0 - - - + * 0x1c: i2s1 Yh 0x6000 0x01030000 + * 0x20: always 0 - - - + * 0x24: qspi N 0x7000 0x01040000 + * 0x28: uart1 N 0x8000 0x01060000 + * 0x2c: i2c1 N 0x9000 0x01020000 + * 0x30: spi0 Y 0xa000 0x01040000 + * 0x34: timer_lb Y 0xb000 0x02020000 + * 0x38: timer_lc Y 0xc000 0x02020000 + * 0x3c: uart2 N 0xd000 0x01060000 + * 0x40: watchdog_le Y 0xe000 0x02020000 + * 0x44: timer_lf Y 0xf000 0x02020000 + * 0x48: spi1 Y 0x10000 0x01040000 + * 0x4c: timer_l11 Y 0x11000 0x02020000 + * 0x50: tdm Yh 0x12000 0x01040000 + * + * Registers 0x58, 0x5c, 0x60, 0x64, 0x68 seem to contain more controls for i2s and tdm. + * + * The device at offset 0x4000 (clk reg 0x10) is a PWM device. The ID matches that of i2c, it has a + * larger register set. ZTE's kernel does not operate it at all. The old upstream pwm-zx.c driver + * provided enough instructions to blink the Wifi led and isolate the parent. + */ + +enum lsp_clock_ids { + ZX_CLK_TIMER_L1_MUX, + ZX_CLK_WDT_L2_MUX, + ZX_CLK_WDT_L3_MUX, + ZX_CLK_I2S0_MUX, + ZX_CLK_I2S1_MUX, + ZX_CLK_QSPI_MUX, + ZX_CLK_UART1_MUX, + ZX_CLK_I2C1_MUX, + ZX_CLK_SPI0_MUX, + ZX_CLK_TIMER_LB_MUX, + ZX_CLK_TIMER_LC_MUX, + ZX_CLK_UART2_MUX, + ZX_CLK_WDT_LE_MUX, + ZX_CLK_TIMER_LF_MUX, + ZX_CLK_SPI1_MUX, + ZX_CLK_TIMER_L11_MUX, + + ZX_CLK_TIMER_L1_DIV, + ZX_CLK_WDT_L2_DIV, + ZX_CLK_WDT_L3_DIV, + ZX_CLK_I2S0_DIV, + ZX_CLK_I2S1_DIV, + ZX_CLK_SPI0_DIV, + ZX_CLK_TIMER_LB_DIV, + ZX_CLK_TIMER_LC_DIV, + ZX_CLK_WDT_LE_DIV, + ZX_CLK_TIMER_LF_DIV, + ZX_CLK_SPI1_DIV, + ZX_CLK_TIMER_L11_DIV, + ZX_CLK_TDM_DIV, + + ZX_CLK_TIMER_L1_PCLK, + ZX_CLK_TIMER_L1_WCLK, + ZX_CLK_WDT_L2_PCLK, + ZX_CLK_WDT_L2_WCLK, + ZX_CLK_WDT_L3_PCLK, + ZX_CLK_WDT_L3_WCLK, + ZX_CLK_PWM_PCLK, + ZX_CLK_PWM_WCLK, + ZX_CLK_I2S0_PCLK, + ZX_CLK_I2S0_WCLK, + ZX_CLK_I2S1_PCLK, + ZX_CLK_I2S1_WCLK, + ZX_CLK_QSPI_PCLK, + ZX_CLK_QSPI_WCLK, + ZX_CLK_UART1_PCLK, + ZX_CLK_UART1_WCLK, + ZX_CLK_I2C1_PCLK, + ZX_CLK_I2C1_WCLK, + ZX_CLK_SPI0_PCLK, + ZX_CLK_SPI0_WCLK, + ZX_CLK_TIMER_LB_PCLK, + ZX_CLK_TIMER_LB_WCLK, + ZX_CLK_TIMER_LC_PCLK, + ZX_CLK_TIMER_LC_WCLK, + ZX_CLK_UART2_PCLK, + ZX_CLK_UART2_WCLK, + ZX_CLK_WDT_LE_PCLK, + ZX_CLK_WDT_LE_WCLK, + ZX_CLK_TIMER_LF_PCLK, + ZX_CLK_TIMER_LF_WCLK, + ZX_CLK_SPI1_PCLK, + ZX_CLK_SPI1_WCLK, + ZX_CLK_TIMER_L11_PCLK, + ZX_CLK_TIMER_L11_WCLK, + ZX_CLK_TDM_PCLK, + ZX_CLK_TDM_WCLK, +}; + +static const struct zx_parent_desc timer_lsp_sel[] = { + PARENT_FW("osc32k"), + PARENT_FW("osc26m"), +}; + +static const struct zx_parent_desc uart_lsp_sel[] = { + PARENT_FW("osc26m"), + PARENT_FW("mpll-d6"), +}; + +static const struct zx_parent_desc i2s_lsp_sel[] = { + PARENT_FW("osc26m"), + PARENT_FW("dpll-d4"), + PARENT_FW("mpll-d6"), + /* Unknown */ +}; + +static const struct zx_parent_desc spi_lsp_sel[] = { + PARENT_FW("osc26m"), + PARENT_FW("mpll-d4"), + PARENT_FW("mpll-d6"), + /* Unknown */ +}; + +static const struct zx_parent_desc qspi_lsp_sel[] = { + PARENT_FW("osc26m"), + PARENT_FW("mpll-d4"), + PARENT_FW("mpll-d5"), + PARENT_FW("mpll-d6"), + PARENT_FW("mpll-d8"), + PARENT_FW("mpll-d12"), + PARENT_FW("osc26m"), + PARENT_FW("osc26m"), +}; + +static const struct zx_clock zx297520v3_lsp_clocks[] = { + [ZX_CLK_TIMER_L1_MUX] = MUX("timer-l1-mux", timer_lsp_sel, 0x04, 4, 1), + [ZX_CLK_WDT_L2_MUX] = MUX("wdt-l2-mux", timer_lsp_sel, 0x08, 4, 1), + [ZX_CLK_WDT_L3_MUX] = MUX("wdt-l3-mux", timer_lsp_sel, 0x0c, 4, 1), + /* PWM: No mux bit can be set */ + [ZX_CLK_I2S0_MUX] = MUX("i2s0-mux", i2s_lsp_sel, 0x14, 4, 2), + /* 0x18: Always 0 */ + [ZX_CLK_I2S1_MUX] = MUX("i2s1-mux", i2s_lsp_sel, 0x1c, 4, 2), + /* 0x20: Always 0 */ + [ZX_CLK_QSPI_MUX] = MUX("qspi-mux", qspi_lsp_sel, 0x24, 4, 3), + [ZX_CLK_UART1_MUX] = MUX("uart1-mux", uart_lsp_sel, 0x28, 4, 1), + [ZX_CLK_I2C1_MUX] = MUX("i2c1-mux", uart_lsp_sel, 0x2c, 4, 1), + [ZX_CLK_SPI0_MUX] = MUX("spi0-mux", spi_lsp_sel, 0x30, 4, 2), + [ZX_CLK_TIMER_LB_MUX] = MUX("timer-lb-mux", timer_lsp_sel, 0x34, 4, 1), + [ZX_CLK_TIMER_LC_MUX] = MUX("timer-lc-mux", timer_lsp_sel, 0x38, 4, 1), + [ZX_CLK_UART2_MUX] = MUX("uart2-mux", uart_lsp_sel, 0x3c, 4, 1), + [ZX_CLK_WDT_LE_MUX] = MUX("wdt-le-mux", timer_lsp_sel, 0x40, 4, 1), + [ZX_CLK_TIMER_LF_MUX] = MUX("timer-lf-mux", timer_lsp_sel, 0x44, 4, 1), + [ZX_CLK_SPI1_MUX] = MUX("spi1-mux", spi_lsp_sel, 0x48, 4, 2), + [ZX_CLK_TIMER_L11_MUX] = MUX("timer-l11-mux", timer_lsp_sel, 0x4c, 4, 1), + /* TDM: No mux in LSP. Instead, it is in matrix with a separate clk line to LSP */ + + [ZX_CLK_TIMER_L1_DIV] = DIV("timer-l1-div", PARENT_ID(ZX_CLK_TIMER_L1_MUX), + 0x04, 12, 4), + [ZX_CLK_WDT_L2_DIV] = DIV("wdt-l2-div", PARENT_ID(ZX_CLK_WDT_L2_MUX), 0x08, 12, 4), + [ZX_CLK_WDT_L3_DIV] = DIV("wdt-l3-div", PARENT_ID(ZX_CLK_WDT_L3_MUX), 0x0c, 12, 4), + /* PWM: No div */ + [ZX_CLK_I2S0_DIV] = DIV("i2s0-div", PARENT_ID(ZX_CLK_I2S0_MUX), 0x14, 16, 4), + /* 0x18: Always 0 */ + [ZX_CLK_I2S1_DIV] = DIV("i2s1-div", PARENT_ID(ZX_CLK_I2S1_MUX), 0x1c, 16, 4), + /* 0x20: Always 0 */ + /* qspi, uart1, i2c1: No div */ + [ZX_CLK_SPI0_DIV] = DIV("spi0-div", PARENT_ID(ZX_CLK_SPI0_MUX), 0x30, 12, 4), + [ZX_CLK_TIMER_LB_DIV] = DIV("timer-lb-div", PARENT_ID(ZX_CLK_TIMER_LB_MUX), + 0x34, 12, 4), + [ZX_CLK_TIMER_LC_DIV] = DIV("timer-lc-div", PARENT_ID(ZX_CLK_TIMER_LC_MUX), + 0x38, 12, 4), + /* uart2: No div */ + [ZX_CLK_WDT_LE_DIV] = DIV("wdt-le-div", PARENT_ID(ZX_CLK_WDT_LE_MUX), 0x40, 12, 4), + [ZX_CLK_TIMER_LF_DIV] = DIV("timer-lf-div", PARENT_ID(ZX_CLK_TIMER_LF_MUX), + 0x44, 12, 4), + [ZX_CLK_SPI1_DIV] = DIV("spi1-div", PARENT_ID(ZX_CLK_SPI1_MUX), 0x48, 12, 4), + [ZX_CLK_TIMER_L11_DIV] = DIV("timer-l11-div", PARENT_ID(ZX_CLK_TIMER_L11_MUX), + 0x4c, 12, 4), + [ZX_CLK_TDM_DIV] = DIV("tdm-div", PARENT_FW("tdm-wclk"), 0x50, 16, 4), + + [ZX_CLK_TIMER_L1_PCLK] = GATE("timer-l1-pclk", PARENT_FW("pclk"), 0x04, 0, 0), + [ZX_CLK_TIMER_L1_WCLK] = GATE("timer-l1-wclk", PARENT_ID(ZX_CLK_TIMER_L1_DIV), 0x04, 1, 0), + [ZX_CLK_WDT_L2_PCLK] = GATE("wdt-l2-pclk", PARENT_FW("pclk"), 0x08, 0, 0), + [ZX_CLK_WDT_L2_WCLK] = GATE("wdt-l2-wclk", PARENT_ID(ZX_CLK_WDT_L2_DIV), 0x08, 1, 0), + [ZX_CLK_WDT_L3_PCLK] = GATE("wdt-l3-pclk", PARENT_FW("pclk"), 0x0c, 0, 0), + [ZX_CLK_WDT_L3_WCLK] = GATE("wdt-l3-wclk", PARENT_ID(ZX_CLK_WDT_L3_DIV), 0x0c, 1, 0), + [ZX_CLK_PWM_PCLK] = GATE("pwm-pclk", PARENT_FW("pclk"), 0x10, 0, 0), + [ZX_CLK_PWM_WCLK] = GATE("pwm-wclk", PARENT_FW("mpll-d6"), 0x10, 1, 0), + [ZX_CLK_I2S0_PCLK] = GATE("i2s0-pclk", PARENT_FW("pclk"), 0x14, 0, 0), + [ZX_CLK_I2S0_WCLK] = GATE("i2s0-wclk", PARENT_ID(ZX_CLK_I2S0_DIV), 0x14, 1, 0), + /* 0x18: Always 0 */ + [ZX_CLK_I2S1_PCLK] = GATE("i2s1-pclk", PARENT_FW("pclk"), 0x1c, 0, 0), + [ZX_CLK_I2S1_WCLK] = GATE("i2s1-wclk", PARENT_ID(ZX_CLK_I2S1_DIV), 0x1c, 1, 0), + /* 0x20: Always 0 */ + [ZX_CLK_QSPI_PCLK] = GATE("qspi-pclk", PARENT_FW("pclk"), 0x24, 0, 0), + [ZX_CLK_QSPI_WCLK] = GATE("qspi-wclk", PARENT_ID(ZX_CLK_QSPI_MUX), 0x24, 1, 0), + [ZX_CLK_UART1_PCLK] = GATE("uart1-pclk", PARENT_FW("pclk"), 0x28, 0, 0), + [ZX_CLK_UART1_WCLK] = GATE("uart1-wclk", PARENT_ID(ZX_CLK_UART1_MUX), 0x28, 1, 0), + [ZX_CLK_I2C1_PCLK] = GATE("i2c1-pclk", PARENT_FW("pclk"), 0x2c, 0, 0), + [ZX_CLK_I2C1_WCLK] = GATE("i2c1-wclk", PARENT_ID(ZX_CLK_I2C1_MUX), 0x2c, 1, 0), + [ZX_CLK_SPI0_PCLK] = GATE("spi0-pclk", PARENT_FW("pclk"), 0x30, 0, 0), + [ZX_CLK_SPI0_WCLK] = GATE("spi0-wclk", PARENT_ID(ZX_CLK_SPI0_DIV), 0x30, 1, 0), + [ZX_CLK_TIMER_LB_PCLK] = GATE("timer-lb-pclk", PARENT_FW("pclk"), 0x34, 0, 0), + [ZX_CLK_TIMER_LB_WCLK] = GATE("timer-lb-wclk", PARENT_ID(ZX_CLK_TIMER_LB_DIV), 0x34, 1, 0), + [ZX_CLK_TIMER_LC_PCLK] = GATE("timer-lc-pclk", PARENT_FW("pclk"), 0x38, 0, 0), + [ZX_CLK_TIMER_LC_WCLK] = GATE("timer-lc-wclk", PARENT_ID(ZX_CLK_TIMER_LC_DIV), 0x38, 1, 0), + [ZX_CLK_UART2_PCLK] = GATE("uart2-pclk", PARENT_FW("pclk"), 0x3c, 0, 0), + [ZX_CLK_UART2_WCLK] = GATE("uart2-wclk", PARENT_ID(ZX_CLK_UART2_MUX), 0x3c, 1, 0), + [ZX_CLK_WDT_LE_PCLK] = GATE("wdt-le-pclk", PARENT_FW("pclk"), 0x40, 0, 0), + [ZX_CLK_WDT_LE_WCLK] = GATE("wdt-le-wclk", PARENT_ID(ZX_CLK_WDT_LE_DIV), 0x40, 1, 0), + [ZX_CLK_TIMER_LF_PCLK] = GATE("timer-lf-pclk", PARENT_FW("pclk"), 0x44, 0, 0), + [ZX_CLK_TIMER_LF_WCLK] = GATE("timer-lf-wclk", PARENT_ID(ZX_CLK_TIMER_LF_DIV), 0x44, 1, 0), + [ZX_CLK_SPI1_PCLK] = GATE("spi1-pclk", PARENT_FW("pclk"), 0x48, 0, 0), + [ZX_CLK_SPI1_WCLK] = GATE("spi1-wclk", PARENT_ID(ZX_CLK_SPI1_DIV), 0x48, 1, 0), + [ZX_CLK_TIMER_L11_PCLK] = GATE("timer-l11-pclk", PARENT_FW("pclk"), 0x4c, 0, 0), + [ZX_CLK_TIMER_L11_WCLK] = GATE("timer-l11-wclk", PARENT_ID(ZX_CLK_TIMER_L11_DIV), + 0x4c, 1, 0), + [ZX_CLK_TDM_PCLK] = GATE("tdm-pclk", PARENT_FW("pclk"), 0x50, 0, 0), + [ZX_CLK_TDM_WCLK] = GATE("tdm-wclk", PARENT_ID(ZX_CLK_TDM_DIV), 0x50, 1, 0), +}; + +static const unsigned int zx297520v3_lsp_exports[] = { + [ZX297520V3_TIMER_L1_WCLK] = ZX_CLK_TIMER_L1_WCLK, + [ZX297520V3_TIMER_L1_PCLK] = ZX_CLK_TIMER_L1_PCLK, + [ZX297520V3_WDT_L2_WCLK] = ZX_CLK_WDT_L2_WCLK, + [ZX297520V3_WDT_L2_PCLK] = ZX_CLK_WDT_L2_PCLK, + [ZX297520V3_WDT_L3_WCLK] = ZX_CLK_WDT_L3_WCLK, + [ZX297520V3_WDT_L3_PCLK] = ZX_CLK_WDT_L3_PCLK, + [ZX297520V3_PWM_WCLK] = ZX_CLK_PWM_WCLK, + [ZX297520V3_PWM_PCLK] = ZX_CLK_PWM_PCLK, + [ZX297520V3_I2S0_WCLK] = ZX_CLK_I2S0_WCLK, + [ZX297520V3_I2S0_PCLK] = ZX_CLK_I2S0_PCLK, + [ZX297520V3_I2S1_WCLK] = ZX_CLK_I2S1_WCLK, + [ZX297520V3_I2S1_PCLK] = ZX_CLK_I2S1_PCLK, + [ZX297520V3_QSPI_WCLK] = ZX_CLK_QSPI_WCLK, + [ZX297520V3_QSPI_PCLK] = ZX_CLK_QSPI_PCLK, + [ZX297520V3_UART1_WCLK] = ZX_CLK_UART1_WCLK, + [ZX297520V3_UART1_PCLK] = ZX_CLK_UART1_PCLK, + [ZX297520V3_I2C1_WCLK] = ZX_CLK_I2C1_WCLK, + [ZX297520V3_I2C1_PCLK] = ZX_CLK_I2C1_PCLK, + [ZX297520V3_SPI0_WCLK] = ZX_CLK_SPI0_WCLK, + [ZX297520V3_SPI0_PCLK] = ZX_CLK_SPI0_PCLK, + [ZX297520V3_TIMER_LB_WCLK] = ZX_CLK_TIMER_LB_WCLK, + [ZX297520V3_TIMER_LB_PCLK] = ZX_CLK_TIMER_LB_PCLK, + [ZX297520V3_TIMER_LC_WCLK] = ZX_CLK_TIMER_LC_WCLK, + [ZX297520V3_TIMER_LC_PCLK] = ZX_CLK_TIMER_LC_PCLK, + [ZX297520V3_UART2_WCLK] = ZX_CLK_UART2_WCLK, + [ZX297520V3_UART2_PCLK] = ZX_CLK_UART2_PCLK, + [ZX297520V3_WDT_LE_WCLK] = ZX_CLK_WDT_LE_WCLK, + [ZX297520V3_WDT_LE_PCLK] = ZX_CLK_WDT_LE_PCLK, + [ZX297520V3_TIMER_LF_WCLK] = ZX_CLK_TIMER_LF_WCLK, + [ZX297520V3_TIMER_LF_PCLK] = ZX_CLK_TIMER_LF_PCLK, + [ZX297520V3_SPI1_WCLK] = ZX_CLK_SPI1_WCLK, + [ZX297520V3_SPI1_PCLK] = ZX_CLK_SPI1_PCLK, + [ZX297520V3_TIMER_L11_WCLK] = ZX_CLK_TIMER_L11_WCLK, + [ZX297520V3_TIMER_L11_PCLK] = ZX_CLK_TIMER_L11_PCLK, + [ZX297520V3_TDM_WCLK] = ZX_CLK_TDM_WCLK, + [ZX297520V3_TDM_PCLK] = ZX_CLK_TDM_PCLK, +}; + +static const struct zx_clk_data zx297520v3_lspclk_data = { + .clocks = zx297520v3_lsp_clocks, + .num_clocks = ARRAY_SIZE(zx297520v3_lsp_clocks), + .exports = zx297520v3_lsp_exports, + .num_exports = ARRAY_SIZE(zx297520v3_lsp_exports), +}; + +static int clk_zx297520v3_probe(struct platform_device *pdev) +{ + const struct platform_device_id *id = platform_get_device_id(pdev); + + if (!id) + return -ENODEV; + + return zx_clk_common_probe(&pdev->dev, pdev->dev.parent->of_node, + (const struct zx_clk_data *)id->driver_data); +} + +static const struct platform_device_id clk_zx297520v3_ids[] = { + { + .name = "zx297520v3-topclk", + .driver_data = (kernel_ulong_t)&zx297520v3_topclk_data, + }, + { + .name = "zx297520v3-matrixclk", + .driver_data = (kernel_ulong_t)&zx297520v3_matrixclk_data, + }, + { + .name = "zx297520v3-lspclk", + .driver_data = (kernel_ulong_t)&zx297520v3_lspclk_data, + }, + { } +}; +MODULE_DEVICE_TABLE(platform, clk_zx297520v3_ids); + +static struct platform_driver clk_zx297520v3 = { + .probe = clk_zx297520v3_probe, + .driver = { + .name = "clk-zx297520v3", + }, + .id_table = clk_zx297520v3_ids, +}; +module_platform_driver(clk_zx297520v3); + +MODULE_AUTHOR("Stefan Dösinger "); +MODULE_DESCRIPTION("ZTE zx297520v3 clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/zte/pll-zx.c b/drivers/clk/zte/pll-zx.c new file mode 100644 index 000000000000..d3687495d06c --- /dev/null +++ b/drivers/clk/zte/pll-zx.c @@ -0,0 +1,576 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Stefan Dösinger + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk-zx.h" + +/* + * This code has only been tested with zx297520v3 PLLs, but from reading the zx296718 clock code it + * looks like PLL registers are similar. ZTE's sources explain the PLL register contents only in a + * .cmm file (A Lauterbach TRACE32 script) and some unused headers in their U-Boot code dump, which + * may not be accurate. When calculating the frequencies from the default PLL configuration the + * results match the fixed rate clocks from their clock driver. + * + * The 26 MHz and 32 kHz clocks can be easily observed with the timers. The 104 MHz output can be + * observed through the UART. One 122.88 MHz clock can be observed through the TDM device. All + * others can only be indirectly inferred, e.g. by comparing CPU speed or SDIO transfer rate between + * the fixed 26 MHz oscillator and the provided PLL frequency. + * + * The formula to calculate the clock is ((ref / refdiv) * fbdiv) / postdiv1 / postdiv2. The masks + * are given below. There are a few control flags: + * + * Bit 31: Disables the PLL, but passes clock-26m through unmodified. Whether POSTDIV_OUT_DISABLE + * still matters is different between PLLs. + * Bit 30: Returns if the PLL is locked + * Bit 29: Not named in ZTE's code, but can be set. There is no obvious impact. Lock times are + * unchanged, so it doesn't influence or bypass lock detection. It doesn't raise any IRQs or + * influence GPIOs. + * Bit 27: Given its name it likely disables the Delta-Sigma Modulator, if one exists at all. The + * boot ROM sets it on every PLL. Unsetting it marginally decreases the time it takes to + * lock to the reference clock (from ~400 us to ~300 us). + * Bit 24: Bypasses the VCO, but still applies refdiv and postdiv. Doesn't matter if PLL_DISABLE=1. + * + * NB: Some PLLs have an automatic bypass logic that forwards clock-26m (REGARDLESS of reference) + * when they don't have a lock, regardless of reason. This can be triggered by disabling the PLL, + * setting an out-of-spec VCO frequency or disabling the parent. This shouldn't matter in regular + * operation, but caused me some confusion when reverse engineering the clock tree. E.g. clock-26m-> + * unknownpll(disabled) -> dpll(enabled) counterintuitively results in a 26 MHz output clock. + */ + +#define ZX29_PLL_DISABLE BIT(31) +#define ZX29_PLL_LOCKED BIT(30) +#define ZX29_PLL_LOCK_FILTER BIT(29) +#define ZX29_PLL_DSM_DISABLE BIT(27) +#define ZX29_PLL_PARENT_MASK GENMASK(26, 25) +#define ZX29_PLL_BYPASS BIT(24) +#define ZX29_PLL_REFDIV_MASK GENMASK(23, 18) +#define ZX29_PLL_FBDIV_MASK GENMASK(17, 6) +#define ZX29_PLL_POSTDIV1_MASK GENMASK(5, 3) +#define ZX29_PLL_POSTDIV2_MASK GENMASK(2, 0) + +/* + * The second register has a 24 bit fractional value, which only matters when ZX29_PLL_DSM_DISABLE + * is not set, and only seems to matter for dpll. ZTE's firmware does not make use of the fractional + * and it is unimplemented in this driver. Experimental testing confirms that it has an impact on + * dpll. + * + * Bits 27:24 contain more flags: + * + * Bit 27: Setting ZX29_PLL_DACAP slows down the lock time and obviates the speed gained from + * !DSM_DISABLE. No other effect observed. + * + * Bit 26: ZX29_PLL_4PHASE_OUT_DISABLE is set on some PLLs on boot but not on others. It is set on + * boot on mpll and upll, but not gpll, dpll or unknownpll. I am not sure what it does + * either. The SDIO devices break if they are fed from gpll with this flag set, but they + * work OK if they are fed from mpll without this flag set. + * + * Bit 25: ZX29_PLL_POSTDIV_OUT_DISABLE seems to disable the PLL output entirely. Whether it is + * bypassed by PLL_DISABLE differs between PLLs. gpll still produces an output clock if + * PLL_DISABLE = 1 and POSTDIV_DISABLE = 1, but produces no output if PLL_DISABLE = 0 and + * POSTDIV_DISABLE = 1. The dpll feeder ("unknownpll") at 0x100 produces no output clock if + * both PLL_DISABLE and POSTDIV_DISABLE are set to 1. + * + * Bit 24: ZX29_PLL_VCO_OUT_DISABLE probably disables the output of the VCO clock without + * post-VCO-dividers, but the raw VCO output is not a possible parent of any consumer clock, + * so I could not confirm this. It does not disable the VCO entirely - that's what + * PLL_DISABLE does. + * + * A spinlock should not be needed. PLLs don't share their registers with anything else and the + * global prepare mutex and enable spinlock should be enough. Beware of conflicts in reg2 between + * POSTDIV_OUT_DISABLE and the fractional value in case you find out how fractional dividers work + * and add support for them. + */ +#define ZX29_PLL_REG2_OFFSET 4 +#define ZX29_PLL_DACAP BIT(27) +#define ZX29_PLL_4PHASE_OUT_DISABLE BIT(26) +#define ZX29_PLL_POSTDIV_OUT_DISABLE BIT(25) +#define ZX29_PLL_VCO_OUT_DISABLE BIT(24) +#define ZX29_PLL_FRACT GENMASK(23, 0) + +/* + * The VCO's frequency range is limited. The stock settings run the VCO between 960 and 1248 MHz. + * Ad-hoc testing with gpll suggests that at least this PLL remains stable down to about 7 MHz and + * up to 2 GHz and produces a clock that can be used by the SDIO controller. Attempting to run the + * mpll VCO at 624 MHz and setting postdiv1 = postdiv2 = 1 - which should result in the same output + * frequency - or running it at 1872 MHz with an effective post divider of 3 crashes the CPU. Most + * likely the PLLs become unstable outside their core range and the SDIO controller is much more + * forgiving than CPU and DRAM are. + */ +#define ZX29_PLL_VCO_MAX_FREQ (1300 * HZ_PER_MHZ) +#define ZX29_PLL_VCO_MIN_FREQ (900 * HZ_PER_MHZ) + +struct zx29_clk_pll { + struct clk_hw hw; + struct device *dev; + struct regmap *map; + u16 reg; +}; + +static inline struct zx29_clk_pll *to_zx29_clk_pll(struct clk_hw *hw) +{ + return container_of(hw, struct zx29_clk_pll, hw); +} + +static int zx29_pll_is_prepared(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + int res; + + res = regmap_test_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + if (res < 0) + return res; + + return !res; +} + +static int zx29_pll_prepare(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + u32 val = 0; + int res; + + res = regmap_clear_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + if (res < 0) + return res; + + /* Lock duration is usually between 300 us and 500 us */ + res = regmap_read_poll_timeout(pll->map, pll->reg, val, val & ZX29_PLL_LOCKED, 50, 2000); + if (res) { + regmap_set_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + dev_err(pll->dev, "%s: PLL prepare failed: %d. Config value 0x%08x\n", + clk_hw_get_name(&pll->hw), res, val); + } + return res; +} + +static void zx29_pll_unprepare(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + + regmap_set_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); +} + +static int zx29_pll_is_enabled(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + int res; + + res = regmap_test_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); + if (res < 0) + return res; + + return !res; +} + +static int zx29_pll_enable(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + + return regmap_clear_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); +} + +static void zx29_pll_disable(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + + regmap_set_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); +} + +static unsigned long zx29_pll_get_rate(const struct zx29_clk_pll *pll, unsigned long parent_rate, + u32 setting) +{ + unsigned long refdiv, fbdiv, postdiv1, postdiv2, freq; + const char *name = clk_hw_get_name(&pll->hw); + u64 vco; + + refdiv = FIELD_GET(ZX29_PLL_REFDIV_MASK, setting); + fbdiv = FIELD_GET(ZX29_PLL_FBDIV_MASK, setting); + postdiv1 = FIELD_GET(ZX29_PLL_POSTDIV1_MASK, setting); + postdiv2 = FIELD_GET(ZX29_PLL_POSTDIV2_MASK, setting); + dev_dbg(pll->dev, "%s: reference clock %lu Hz, PLL setting 0x%08x\n", + name, parent_rate, setting); + + if (!refdiv || !postdiv1 || !postdiv2) { + dev_err(pll->dev, "%s: divide by zero (%lu, %lu, %lu)\n", name, refdiv, postdiv1, + postdiv2); + return 0; + } + + vco = div_u64((u64)parent_rate * fbdiv, refdiv); + freq = div_u64(div_u64(vco, postdiv1), postdiv2); + dev_dbg(pll->dev, "%s: refdiv %lu fbdiv %lu\n", name, refdiv, fbdiv); + dev_dbg(pll->dev, "%s: postdiv1 %lu postdiv2 %lu\n", name, postdiv1, postdiv2); + + dev_dbg(pll->dev, "%s: %lu MHz\n", name, freq / HZ_PER_MHZ); + + return freq; +} + +static unsigned long zx29_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + u32 val; + int res; + + res = regmap_read(pll->map, pll->reg, &val); + if (res < 0) { + dev_err(pll->dev, "%s: Failed to read PLL settings\n", clk_hw_get_name(&pll->hw)); + return 0; + } + + return zx29_pll_get_rate(pll, parent_rate, val); +} + +static u32 zx29_pll_calc_values(const struct zx29_clk_pll *pll, unsigned long parent_rate, + unsigned long rate, unsigned long min_rate, unsigned long max_rate) +{ + const unsigned int postdiv1_max = (1 << hweight32(ZX29_PLL_POSTDIV1_MASK)) - 1; + const unsigned int postdiv2_max = (1 << hweight32(ZX29_PLL_POSTDIV2_MASK)) - 1; + unsigned long fbdiv, refdiv, best_fbdiv = 0, best_refdiv = 0; + u32 postdiv1 = 0, postdiv2 = 0, i, j, setting; + const char *name = clk_hw_get_name(&pll->hw); + long best = LONG_MAX; + + /* + * This code produces the same VCO settings that the boot loader and stock firmware use for + * the standard frequencies. It has seen only very little manual testing beyond that. + * + * The goal is to find a VCO setting that gets us as close as possible to the desired output + * rate, while being within the VCO's operating limits and achievable with the input value + * range. It is iterating over possible post-VCO divider values (1-7)*(1-7) to look for + * valid VCO target frequencies and then looks for refdiv and fbdiv values to achieve the + * VCO frequency from the reference frequency. + */ + for (j = 1; j <= postdiv2_max; j++) { + for (i = 1; i <= postdiv1_max; i++) { + u64 vco = (u64)rate * i * j; + unsigned long out; + + if (vco > ZX29_PLL_VCO_MAX_FREQ || vco < ZX29_PLL_VCO_MIN_FREQ) + continue; + + rational_best_approximation(vco, parent_rate, + (1 << hweight32(ZX29_PLL_FBDIV_MASK)) - 1, + (1 << hweight32(ZX29_PLL_REFDIV_MASK)) - 1, + &fbdiv, &refdiv); + setting = FIELD_PREP(ZX29_PLL_FBDIV_MASK, fbdiv); + setting |= FIELD_PREP(ZX29_PLL_REFDIV_MASK, refdiv); + setting |= FIELD_PREP(ZX29_PLL_POSTDIV1_MASK, i); + setting |= FIELD_PREP(ZX29_PLL_POSTDIV2_MASK, j); + out = zx29_pll_get_rate(pll, parent_rate, setting); + + if (out < min_rate || out > max_rate) + continue; + + if (abs_diff(out, rate) > best) + continue; + + if (abs_diff(out, rate) < best) { + postdiv1 = i; + postdiv2 = j; + best_fbdiv = fbdiv; + best_refdiv = refdiv; + best = abs_diff(out, rate); + + if (!best) + goto search_done; + } + } + } +search_done: + + if (!postdiv1) { + dev_err(pll->dev, "Did not find a setting for %lu Hz, parent %lu Hz\n", + rate, parent_rate); + return 0; + } + + dev_dbg(pll->dev, "%s: parent rate %lu\n", name, parent_rate); + dev_dbg(pll->dev, "%s: found VCO dividers %u and %u\n", name, postdiv1, postdiv2); + dev_dbg(pll->dev, "%s: VCO target rate %lu\n", name, rate * postdiv1 * postdiv2); + + dev_dbg(pll->dev, "%s: Got fbdiv = %lu refdiv = %lu\n", name, best_fbdiv, best_refdiv); + + setting = FIELD_PREP(ZX29_PLL_FBDIV_MASK, best_fbdiv); + setting |= FIELD_PREP(ZX29_PLL_REFDIV_MASK, best_refdiv); + setting |= FIELD_PREP(ZX29_PLL_POSTDIV1_MASK, postdiv1); + setting |= FIELD_PREP(ZX29_PLL_POSTDIV2_MASK, postdiv2); + dev_dbg(pll->dev, "%s: Final setting 0x%08x\n", name, setting); + + return setting; +} + +static int zx29_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + unsigned long new_rate; + u32 setting; + + /* + * TODO: DPLL can switch between two parents, one of which is another PLL. Take this into + * account when searching the config space and set req->best_parent_rate. + * + * In practice it shouldn't matter though. Dpll is always configured to a fixed frequency + * and is the only clock with a switchable parent. + */ + if (!req->best_parent_rate) { + dev_err(pll->dev, "Did not expect best_parent_rate=0\n"); + return -EINVAL; + } + + setting = zx29_pll_calc_values(pll, req->best_parent_rate, req->rate, req->min_rate, + req->max_rate); + if (!setting) + return -EINVAL; + + new_rate = zx29_pll_get_rate(pll, req->best_parent_rate, setting); + if (new_rate != req->rate) { + dev_dbg(pll->dev, "Did not find an exact match. Want %lu, got %lu\n", + req->rate, new_rate); + req->rate = new_rate; + } + + return 0; +} + +static int zx29_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + u32 setting; + + /* + * TODO: Implement gradual PLL rate change. PLLs can be changed while they are running and + * downstream hardware is generally fine with that. The exception is DRAM, which reads + * incorrect values if changed too fast. + * + * Changing the mpll rate is potentially useful for over/underclocking. Gating mpll is + * unrealistic because too many devices depend on it. + */ + setting = zx29_pll_calc_values(pll, parent_rate, rate, rate, rate); + if (!setting) + return -EINVAL; + + dev_dbg(pll->dev, "%s: Setting new configuration: 0x%08x\n", clk_hw_get_name(hw), setting); + + return regmap_update_bits(pll->map, pll->reg, 0x00ffffff, setting); +} + +static u8 zx29_pll_get_parent(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + u32 val; + int res; + + res = regmap_read(pll->map, pll->reg, &val); + if (res < 0) + return 0xff; + + val = FIELD_GET(ZX29_PLL_PARENT_MASK, val); + dev_dbg(pll->dev, "%s: Parent 0x%x\n", clk_hw_get_name(hw), val); + + return val; +} + +static int zx29_pll_set_parent(struct clk_hw *hw, u8 index) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + u32 parent = FIELD_PREP(ZX29_PLL_PARENT_MASK, index); + int res; + u32 val; + + res = regmap_update_bits(pll->map, pll->reg, ZX29_PLL_PARENT_MASK, parent); + if (res < 0) + return res; + + res = regmap_read(pll->map, pll->reg, &val); + if (res < 0) + return res; + + if ((val & ZX29_PLL_PARENT_MASK) != parent) { + dev_err(pll->dev, "Hardware rejected PLL parent %u\n", index); + return -EINVAL; + } + + return 0; +} + +static int zx29_pll_init(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + const char *name = clk_hw_get_name(hw); + int res; + u32 val; + + dev_dbg(pll->dev, "%s: initializing\n", name); + + /* + * The fractional value is not yet implemented. It works at least with dpll, but I have + * never seen it used on actual hardware. + */ + res = regmap_read(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, &val); + if (res < 0) + return res; + + if (val & ZX29_PLL_FRACT) { + dev_warn(pll->dev, "%s: unsupported nonzero fractional value 0x%08lx\n", + name, val & ZX29_PLL_FRACT); + } + + /* + * Remove the bypass flag so we don't have to bother with it in enable/disable. I have never + * seen it set by the earlier boot stages anyhow. + */ + res = regmap_clear_bits(pll->map, pll->reg, ZX29_PLL_BYPASS); + if (res < 0) + return res; + + res = regmap_test_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + if (res > 0) { + /* + * Set ZX29_PLL_POSTDIV_OUT_DISABLE for PLLs that have ZX29_PLL_DISABLE for + * consistency with .enable and .prepare. This ensures that .prepare doesn't + * inadvertently enable PLLs without .enable being called. + */ + res = regmap_set_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); + } + + return res; +} + +static const struct clk_ops zx29_pll_ops = { + .init = zx29_pll_init, + .is_prepared = zx29_pll_is_prepared, + .prepare = zx29_pll_prepare, + .unprepare = zx29_pll_unprepare, + .is_enabled = zx29_pll_is_enabled, + .enable = zx29_pll_enable, + .disable = zx29_pll_disable, + .recalc_rate = zx29_pll_recalc_rate, + .determine_rate = zx29_pll_determine_rate, + .get_parent = zx29_pll_get_parent, + .set_parent = zx29_pll_set_parent, + .set_rate = zx29_pll_set_rate, +}; + +/* + * A PLL that can be a parent of another PLL needs to produce an output signal when prepared, + * otherwise the downstream PLL's prepare() will fail to acquire a lock. + */ +static int zx29_pll_nodisable_init(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + const char *name = clk_hw_get_name(hw); + int res; + u32 val; + + dev_dbg(pll->dev, "%s: initializing, prepare-is-enabled\n", name); + + res = regmap_read(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, &val); + if (res < 0) + return res; + + if (val & ZX29_PLL_FRACT) { + dev_warn(pll->dev, "%s: unsupported nonzero fractional value 0x%08lx\n", + name, val & ZX29_PLL_FRACT); + } + + res = regmap_clear_bits(pll->map, pll->reg, ZX29_PLL_BYPASS); + if (res < 0) + return res; + + return regmap_clear_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); +} + +static const struct clk_ops zx29_pll_nodisable_ops = { + .init = zx29_pll_nodisable_init, + .is_prepared = zx29_pll_is_prepared, + .prepare = zx29_pll_prepare, + .unprepare = zx29_pll_unprepare, + .recalc_rate = zx29_pll_recalc_rate, + .determine_rate = zx29_pll_determine_rate, + .get_parent = zx29_pll_get_parent, + .set_parent = zx29_pll_set_parent, + .set_rate = zx29_pll_set_rate, +}; + +struct clk_hw *zx_clk_register_pll(struct device *dev, struct regmap *regmap, + const struct zx_pll_desc *desc, struct clk_hw * const *clocks) +{ + struct clk_parent_data parents[CLK_ZX_MAX_PARENTS]; + struct clk_init_data init = {}; + struct zx29_clk_pll *pll; + unsigned int i; + int res; + + pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + if (desc->flags & CLK_ZX_PLL_PREPARE_IS_ENABLE) + init.ops = &zx29_pll_nodisable_ops; + else + init.ops = &zx29_pll_ops; + + if (WARN_ON(desc->num_parents > ARRAY_SIZE(parents))) + return ERR_PTR(-EINVAL); + + for (i = 0; i < desc->num_parents; ++i) + parents[i] = zx_get_parent(&desc->parents[i], clocks); + + init.name = desc->name; + init.parent_data = parents; + init.num_parents = desc->num_parents; + + /* + * Disallow live reparent, but allow rate changes. PLLs can handle gradual changes fine, but + * large ones cause a temporary incorrect output, which can break downstream devices. + * See zx29_pll_set_rate for considerations on that. + */ + init.flags = CLK_SET_PARENT_GATE; + pll->hw.init = &init; + pll->dev = dev; + pll->map = regmap; + pll->reg = desc->reg; + + res = devm_clk_hw_register(dev, &pll->hw); + if (res) + return ERR_PTR(res); + + /* + * Set the PLL rate only if the bootloader left it disabled. Keep the bootloader setup + * otherwise. + */ + res = regmap_test_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + if (res < 0) + return ERR_PTR(res); + + if (res > 0 && desc->rate) { + dev_dbg(pll->dev, "%s: setting to %lu Hz\n", desc->name, desc->rate); + res = clk_set_rate(pll->hw.clk, desc->rate); + if (res) + return ERR_PTR(dev_err_probe(dev, res, "%s: failed to set rate\n", + desc->name)); + } + + return &pll->hw; +} diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c index db10eb69f3fe..1a462af7b8ea 100644 --- a/drivers/clk/zynqmp/clk-gate-zynqmp.c +++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c @@ -109,10 +109,10 @@ struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id, u8 num_parents, const struct clock_topology *nodes) { + struct clk_init_data init = {}; struct zynqmp_clk_gate *gate; struct clk_hw *hw; int ret; - struct clk_init_data init; /* allocate the gate */ gate = kzalloc_obj(*gate); diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c index e37bd3516974..79509e387b51 100644 --- a/drivers/clk/zynqmp/clk-mux-zynqmp.c +++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c @@ -133,9 +133,9 @@ struct clk_hw *zynqmp_clk_register_mux(const char *name, u32 clk_id, u8 num_parents, const struct clock_topology *nodes) { + struct clk_init_data init = {}; struct zynqmp_clk_mux *mux; struct clk_hw *hw; - struct clk_init_data init; int ret; mux = kzalloc_obj(*mux); diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c index 4075f6ecf076..3eabd1cf211d 100644 --- a/drivers/clk/zynqmp/divider.c +++ b/drivers/clk/zynqmp/divider.c @@ -278,9 +278,9 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name, u8 num_parents, const struct clock_topology *nodes) { + struct clk_init_data init = {}; struct zynqmp_clk_divider *div; struct clk_hw *hw; - struct clk_init_data init; int ret; /* allocate the divider */ diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c index 6463787cf57b..6158386ca743 100644 --- a/drivers/clk/zynqmp/pll.c +++ b/drivers/clk/zynqmp/pll.c @@ -313,9 +313,9 @@ struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id, u8 num_parents, const struct clock_topology *nodes) { + struct clk_init_data init = {}; struct zynqmp_pll *pll; struct clk_hw *hw; - struct clk_init_data init; int ret; init.name = name; diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 3168ab1eea88..eda9c698a95f 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -73,6 +73,16 @@ config RESET_BRCMSTB_RESCAL This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on BCM7216 or the BCM2712. +config RESET_DR1V90 + tristate "Anlogic DR1V90 reset controller" + depends on ARCH_ANLOGIC || COMPILE_TEST + depends on ANLOGIC_DR1V90_CRU + select AUXILIARY_BUS + default ARCH_ANLOGIC + help + This enables the reset controller driver for Anlogic DR1V90 SoCs + provided by the CRU unit. + config RESET_EIC7700 bool "Reset controller driver for ESWIN SoCs" depends on ARCH_ESWIN || COMPILE_TEST diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 45ad17062462..489fafd6bbe3 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o 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_DR1V90) += reset-dr1v90.o obj-$(CONFIG_RESET_EIC7700) += reset-eic7700.o obj-$(CONFIG_RESET_EIC7700_HSP) += reset-eic7700-hsp.o obj-$(CONFIG_RESET_EYEQ) += reset-eyeq.o diff --git a/drivers/reset/reset-dr1v90.c b/drivers/reset/reset-dr1v90.c new file mode 100644 index 000000000000..daa99c797b1a --- /dev/null +++ b/drivers/reset/reset-dr1v90.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Junhui Liu + */ + +#include +#include +#include +#include +#include + +#include + +struct dr1v90_reset_map { + u32 offset; + u32 bit; +}; + +struct dr1v90_reset_controller { + struct reset_controller_dev rcdev; + void __iomem *base; + spinlock_t lock; /* protect register read-modify-write */ +}; + +static inline struct dr1v90_reset_controller * +to_dr1v90_reset_controller(struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct dr1v90_reset_controller, rcdev); +} + +static const struct dr1v90_reset_map dr1v90_resets[] = { + [RESET_OCM] = { 0x74, BIT(4)}, + [RESET_QSPI] = { 0x74, BIT(5)}, + [RESET_SMC] = { 0x74, BIT(6)}, + [RESET_WDT] = { 0x74, BIT(7)}, + [RESET_DMAC_AXI] = { 0x74, BIT(8)}, + [RESET_DMAC_AHB] = { 0x74, BIT(9)}, + [RESET_NPU] = { 0x74, BIT(12)}, + [RESET_JPU] = { 0x74, BIT(13)}, + [RESET_DDRBUS] = { 0x74, BIT(14)}, + [RESET_NIC_HP0] = { 0x78, BIT(0)}, + [RESET_NIC_HP1] = { 0x78, BIT(1)}, + [RESET_NIC_GP0M] = { 0x78, BIT(4)}, + [RESET_NIC_GP1M] = { 0x78, BIT(5)}, + [RESET_GPIO] = { 0x78, BIT(8)}, + [RESET_IPC] = { 0x78, BIT(12)}, + [RESET_USB0] = { 0x7C, BIT(0)}, + [RESET_USB1] = { 0x7C, BIT(1)}, + [RESET_GBE0] = { 0x7C, BIT(4)}, + [RESET_GBE1] = { 0x7C, BIT(5)}, + [RESET_SDIO0] = { 0x7C, BIT(8)}, + [RESET_SDIO1] = { 0x7C, BIT(9)}, + [RESET_UART0] = { 0x7C, BIT(12)}, + [RESET_UART1] = { 0x7C, BIT(13)}, + [RESET_SPI0] = { 0x7C, BIT(16)}, + [RESET_SPI1] = { 0x7C, BIT(17)}, + [RESET_CAN0] = { 0x7C, BIT(20)}, + [RESET_CAN1] = { 0x7C, BIT(21)}, + [RESET_TTC0] = { 0x7C, BIT(24)}, + [RESET_TTC1] = { 0x7C, BIT(25)}, + [RESET_I2C0] = { 0x7C, BIT(28)}, + [RESET_I2C1] = { 0x7C, BIT(29)} +}; + +static int dr1v90_reset_control_update(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) +{ + struct dr1v90_reset_controller *rstc = to_dr1v90_reset_controller(rcdev); + u32 offset = dr1v90_resets[id].offset; + u32 bit = dr1v90_resets[id].bit; + u32 reg; + + guard(spinlock_irqsave)(&rstc->lock); + + reg = readl(rstc->base + offset); + if (assert) + reg &= ~bit; + else + reg |= bit; + writel(reg, rstc->base + offset); + + return 0; +} + +static int dr1v90_reset_control_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return dr1v90_reset_control_update(rcdev, id, true); +} + +static int dr1v90_reset_control_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return dr1v90_reset_control_update(rcdev, id, false); +} + +static const struct reset_control_ops dr1v90_reset_control_ops = { + .assert = dr1v90_reset_control_assert, + .deassert = dr1v90_reset_control_deassert, +}; + +static int dr1v90_reset_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct dr1v90_reset_controller *rstc; + struct device *dev = &adev->dev; + + rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); + if (!rstc) + return -ENOMEM; + + spin_lock_init(&rstc->lock); + + rstc->base = dev->platform_data; + rstc->rcdev.dev = dev; + rstc->rcdev.nr_resets = ARRAY_SIZE(dr1v90_resets); + rstc->rcdev.of_node = dev->parent->of_node; + rstc->rcdev.ops = &dr1v90_reset_control_ops; + rstc->rcdev.owner = THIS_MODULE; + + return devm_reset_controller_register(dev, &rstc->rcdev); +} + +static const struct auxiliary_device_id dr1v90_reset_ids[] = { + { + .name = "anlogic_dr1_cru.reset" + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(auxiliary, dr1v90_reset_ids); + +static struct auxiliary_driver dr1v90_reset_driver = { + .probe = dr1v90_reset_probe, + .id_table = dr1v90_reset_ids, +}; +module_auxiliary_driver(dr1v90_reset_driver); + +MODULE_AUTHOR("Junhui Liu "); +MODULE_DESCRIPTION("Anlogic DR1V90 reset controller driver"); +MODULE_LICENSE("GPL"); diff --git a/include/dt-bindings/clock/amlogic,a9-scmi-clkc.h b/include/dt-bindings/clock/amlogic,a9-scmi-clkc.h new file mode 100644 index 000000000000..d543db9fe035 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,a9-scmi-clkc.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2026 Amlogic, Inc. All rights reserved. + */ + +#ifndef __AMLOGIC_A9_SCMI_CLKC_H +#define __AMLOGIC_A9_SCMI_CLKC_H + +#define CLKID_GP0_PLL_OSC 0 +#define CLKID_GP1_PLL_OSC 1 +#define CLKID_HIFI_PLL_OSC 2 +#define CLKID_GP2_PLL_OSC 3 +#define CLKID_MCLK_PLL_OSC 4 +#define CLKID_FIXED_PLL 5 +#define CLKID_FCLK_50M_PREDIV 6 +#define CLKID_FCLK_50M_DIV 7 +#define CLKID_FCLK_50M 8 +#define CLKID_FCLK_DIV2_DIV 9 +#define CLKID_FCLK_DIV2 10 +#define CLKID_FCLK_DIV2P5_DIV 11 +#define CLKID_FCLK_DIV2P5 12 +#define CLKID_FCLK_DIV3_DIV 13 +#define CLKID_FCLK_DIV3 14 +#define CLKID_FCLK_DIV4_DIV 15 +#define CLKID_FCLK_DIV4 16 +#define CLKID_FCLK_DIV5_DIV 17 +#define CLKID_FCLK_DIV5 18 +#define CLKID_FCLK_DIV7_DIV 19 +#define CLKID_FCLK_DIV7 20 +#define CLKID_SYS_CLK 21 +#define CLKID_SYS_AO_SYS 22 +#define CLKID_SYS_MMC_APB 23 +#define CLKID_SYS_CPU_APB 24 +#define CLKID_SYS_GIC 25 +#define CLKID_AXI_CLK 26 +#define CLKID_AXI_SYS_NIC 27 +#define CLKID_AXI_RAMA 28 +#define CLKID_CPU_CLK 29 +#define CLKID_A78_CLK 30 +#define CLKID_DSU_CLK 31 +#define CLKID_ACLKM 32 +#define CLKID_GP1_PLL 33 +#define CLKID_GP2_PLL 34 +#define CLKID_SYS_PLL_DIV16 35 +#define CLKID_CPU_CLK_DIV16 36 +#define CLKID_A78_CLK_DIV16 37 +#define CLKID_DSU_CLK_DIV16 38 +#define CLKID_GIC_CLK 39 +#define CLKID_RTC 40 + +#endif /* __AMLOGIC_A9_SCMI_CLKC_H */ diff --git a/include/dt-bindings/clock/anlogic,dr1v90-cru.h b/include/dt-bindings/clock/anlogic,dr1v90-cru.h new file mode 100644 index 000000000000..664daf3946a7 --- /dev/null +++ b/include/dt-bindings/clock/anlogic,dr1v90-cru.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2024-2025 Anlogic, Inc. + * Copyright (C) 2025 Junhui Liu + */ + +#ifndef _DT_BINDINGS_CLOCK_ANLOGIC_DR1V90_CRU_H_ +#define _DT_BINDINGS_CLOCK_ANLOGIC_DR1V90_CRU_H_ + +#define CLK_OSC_DIV2 0 +#define CLK_CPU_PLL 1 +#define CLK_CPU_PLL_4X 2 +#define CLK_CPU_4X 3 +#define CLK_CPU_2X 4 +#define CLK_CPU_1X 5 +#define CLK_IO_PLL 6 +#define CLK_IO_1000M 7 +#define CLK_IO_400M 8 +#define CLK_IO_25M 9 +#define CLK_IO_80M 10 +#define CLK_IO_400M_DIV2 11 +#define CLK_IO_400M_DIV4 12 +#define CLK_IO_400M_DIV8 13 +#define CLK_IO_400M_DIV16 14 +#define CLK_QSPI 15 +#define CLK_SPI 16 +#define CLK_SMC 17 +#define CLK_SDIO 18 +#define CLK_GPIO_DB 19 +#define CLK_EFUSE 20 +#define CLK_TVS 21 +#define CLK_TRNG 22 +#define CLK_OSC_DIV 23 +#define CLK_PWM 24 +#define CLK_FCLK0 25 +#define CLK_FCLK1 26 +#define CLK_FCLK2 27 +#define CLK_FCLK3 28 +#define CLK_WDT_SEL 29 +#define CLK_EFUSE_SEL 30 +#define CLK_CAN_SEL 31 +#define CLK_CPU_SEL 32 +#define CLK_CAN0 33 +#define CLK_CAN1 34 + +#endif /* _DT_BINDINGS_CLOCK_ANLOGIC_DR1V90_CRU_H_ */ diff --git a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h index ba2d70f776a6..764d837d6162 100644 --- a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h +++ b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h @@ -248,6 +248,7 @@ #define ADC_GATE 233 #define EADC_DIV 234 #define EADC_GATE 235 -#define CLK_MAX_IDX 236 +#define PCLK3_DIV4096 236 +#define PCLK4_DIV4096 237 #endif /* __DT_BINDINGS_CLOCK_NUVOTON_MA35D1_CLK_H */ diff --git a/include/dt-bindings/clock/qcom,gcc-msm8952.h b/include/dt-bindings/clock/qcom,gcc-msm8952.h new file mode 100644 index 000000000000..5b5c38a9f4dd --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-msm8952.h @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright 2020 Linaro Limited + * Copyright 2026 Muzaffer Kadir + */ + +#ifndef _DT_BINDINGS_CLK_MSM_GCC_8952_H +#define _DT_BINDINGS_CLK_MSM_GCC_8952_H + +#define GPLL0 0 +#define GPLL0_VOTE 1 +#define GPLL3 2 +#define GPLL3_EARLY 3 +#define GPLL4 4 +#define GPLL4_VOTE 5 +#define GPLL6 6 +#define GPLL6_VOTE 7 +#define CAMSS_TOP_AHB_CLK_SRC 8 +#define APSS_AHB_CLK_SRC 9 +#define CSI0_CLK_SRC 10 +#define CSI1_CLK_SRC 11 +#define GFX3D_CLK_SRC 12 +#define VFE0_CLK_SRC 13 +#define BLSP1_QUP1_I2C_APPS_CLK_SRC 14 +#define BLSP1_QUP1_SPI_APPS_CLK_SRC 15 +#define BLSP1_QUP2_I2C_APPS_CLK_SRC 16 +#define BLSP1_QUP2_SPI_APPS_CLK_SRC 17 +#define BLSP1_QUP3_I2C_APPS_CLK_SRC 18 +#define BLSP1_QUP3_SPI_APPS_CLK_SRC 19 +#define BLSP1_QUP4_I2C_APPS_CLK_SRC 20 +#define BLSP1_QUP4_SPI_APPS_CLK_SRC 21 +#define BLSP1_UART1_APPS_CLK_SRC 22 +#define BLSP1_UART2_APPS_CLK_SRC 23 +#define CCI_CLK_SRC 24 +#define CAMSS_GP0_CLK_SRC 25 +#define CAMSS_GP1_CLK_SRC 26 +#define JPEG0_CLK_SRC 27 +#define MCLK0_CLK_SRC 28 +#define MCLK1_CLK_SRC 29 +#define CSI0PHYTIMER_CLK_SRC 30 +#define CSI1PHYTIMER_CLK_SRC 31 +#define CPP_CLK_SRC 32 +#define CRYPTO_CLK_SRC 33 +#define GP1_CLK_SRC 34 +#define GP2_CLK_SRC 35 +#define GP3_CLK_SRC 36 +#define BYTE0_CLK_SRC 37 +#define ESC0_CLK_SRC 38 +#define MDP_CLK_SRC 39 +#define PCLK0_CLK_SRC 40 +#define VSYNC_CLK_SRC 41 +#define PDM2_CLK_SRC 42 +#define SDCC1_APPS_CLK_SRC 43 +#define SDCC2_APPS_CLK_SRC 44 +#define USB_HS_SYSTEM_CLK_SRC 45 +#define VCODEC0_CLK_SRC 46 +#define GCC_BLSP1_AHB_CLK 47 +#define GCC_BLSP1_QUP1_I2C_APPS_CLK 48 +#define GCC_BLSP1_QUP1_SPI_APPS_CLK 49 +#define GCC_BLSP1_QUP2_I2C_APPS_CLK 50 +#define GCC_BLSP1_QUP2_SPI_APPS_CLK 51 +#define GCC_BLSP1_QUP3_I2C_APPS_CLK 52 +#define GCC_BLSP1_QUP3_SPI_APPS_CLK 53 +#define GCC_BLSP1_QUP4_I2C_APPS_CLK 54 +#define GCC_BLSP1_QUP4_SPI_APPS_CLK 55 +#define GCC_BLSP1_UART1_APPS_CLK 56 +#define GCC_BLSP1_UART2_APPS_CLK 57 +#define GCC_BOOT_ROM_AHB_CLK 58 +#define GCC_CAMSS_CCI_AHB_CLK 59 +#define GCC_CAMSS_CCI_CLK 60 +#define GCC_CAMSS_CSI0_AHB_CLK 61 +#define GCC_CAMSS_CSI0_CLK 62 +#define GCC_CAMSS_CSI0PHY_CLK 63 +#define GCC_CAMSS_CSI0PIX_CLK 64 +#define GCC_CAMSS_CSI0RDI_CLK 65 +#define GCC_CAMSS_CSI1_AHB_CLK 66 +#define GCC_CAMSS_CSI1_CLK 67 +#define GCC_CAMSS_CSI1PHY_CLK 68 +#define GCC_CAMSS_CSI1PIX_CLK 69 +#define GCC_CAMSS_CSI1RDI_CLK 70 +#define GCC_CAMSS_CSI_VFE0_CLK 71 +#define GCC_CAMSS_GP0_CLK 72 +#define GCC_CAMSS_GP1_CLK 73 +#define GCC_CAMSS_ISPIF_AHB_CLK 74 +#define GCC_CAMSS_JPEG0_CLK 75 +#define GCC_CAMSS_JPEG_AHB_CLK 76 +#define GCC_CAMSS_JPEG_AXI_CLK 77 +#define GCC_CAMSS_MCLK0_CLK 78 +#define GCC_CAMSS_MCLK1_CLK 79 +#define GCC_CAMSS_MICRO_AHB_CLK 80 +#define GCC_CAMSS_CSI0PHYTIMER_CLK 81 +#define GCC_CAMSS_CSI1PHYTIMER_CLK 82 +#define GCC_CAMSS_AHB_CLK 83 +#define GCC_CAMSS_TOP_AHB_CLK 84 +#define GCC_CAMSS_CPP_AHB_CLK 85 +#define GCC_CAMSS_CPP_CLK 86 +#define GCC_CAMSS_VFE0_CLK 87 +#define GCC_CAMSS_VFE0_AHB_CLK 88 +#define GCC_CAMSS_VFE0_AXI_CLK 89 +#define GCC_CRYPTO_AHB_CLK 90 +#define GCC_CRYPTO_AXI_CLK 91 +#define GCC_CRYPTO_CLK 92 +#define GCC_OXILI_GMEM_CLK 93 +#define GCC_GP1_CLK 94 +#define GCC_GP2_CLK 95 +#define GCC_GP3_CLK 96 +#define GCC_MDSS_AHB_CLK 97 +#define GCC_MDSS_AXI_CLK 98 +#define GCC_MDSS_BYTE0_CLK 99 +#define GCC_MDSS_ESC0_CLK 100 +#define GCC_MDSS_MDP_CLK 101 +#define GCC_MDSS_PCLK0_CLK 102 +#define GCC_MDSS_VSYNC_CLK 103 +#define GCC_MSS_CFG_AHB_CLK 104 +#define GCC_OXILI_AHB_CLK 105 +#define GCC_OXILI_GFX3D_CLK 106 +#define GCC_PDM2_CLK 107 +#define GCC_PDM_AHB_CLK 108 +#define GCC_PRNG_AHB_CLK 109 +#define GCC_SDCC1_AHB_CLK 110 +#define GCC_SDCC1_APPS_CLK 111 +#define GCC_SDCC2_AHB_CLK 112 +#define GCC_SDCC2_APPS_CLK 113 +#define GCC_GTCU_AHB_CLK 114 +#define GCC_JPEG_TBU_CLK 115 +#define GCC_MDP_TBU_CLK 116 +#define GCC_SMMU_CFG_CLK 117 +#define GCC_VENUS_TBU_CLK 118 +#define GCC_VFE_TBU_CLK 119 +#define GCC_USB2A_PHY_SLEEP_CLK 120 +#define GCC_USB_HS_AHB_CLK 121 +#define GCC_USB_HS_SYSTEM_CLK 122 +#define GCC_VENUS0_AHB_CLK 123 +#define GCC_VENUS0_AXI_CLK 124 +#define GCC_VENUS0_VCODEC0_CLK 125 +#define GCC_APSS_TCU_CLK 126 +#define GCC_GFX_TCU_CLK 127 +#define GCC_BIMC_GFX_CLK 128 +#define GCC_BIMC_GPU_CLK 129 +#define GCC_MSS_Q6_BIMC_AXI_CLK 130 +#define GCC_GFX_TBU_CLK 131 +#define GCC_CPP_TBU_CLK 132 +#define USB_FS_SYSTEM_CLK_SRC 133 +#define USB_FS_IC_CLK_SRC 134 +#define GCC_USB_FS_AHB_CLK 135 +#define GCC_USB_FS_IC_CLK 136 +#define GCC_USB_FS_SYSTEM_CLK 137 +#define GCC_VENUS0_CORE0_VCODEC0_CLK 138 +#define GCC_VENUS0_CORE1_VCODEC0_CLK 139 +#define GCC_OXILI_TIMER_CLK 140 +#define GCC_USB_HS_PHY_CFG_AHB_CLK 141 +#define CSI2_CLK_SRC 142 +#define GCC_CAMSS_CSI2_AHB_CLK 143 +#define GCC_CAMSS_CSI2_CLK 144 +#define GCC_CAMSS_CSI2PHY_CLK 145 +#define GCC_CAMSS_CSI2PIX_CLK 146 +#define GCC_CAMSS_CSI2RDI_CLK 147 +#define SDCC1_ICE_CORE_CLK_SRC 148 +#define GCC_SDCC1_ICE_CORE_CLK 149 +#define BLSP2_QUP1_I2C_APPS_CLK_SRC 150 +#define BLSP2_QUP1_SPI_APPS_CLK_SRC 151 +#define BLSP2_QUP2_I2C_APPS_CLK_SRC 152 +#define BLSP2_QUP2_SPI_APPS_CLK_SRC 153 +#define BLSP2_QUP3_I2C_APPS_CLK_SRC 154 +#define BLSP2_QUP3_SPI_APPS_CLK_SRC 155 +#define BLSP2_QUP4_I2C_APPS_CLK_SRC 156 +#define BLSP2_QUP4_SPI_APPS_CLK_SRC 157 +#define BLSP2_UART1_APPS_CLK_SRC 158 +#define BLSP2_UART2_APPS_CLK_SRC 159 +#define GCC_BLSP2_AHB_CLK 160 +#define GCC_BLSP2_QUP1_I2C_APPS_CLK 161 +#define GCC_BLSP2_QUP1_SPI_APPS_CLK 162 +#define GCC_BLSP2_QUP2_I2C_APPS_CLK 163 +#define GCC_BLSP2_QUP2_SPI_APPS_CLK 164 +#define GCC_BLSP2_QUP3_I2C_APPS_CLK 165 +#define GCC_BLSP2_QUP3_SPI_APPS_CLK 166 +#define GCC_BLSP2_QUP4_I2C_APPS_CLK 167 +#define GCC_BLSP2_QUP4_SPI_APPS_CLK 168 +#define GCC_BLSP2_UART1_APPS_CLK 169 +#define GCC_BLSP2_UART2_APPS_CLK 170 +#define VFE1_CLK_SRC 171 +#define GCC_CAMSS_VFE1_CLK 172 +#define GCC_CAMSS_VFE1_AHB_CLK 173 +#define GCC_CAMSS_VFE1_AXI_CLK 174 +#define GCC_CAMSS_CSI_VFE1_CLK 175 +#define MCLK2_CLK_SRC 176 +#define GCC_CAMSS_MCLK2_CLK 177 +#define GCC_VFE1_TBU_CLK 178 +#define GCC_IPA_TBU_CLK 179 +#define GCC_CAMSS_CPP_AXI_CLK 180 + +/* Indexes for GDSCs */ +#define VENUS_GDSC 0 +#define MDSS_GDSC 1 +#define JPEG_GDSC 2 +#define VFE0_GDSC 3 +#define VFE1_GDSC 4 +#define OXILI_GX_GDSC 5 +#define VENUS_CORE0_GDSC 6 +#define VENUS_CORE1_GDSC 7 +#define CPP_GDSC 8 + +/* Indexes for Resets */ +#define GCC_CRYPTO_BCR 0 +#define GCC_USB_FS_BCR 1 +#define GCC_USB_HS_BCR 2 +#define GCC_QUSB2_PHY_BCR 3 +#define GCC_USB2_HS_PHY_ONLY_BCR 4 +#define GCC_SDCC1_BCR 5 +#define GCC_SDCC2_BCR 6 +#define GCC_MDSS_BCR 7 +#define GCC_CAMSS_MICRO_BCR 8 +#define GCC_MSS_BCR 9 + +#endif diff --git a/include/dt-bindings/clock/qcom,ipq5210-cmn-pll.h b/include/dt-bindings/clock/qcom,ipq5210-cmn-pll.h new file mode 100644 index 000000000000..9201d1e1062c --- /dev/null +++ b/include/dt-bindings/clock/qcom,ipq5210-cmn-pll.h @@ -0,0 +1,30 @@ +/* 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_IPQ5210_CMN_PLL_H +#define _DT_BINDINGS_CLK_QCOM_IPQ5210_CMN_PLL_H + +/* Parent clock */ +#define IPQ5210_CMN_PLL_CLK 0 + +/* Fixed-rate clocks */ +#define IPQ5210_XO_24MHZ_CLK 1 +#define IPQ5210_SLEEP_32KHZ_CLK 2 + +/* Configurable divider clocks */ +#define IPQ5210_NSS_CLK 3 +#define IPQ5210_PPE_CLK 4 +#define IPQ5210_PON_CLK 5 +#define IPQ5210_EPHY_RAW_CLK 6 + +/* Gate clocks */ +#define IPQ5210_PCS_31P25MHZ_CLK 7 +#define IPQ5210_ETH0_50MHZ_CLK 8 +#define IPQ5210_ETH1_50MHZ_CLK 9 +#define IPQ5210_ETH2_50MHZ_CLK 10 +#define IPQ5210_EPHY_50MHZ_CLK 11 +#define IPQ5210_ETH_25MHZ_CLK 12 + +#endif diff --git a/include/dt-bindings/clock/qcom,kuno-gcc.h b/include/dt-bindings/clock/qcom,kuno-gcc.h new file mode 100644 index 000000000000..a237b25a061d --- /dev/null +++ b/include/dt-bindings/clock/qcom,kuno-gcc.h @@ -0,0 +1,100 @@ +/* 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_KUNO_H +#define _DT_BINDINGS_CLK_QCOM_GCC_KUNO_H + +/* GCC clocks */ +#define GPLL0 0 +#define GPLL0_OUT_EVEN 1 +#define GPLL2 2 +#define GPLL3 3 +#define GPLL4 4 +#define GPLL4_OUT_EVEN 5 +#define GCC_EMAC0_AXI_CLK 7 +#define GCC_EMAC0_PHY_AUX_CLK 8 +#define GCC_EMAC0_PHY_AUX_CLK_SRC 9 +#define GCC_EMAC0_PTP_CLK 10 +#define GCC_EMAC0_PTP_CLK_SRC 11 +#define GCC_EMAC0_RGMII_CLK 12 +#define GCC_EMAC0_RGMII_CLK_SRC 13 +#define GCC_EMAC0_SLV_AHB_CLK 14 +#define GCC_EMAC_0_CLKREF_EN 15 +#define GCC_GP1_CLK 16 +#define GCC_GP1_CLK_SRC 17 +#define GCC_GP2_CLK 18 +#define GCC_GP2_CLK_SRC 19 +#define GCC_GP3_CLK 20 +#define GCC_GP3_CLK_SRC 21 +#define GCC_PCIE_0_CLKREF_EN 22 +#define GCC_PCIE_AUX_CLK 23 +#define GCC_PCIE_AUX_CLK_SRC 24 +#define GCC_PCIE_AUX_PHY_CLK_SRC 25 +#define GCC_PCIE_CFG_AHB_CLK 26 +#define GCC_PCIE_MSTR_AXI_CLK 27 +#define GCC_PCIE_PIPE_CLK 28 +#define GCC_PCIE_PIPE_CLK_SRC 29 +#define GCC_PCIE_RCHNG_PHY_CLK 30 +#define GCC_PCIE_RCHNG_PHY_CLK_SRC 31 +#define GCC_PCIE_SLEEP_CLK 32 +#define GCC_PCIE_SLV_AXI_CLK 33 +#define GCC_PCIE_SLV_Q2A_AXI_CLK 34 +#define GCC_PDM2_CLK 35 +#define GCC_PDM2_CLK_SRC 36 +#define GCC_PDM_AHB_CLK 37 +#define GCC_PDM_XO4_CLK 38 +#define GCC_QUPV3_WRAP0_CORE_2X_CLK 39 +#define GCC_QUPV3_WRAP0_CORE_CLK 40 +#define GCC_QUPV3_WRAP0_S0_CLK 41 +#define GCC_QUPV3_WRAP0_S0_CLK_SRC 42 +#define GCC_QUPV3_WRAP0_S1_CLK 43 +#define GCC_QUPV3_WRAP0_S1_CLK_SRC 44 +#define GCC_QUPV3_WRAP0_S2_CLK 45 +#define GCC_QUPV3_WRAP0_S2_CLK_SRC 46 +#define GCC_QUPV3_WRAP0_S3_CLK 47 +#define GCC_QUPV3_WRAP0_S3_CLK_SRC 48 +#define GCC_QUPV3_WRAP0_S4_CLK 49 +#define GCC_QUPV3_WRAP0_S4_CLK_SRC 50 +#define GCC_QUPV3_WRAP_0_M_AHB_CLK 51 +#define GCC_QUPV3_WRAP_0_S_AHB_CLK 52 +#define GCC_SDCC4_AHB_CLK 53 +#define GCC_SDCC4_APPS_CLK 54 +#define GCC_SDCC4_APPS_CLK_SRC 55 +#define GCC_SNOC_CNOC_USB3_CLK 56 +#define GCC_SYS_NOC_USB_SF_AXI_CLK 57 +#define GCC_USB20_MASTER_CLK 58 +#define GCC_USB20_MASTER_CLK_SRC 59 +#define GCC_USB20_MOCK_UTMI_CLK 60 +#define GCC_USB20_MOCK_UTMI_CLK_SRC 61 +#define GCC_USB20_MOCK_UTMI_POSTDIV_CLK_SRC 62 +#define GCC_USB20_SLEEP_CLK 63 +#define GCC_USB2_CLKREF_EN 64 +#define GCC_USB3_PRIM_CLKREF_EN 65 +#define GCC_USB_PHY_CFG_AHB2PHY_CLK 66 +#define GCC_BOOT_ROM_AHB_CLK 68 + +/* GCC power domains */ +#define GCC_EMAC0_GDSC 0 +#define GCC_PCIE_GDSC 1 +#define GCC_USB20_GDSC 2 + +/* GCC resets */ +#define GCC_EMAC0_BCR 0 +#define GCC_PCIE_BCR 1 +#define GCC_PCIE_LINK_DOWN_BCR 2 +#define GCC_PCIE_NOCSR_COM_PHY_BCR 3 +#define GCC_PCIE_PHY_BCR 4 +#define GCC_PCIE_PHY_CFG_AHB_BCR 5 +#define GCC_PCIE_PHY_COM_BCR 6 +#define GCC_PCIE_PHY_NOCSR_COM_PHY_BCR 7 +#define GCC_PDM_BCR 8 +#define GCC_QUPV3_WRAPPER_0_BCR 9 +#define GCC_QUSB2PHY_BCR 10 +#define GCC_SDCC4_BCR 11 +#define GCC_TCSR_PCIE_BCR 12 +#define GCC_USB20_BCR 13 +#define GCC_USB_PHY_CFG_AHB2PHY_BCR 14 + +#endif diff --git a/include/dt-bindings/clock/qcom,nord-negcc.h b/include/dt-bindings/clock/qcom,nord-negcc.h index a7024317e90b..ad9ff389956d 100644 --- a/include/dt-bindings/clock/qcom,nord-negcc.h +++ b/include/dt-bindings/clock/qcom,nord-negcc.h @@ -121,5 +121,6 @@ #define NE_GCC_USB3PHY_PHY_PRIM_BCR 11 #define NE_GCC_USB3PHY_PHY_SEC_BCR 12 #define NE_GCC_QUSB2PHY_PRIM_BCR 13 +#define NE_GCC_QUSB2PHY_SEC_BCR 14 #endif diff --git a/include/dt-bindings/clock/qcom,nord-segcc.h b/include/dt-bindings/clock/qcom,nord-segcc.h index f0f7422af692..de4539b99985 100644 --- a/include/dt-bindings/clock/qcom,nord-segcc.h +++ b/include/dt-bindings/clock/qcom,nord-segcc.h @@ -84,6 +84,8 @@ #define SE_GCC_QUPV3_WRAP1_S6_CLK 74 #define SE_GCC_QUPV3_WRAP1_S6_CLK_SRC 75 #define SE_GCC_QUPV3_WRAP1_S_AHB_CLK 76 +#define SE_GCC_EMAC0_CNOC_APB_CLK 77 +#define SE_GCC_EMAC1_CNOC_APB_CLK 78 /* SE_GCC power domains */ #define SE_GCC_EMAC0_GDSC 0 diff --git a/include/dt-bindings/clock/qcom,qcs8300-gcc.h b/include/dt-bindings/clock/qcom,qcs8300-gcc.h index a0083b1d2126..3c674c7baaba 100644 --- a/include/dt-bindings/clock/qcom,qcs8300-gcc.h +++ b/include/dt-bindings/clock/qcom,qcs8300-gcc.h @@ -191,6 +191,11 @@ #define GCC_VIDEO_AXI0_CLK 181 #define GCC_VIDEO_AXI1_CLK 182 #define GCC_VIDEO_XO_CLK 183 +#define GCC_GPLL5 184 +#define GCC_TSCSS_AHB_CLK 185 +#define GCC_TSCSS_CNTR_CLK_SRC 186 +#define GCC_TSCSS_ETU_CLK 187 +#define GCC_TSCSS_GLOBAL_CNTR_CLK 188 /* GCC power domains */ #define GCC_EMAC0_GDSC 0 @@ -230,5 +235,6 @@ #define GCC_VIDEO_BCR 26 #define GCC_VIDEO_AXI0_CLK_ARES 27 #define GCC_VIDEO_AXI1_CLK_ARES 28 +#define GCC_TSCSS_BCR 29 #endif diff --git a/include/dt-bindings/clock/samsung,exynos5515-cmu.h b/include/dt-bindings/clock/samsung,exynos5515-cmu.h new file mode 100644 index 000000000000..2877d3681b55 --- /dev/null +++ b/include/dt-bindings/clock/samsung,exynos5515-cmu.h @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2026 Aiden Isik + * Author: Aiden Isik + * + * Device Tree binding constants for Exynos5515 clock controller. + */ + +#ifndef _DT_BINDINGS_CLOCK_EXYNOS5515_H +#define _DT_BINDINGS_CLOCK_EXYNOS5515_H + +/* CMU_TOP */ +#define CLK_FOUT_AUD_PLL 1 +#define CLK_FOUT_SHARED0_PLL 2 +#define CLK_FOUT_SHARED1_PLL 3 + +#define CLK_MOUT_CMU_APM_BUS 4 +#define CLK_MOUT_CMU_CORE_BUS 5 +#define CLK_MOUT_CMU_CORE_SSS 6 +#define CLK_MOUT_CMU_CPUCL0_BUSP 7 +#define CLK_MOUT_CMU_CPUCL0_CPU 8 +#define CLK_MOUT_CMU_CPUCL0_DBG 9 +#define CLK_MOUT_CMU_DPU_AUDIF 10 +#define CLK_MOUT_CMU_DPU_AUD_BUS 11 +#define CLK_MOUT_CMU_DPU_AUD_CPU 12 +#define CLK_MOUT_CMU_DPU_BUS 13 +#define CLK_MOUT_CMU_FSYS_BUS 14 +#define CLK_MOUT_CMU_FSYS_MMC_CARD 15 +#define CLK_MOUT_CMU_FSYS_MMC_EMBD 16 +#define CLK_MOUT_CMU_FSYS_USB20DRD 17 +#define CLK_MOUT_CMU_G3D_BUS 18 +#define CLK_MOUT_CMU_MFC_BUS 19 +#define CLK_MOUT_CMU_MIF_BUSP 20 +#define CLK_MOUT_CMU_MIF_SWITCH 21 +#define CLK_MOUT_CMU_MODEM_SHARED1 22 +#define CLK_MOUT_CMU_PERI_BUS 23 +#define CLK_MOUT_CMU_PERI_IP 24 +#define CLK_MOUT_CMU_PERI_UART 25 +#define CLK_MOUT_CMU_CMUREF 26 + +#define CLK_DOUT_AP2CP_SHARED0_PLL 27 +#define CLK_DOUT_AP2CP_SHARED1_PLL 28 +#define CLK_DOUT_AP2CP_SHARED2_PLL 29 +#define CLK_DOUT_CMU_APM_BUS 30 +#define CLK_DOUT_CMU_CMU_BOOST 31 +#define CLK_DOUT_CMU_CORE_BUS 32 +#define CLK_DOUT_CMU_CORE_SSS 33 +#define CLK_DOUT_CMU_CPUCL0_BUSP 34 +#define CLK_DOUT_CMU_CPUCL0_CPU 35 +#define CLK_DOUT_CMU_CPUCL0_DBG 36 +#define CLK_DOUT_CMU_DPU_AUDIF 37 +#define CLK_DOUT_CMU_DPU_AUD_BUS 38 +#define CLK_DOUT_CMU_DPU_AUD_CPU 39 +#define CLK_DOUT_CMU_DPU_BUS 40 +#define CLK_DOUT_CMU_FSYS_BUS 41 +#define CLK_DOUT_CMU_FSYS_MMC_CARD 42 +#define CLK_DOUT_CMU_FSYS_MMC_EMBD 43 +#define CLK_DOUT_CMU_FSYS_USB20DRD 44 +#define CLK_DOUT_CMU_G3D_BUS 45 +#define CLK_DOUT_CMU_MFC_BUS 46 +#define CLK_DOUT_CMU_MIF_BUSP 47 +#define CLK_DOUT_CMU_PERI_BUS 48 +#define CLK_DOUT_CMU_PERI_IP 49 +#define CLK_DOUT_CMU_PERI_UART 50 +#define CLK_DOUT_CMU_CMUREF 51 + +#define CLK_DOUT_SHARED0_DIV2 52 +#define CLK_DOUT_SHARED0_DIV3 53 +#define CLK_DOUT_SHARED0_DIV4 54 +#define CLK_DOUT_SHARED1_DIV2 55 +#define CLK_DOUT_SHARED1_DIV3 56 +#define CLK_DOUT_SHARED1_DIV4 57 +#define CLK_DOUT_AUD_DIV2 58 +#define CLK_DOUT_AUD_DIV3 59 +#define CLK_DOUT_AUD_DIV4 60 + +#define CLK_GOUT_CMU_MIF_SWITCH 61 +#define CLK_GOUT_CMU_APM_BUS 62 +#define CLK_GOUT_CMU_CORE_BUS 63 +#define CLK_GOUT_CMU_CORE_SSS 64 +#define CLK_GOUT_CMU_CPUCL0_BUSP 65 +#define CLK_GOUT_CMU_CPUCL0_CPU 66 +#define CLK_GOUT_CMU_CPUCL0_DBG 67 +#define CLK_GOUT_CMU_DPU_AUDIF 68 +#define CLK_GOUT_CMU_DPU_AUD_BUS 69 +#define CLK_GOUT_CMU_DPU_AUD_CPU 70 +#define CLK_GOUT_CMU_DPU_BUS 71 +#define CLK_GOUT_CMU_FSYS_BUS 72 +#define CLK_GOUT_CMU_FSYS_MMC_CARD 73 +#define CLK_GOUT_CMU_FSYS_MMC_EMBD 74 +#define CLK_GOUT_CMU_FSYS_USB20DRD 75 +#define CLK_GOUT_CMU_G3D_BUS 76 +#define CLK_GOUT_CMU_MFC_BUS 77 +#define CLK_GOUT_CMU_MIF_BUSP 78 +#define CLK_GOUT_CMU_MODEM_SHARED0 79 +#define CLK_GOUT_CMU_MODEM_SHARED1 80 +#define CLK_GOUT_CMU_MODEM_SHARED2 81 +#define CLK_GOUT_CMU_PERI_BUS 82 +#define CLK_GOUT_CMU_PERI_IP 83 +#define CLK_GOUT_CMU_PERI_UART 84 + +/* CMU_PERI */ +#define CLK_MOUT_PLL_PERI_BUS_USER 1 +#define CLK_MOUT_PLL_PERI_IP_USER 2 +#define CLK_MOUT_PLL_PERI_UART_USER 3 +#define CLK_MOUT_PERI_SPI 4 +#define CLK_MOUT_PERI_USI00_USI 5 + +#define CLK_DOUT_PERI_OTP 6 + +#define CLK_DOUT_PERI_I2C_0 7 +#define CLK_DOUT_PERI_I2C_1 8 +#define CLK_DOUT_PERI_I2C_2 9 +#define CLK_DOUT_PERI_I2C_3 10 +#define CLK_DOUT_PERI_SPI 11 +#define CLK_DOUT_PERI_USI00_I2C 12 +#define CLK_DOUT_PERI_USI00_USI 13 + +#define CLK_GOUT_PERI_BUSIF_TMU_PCLK 14 +#define CLK_GOUT_PERI_D_TZPC_PCLK 15 +#define CLK_GOUT_PERI_GPIO_PCLK 16 +#define CLK_GOUT_PERI_I2C_0_IPCLK 17 +#define CLK_GOUT_PERI_I2C_0_PCLK 18 +#define CLK_GOUT_PERI_I2C_1_IPCLK 19 +#define CLK_GOUT_PERI_I2C_1_PCLK 20 +#define CLK_GOUT_PERI_I2C_2_IPCLK 21 +#define CLK_GOUT_PERI_I2C_2_PCLK 22 +#define CLK_GOUT_PERI_I2C_3_IPCLK 23 +#define CLK_GOUT_PERI_I2C_3_PCLK 24 +#define CLK_GOUT_PERI_MCT_PCLK 25 +#define CLK_GOUT_PERI_OTP_OSCCLK 26 +#define CLK_GOUT_PERI_OTP_PCLK 27 +#define CLK_GOUT_PERI_CMU_PCLK 28 +#define CLK_GOUT_PERI_PWM_MOTOR_PCLK 29 +#define CLK_GOUT_PERI_BUS_CLK 30 +#define CLK_GOUT_PERI_I2C_0_CLK 31 +#define CLK_GOUT_PERI_I2C_1_CLK 32 +#define CLK_GOUT_PERI_I2C_2_CLK 33 +#define CLK_GOUT_PERI_I2C_3_CLK 34 +#define CLK_GOUT_PERI_OSCCLK 35 +#define CLK_GOUT_PERI_SPI_CLK 36 +#define CLK_GOUT_PERI_UART_CLK 37 +#define CLK_GOUT_PERI_USI00_I2C_CLK 38 +#define CLK_GOUT_PERI_USI00_USI_CLK 39 +#define CLK_GOUT_PERI_SLH_AXI_MI_P_CLK 40 +#define CLK_GOUT_PERI_SYSREG_PCLK 41 +#define CLK_GOUT_PERI_USI00_I2C_IPCLK 42 +#define CLK_GOUT_PERI_USI00_I2C_PCLK 43 +#define CLK_GOUT_PERI_USI00_USI_IPCLK 44 +#define CLK_GOUT_PERI_USI00_USI_PCLK 45 +#define CLK_GOUT_PERI_USI_SPI_IPCLK 46 +#define CLK_GOUT_PERI_USI_SPI_PCLK 47 +#define CLK_GOUT_PERI_USI_UART_IPCLK 48 +#define CLK_GOUT_PERI_USI_UART_PCLK 49 +#define CLK_GOUT_PERI_WDT0_PCLK 50 +#define CLK_GOUT_PERI_WDT1_PCLK 51 +#define CLK_GOUT_PERI_I2C_0 52 +#define CLK_GOUT_PERI_I2C_1 53 +#define CLK_GOUT_PERI_I2C_2 54 +#define CLK_GOUT_PERI_I2C_3 55 +#define CLK_GOUT_PERI_USI00_I2C 56 + +/* CMU_FSYS */ +#define CLK_MOUT_PLL_FSYS_BUS_USER 1 +#define CLK_MOUT_PLL_FSYS_MMC_CARD_USER 2 +#define CLK_MOUT_PLL_FSYS_MMC_EMBD_USER 3 +#define CLK_MOUT_PLL_FSYS_USB20DRD_USER 4 + +#define CLK_GOUT_FSYS_CMU_PCLK 5 +#define CLK_GOUT_FSYS_MMC_CARD_SDCLKIN 6 +#define CLK_GOUT_FSYS_MMC_EMBD_SDCLKIN 7 +#define CLK_GOUT_FSYS_OSCCLK 8 +#define CLK_GOUT_FSYS_USB20DRD_REFCLK 9 +#define CLK_GOUT_FSYS_USB20DRD_PHY_REFCLK 10 +#define CLK_GOUT_FSYS_D_TZPC_PCLK 11 +#define CLK_GOUT_FSYS_GPIO_PCLK 12 +#define CLK_GOUT_FSYS_MMC_CARD_ACLK 13 +#define CLK_GOUT_FSYS_MMC_EMBD_ACLK 14 +#define CLK_GOUT_FSYS_PPMU_ACLK 15 +#define CLK_GOUT_FSYS_PPMU_PCLK 16 +#define CLK_GOUT_FSYS_BUS_CLK 17 +#define CLK_GOUT_FSYS_SLH_AXI_MI_P_CLK 18 +#define CLK_GOUT_FSYS_SLH_AXI_SI_D_CLK 19 +#define CLK_GOUT_FSYS_SYSREG_PCLK 20 +#define CLK_GOUT_FSYS_USB20DRD_ACLK_PHYCTRL 21 +#define CLK_GOUT_FSYS_USB20DRD_BUS_CLK_EARLY 22 +#define CLK_GOUT_FSYS_US_64TO128_ACLK 23 +#define CLK_GOUT_FSYS_XIU_D_ACLK 24 +#define CLK_GOUT_FSYS_XIU_P_ACLK 25 + +#endif /* _DT_BINDINGS_CLOCK_EXYNOS5515_H */ diff --git a/include/dt-bindings/clock/zte,zx297520v3-clk.h b/include/dt-bindings/clock/zte,zx297520v3-clk.h new file mode 100644 index 000000000000..a63283d5df5c --- /dev/null +++ b/include/dt-bindings/clock/zte,zx297520v3-clk.h @@ -0,0 +1,154 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) Stefan Dösinger. + */ + +#ifndef __DT_BINDINGS_CLOCK_ZX297520V3_H +#define __DT_BINDINGS_CLOCK_ZX297520V3_H + +#define ZX297520V3_M0_WCLK 0 +#define ZX297520V3_SRAM1_PCLK 1 +#define ZX297520V3_SRAM2_PCLK 2 +#define ZX297520V3_UART0_WCLK 3 +#define ZX297520V3_UART0_PCLK 4 +#define ZX297520V3_I2C0_WCLK 5 +#define ZX297520V3_I2C0_PCLK 6 +#define ZX297520V3_RTC_WCLK 7 +#define ZX297520V3_RTC_PCLK 8 +#define ZX297520V3_LPM_GSM_WCLK 9 +#define ZX297520V3_LPM_GSM_PCLK 10 +#define ZX297520V3_LPM_LTE_WCLK 11 +#define ZX297520V3_LPM_LTE_PCLK 12 +#define ZX297520V3_LPM_TD_WCLK 13 +#define ZX297520V3_LPM_TD_PCLK 14 +#define ZX297520V3_LPM_W_WCLK 15 +#define ZX297520V3_LPM_W_PCLK 16 +#define ZX297520V3_TIMER_T08_WCLK 17 +#define ZX297520V3_TIMER_T08_PCLK 18 +#define ZX297520V3_TIMER_T09_WCLK 19 +#define ZX297520V3_TIMER_T09_PCLK 20 +#define ZX297520V3_MPLL 21 +#define ZX297520V3_MPLL_D5 22 +#define ZX297520V3_DPLL 23 +#define ZX297520V3_GPLL 24 +#define ZX297520V3_GPLL_D2 25 +#define ZX297520V3_GATED_OSC26M 26 +#define ZX297520V3_PMM_WCLK 27 +#define ZX297520V3_PMM_PCLK 28 +#define ZX297520V3_OUT0_WCLK 29 +#define ZX297520V3_OUT1_WCLK 30 +#define ZX297520V3_OUT2_WCLK 31 +#define ZX297520V3_OUT32K_WCLK 32 +#define ZX297520V3_RMIIPHY_WCLK 33 +#define ZX297520V3_TIMER_T12_WCLK 34 +#define ZX297520V3_TIMER_T12_PCLK 35 +#define ZX297520V3_TIMER_T13_WCLK 36 +#define ZX297520V3_TIMER_T13_PCLK 37 +#define ZX297520V3_TIMER_T14_WCLK 38 +#define ZX297520V3_TIMER_T14_PCLK 39 +#define ZX297520V3_TIMER_T15_WCLK 40 +#define ZX297520V3_TIMER_T15_PCLK 41 +#define ZX297520V3_TIMER_T16_WCLK 42 +#define ZX297520V3_TIMER_T16_PCLK 43 +#define ZX297520V3_TIMER_T17_WCLK 44 +#define ZX297520V3_TIMER_T17_PCLK 45 +#define ZX297520V3_WDT_T18_WCLK 46 +#define ZX297520V3_WDT_T18_PCLK 47 +#define ZX297520V3_USIM1_WCLK 48 +#define ZX297520V3_USIM1_PCLK 49 +#define ZX297520V3_AHB_WCLK 50 +#define ZX297520V3_AHB_PCLK 51 +#define ZX297520V3_USB_WCLK 52 +#define ZX297520V3_USB_PCLK 53 +#define ZX297520V3_HSIC_WCLK 54 +#define ZX297520V3_HSIC_PCLK 55 +#define ZX297520V3_GSM_32K 56 +#define ZX297520V3_GSM_26M 57 +#define ZX297520V3_GSM_48M 58 +#define ZX297520V3_GSM_104M 59 +#define ZX297520V3_GSM_156M 60 +#define ZX297520V3_ABB_WCLK 61 + +#define ZX297520V3_SYS_TIMER_WCLK 0 +#define ZX297520V3_CPU_WCLK 1 +#define ZX297520V3_CPU_PCLK 2 +#define ZX297520V3_ZSP_WCLK 3 +#define ZX297520V3_ZSP_PCLK 4 +#define ZX297520V3_DDR_CTRL_PCLK 5 +#define ZX297520V3_DDR_CTRL_WCLK 6 +#define ZX297520V3_EDCP_WCLK 7 +#define ZX297520V3_EDCP_PCLK 8 +#define ZX297520V3_SD0_WCLK 9 +#define ZX297520V3_SD0_PCLK 10 +#define ZX297520V3_SD0_CDET 11 +#define ZX297520V3_SD1_WCLK 12 +#define ZX297520V3_SD1_PCLK 13 +#define ZX297520V3_SD1_CDET 14 +#define ZX297520V3_NAND_WCLK 15 +#define ZX297520V3_NAND_PCLK 16 +#define ZX297520V3_DMA_PCLK 17 +#define ZX297520V3_MBOX_PCLK 18 +#define ZX297520V3_PDCFG_WCLK 19 +#define ZX297520V3_PDCFG_PCLK 20 +#define ZX297520V3_RFFE_WCLK 21 +#define ZX297520V3_SSC_WCLK 22 +#define ZX297520V3_SSC_PCLK 23 +#define ZX297520V3_AXI_WCLK 24 +#define ZX297520V3_GMAC_WCLK 25 +#define ZX297520V3_GMAC_PCLK 26 +#define ZX297520V3_GMAC_AHB 27 +#define ZX297520V3_VOU_WCLK 28 +#define ZX297520V3_VOU_PCLK 29 +#define ZX297520V3_LSP_MPLL_D5_WCLK 30 +#define ZX297520V3_LSP_MPLL_D4_WCLK 31 +#define ZX297520V3_LSP_MPLL_D6_WCLK 32 +#define ZX297520V3_LSP_MPLL_D8_WCLK 33 +#define ZX297520V3_LSP_MPLL_D12_WCLK 34 +#define ZX297520V3_LSP_OSC26M_WCLK 35 +#define ZX297520V3_LSP_OSC32K_WCLK 36 +#define ZX297520V3_LSP_PCLK 37 +#define ZX297520V3_LSP_TDM_WCLK 38 +#define ZX297520V3_LSP_DPLL_D4_WCLK 39 +#define ZX297520V3_SRAM0_PCLK 40 +#define ZX297520V3_GSM_CFG_PCLK 41 +#define ZX297520V3_LTE_MODEM_WCLK 42 +#define ZX297520V3_LTE_MODEM_PCLK 43 + +#define ZX297520V3_TIMER_L1_WCLK 0 +#define ZX297520V3_TIMER_L1_PCLK 1 +#define ZX297520V3_WDT_L2_WCLK 2 +#define ZX297520V3_WDT_L2_PCLK 3 +#define ZX297520V3_WDT_L3_WCLK 4 +#define ZX297520V3_WDT_L3_PCLK 5 +#define ZX297520V3_PWM_WCLK 6 +#define ZX297520V3_PWM_PCLK 7 +#define ZX297520V3_I2S0_WCLK 8 +#define ZX297520V3_I2S0_PCLK 9 +#define ZX297520V3_I2S1_WCLK 10 +#define ZX297520V3_I2S1_PCLK 11 +#define ZX297520V3_QSPI_WCLK 12 +#define ZX297520V3_QSPI_PCLK 13 +#define ZX297520V3_UART1_WCLK 14 +#define ZX297520V3_UART1_PCLK 15 +#define ZX297520V3_I2C1_WCLK 16 +#define ZX297520V3_I2C1_PCLK 17 +#define ZX297520V3_SPI0_WCLK 18 +#define ZX297520V3_SPI0_PCLK 19 +#define ZX297520V3_TIMER_LB_WCLK 20 +#define ZX297520V3_TIMER_LB_PCLK 21 +#define ZX297520V3_TIMER_LC_WCLK 22 +#define ZX297520V3_TIMER_LC_PCLK 23 +#define ZX297520V3_UART2_WCLK 24 +#define ZX297520V3_UART2_PCLK 25 +#define ZX297520V3_WDT_LE_WCLK 26 +#define ZX297520V3_WDT_LE_PCLK 27 +#define ZX297520V3_TIMER_LF_WCLK 28 +#define ZX297520V3_TIMER_LF_PCLK 29 +#define ZX297520V3_SPI1_WCLK 30 +#define ZX297520V3_SPI1_PCLK 31 +#define ZX297520V3_TIMER_L11_WCLK 32 +#define ZX297520V3_TIMER_L11_PCLK 33 +#define ZX297520V3_TDM_WCLK 34 +#define ZX297520V3_TDM_PCLK 35 + +#endif /* __DT_BINDINGS_CLOCK_ZX297520V3_H */ diff --git a/include/dt-bindings/phy/zte,zx297520v3-topcrm.h b/include/dt-bindings/phy/zte,zx297520v3-topcrm.h new file mode 100644 index 000000000000..b36ccf2f54ef --- /dev/null +++ b/include/dt-bindings/phy/zte,zx297520v3-topcrm.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) Stefan Dösinger. + */ + +#ifndef __DT_BINDINGS_PHY_ZTE_ZX297520V3_TOPCRM_H +#define __DT_BINDINGS_PHY_ZTE_ZX297520V3_TOPCRM_H + +#define ZX297520V3_USB_PHY 0 +#define ZX297520V3_HSIC_PHY 1 + +#endif /* __DT_BINDINGS_PHY_ZTE_ZX297520V3_TOPCRM_H */ diff --git a/include/dt-bindings/reset/anlogic,dr1v90-cru.h b/include/dt-bindings/reset/anlogic,dr1v90-cru.h new file mode 100644 index 000000000000..c5b7aae1ab6a --- /dev/null +++ b/include/dt-bindings/reset/anlogic,dr1v90-cru.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2025 Junhui Liu + */ + +#ifndef _DT_BINDINGS_RESET_ANLOGIC_DR1V90_CRU_H_ +#define _DT_BINDINGS_RESET_ANLOGIC_DR1V90_CRU_H_ + +#define RESET_OCM 0 +#define RESET_QSPI 1 +#define RESET_SMC 2 +#define RESET_WDT 3 +#define RESET_DMAC_AXI 4 +#define RESET_DMAC_AHB 5 +#define RESET_NPU 6 +#define RESET_JPU 7 +#define RESET_DDRBUS 8 +#define RESET_NIC_HP0 9 +#define RESET_NIC_HP1 10 +#define RESET_NIC_GP0M 11 +#define RESET_NIC_GP1M 12 +#define RESET_GPIO 13 +#define RESET_IPC 14 +#define RESET_USB0 15 +#define RESET_USB1 16 +#define RESET_GBE0 17 +#define RESET_GBE1 18 +#define RESET_SDIO0 19 +#define RESET_SDIO1 20 +#define RESET_UART0 21 +#define RESET_UART1 22 +#define RESET_SPI0 23 +#define RESET_SPI1 24 +#define RESET_CAN0 25 +#define RESET_CAN1 26 +#define RESET_TTC0 27 +#define RESET_TTC1 28 +#define RESET_I2C0 29 +#define RESET_I2C1 30 + +#endif /* _DT_BINDINGS_RESET_ANLOGIC_DR1V90_CRU_H_ */ diff --git a/include/dt-bindings/reset/zte,zx297520v3-reset.h b/include/dt-bindings/reset/zte,zx297520v3-reset.h new file mode 100644 index 000000000000..b21d5901a7b9 --- /dev/null +++ b/include/dt-bindings/reset/zte,zx297520v3-reset.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) Stefan Dösinger. + */ + +#ifndef __DT_BINDINGS_RESET_ZX297520V3_H +#define __DT_BINDINGS_RESET_ZX297520V3_H + +#define ZX297520V3_ZSP_CORE_RESET 0 +#define ZX297520V3_UART0_RESET 1 +#define ZX297520V3_I2C0_RESET 2 +#define ZX297520V3_RTC_RESET 3 +#define ZX297520V3_TIMER_T08_RESET 4 +#define ZX297520V3_TIMER_T09_RESET 5 +#define ZX297520V3_PMM_RESET 6 +#define ZX297520V3_GPIO_RESET 7 +#define ZX297520V3_GPIO8_RESET 8 +#define ZX297520V3_TIMER_T12_RESET 9 +#define ZX297520V3_TIMER_T13_RESET 10 +#define ZX297520V3_TIMER_T14_RESET 11 +#define ZX297520V3_TIMER_T15_RESET 12 +#define ZX297520V3_TIMER_T16_RESET 13 +#define ZX297520V3_TIMER_T17_RESET 14 +#define ZX297520V3_WDT_T18_RESET 15 +#define ZX297520V3_USIM1_RESET 16 +#define ZX297520V3_AHB_RESET 17 +#define ZX297520V3_USB_RESET 18 +#define ZX297520V3_HSIC_RESET 19 + +#define ZX297520V3_CPU_RESET 0 +#define ZX297520V3_ZSP_BUS_RESET 1 +#define ZX297520V3_DDR_CTRL_RESET 2 +#define ZX297520V3_EDCP_RESET 3 +#define ZX297520V3_SD0_RESET 4 +#define ZX297520V3_SD1_RESET 5 +#define ZX297520V3_NAND_RESET 6 +#define ZX297520V3_PDCFG_RESET 7 +#define ZX297520V3_SSC_RESET 8 +#define ZX297520V3_GMAC_RESET 9 +#define ZX297520V3_VOU_RESET 10 +#define ZX297520V3_LSP_RESET 11 + +#define ZX297520V3_TIMER_L1_RESET 0 +#define ZX297520V3_WDT_L2_RESET 1 +#define ZX297520V3_WDT_L3_RESET 2 +#define ZX297520V3_PWM_RESET 3 +#define ZX297520V3_I2S0_RESET 4 +#define ZX297520V3_I2S1_RESET 5 +#define ZX297520V3_QSPI_RESET 6 +#define ZX297520V3_UART1_RESET 7 +#define ZX297520V3_I2C1_RESET 8 +#define ZX297520V3_SPI0_RESET 9 +#define ZX297520V3_TIMER_LB_RESET 10 +#define ZX297520V3_TIMER_LC_RESET 11 +#define ZX297520V3_UART2_RESET 12 +#define ZX297520V3_WDT_LE_RESET 13 +#define ZX297520V3_TIMER_LF_RESET 14 +#define ZX297520V3_SPI1_RESET 15 +#define ZX297520V3_TIMER_L11_RESET 16 +#define ZX297520V3_TDM_RESET 17 + +#endif /* __DT_BINDINGS_RESET_ZX297520V3_H */ diff --git a/include/dt-bindings/soc/airoha,scu-ssr.h b/include/dt-bindings/soc/airoha,scu-ssr.h new file mode 100644 index 000000000000..33c64844ada3 --- /dev/null +++ b/include/dt-bindings/soc/airoha,scu-ssr.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef __DT_BINDINGS_AIROHA_SCU_SSR_H +#define __DT_BINDINGS_AIROHA_SCU_SSR_H + +#define AIROHA_SCU_SERDES_PCIE1 0 +#define AIROHA_SCU_SERDES_PCIE2 1 +#define AIROHA_SCU_SERDES_USB1 2 +#define AIROHA_SCU_SERDES_USB2 3 + +#endif /* __DT_BINDINGS_AIROHA_SCU_SSR_H */ diff --git a/include/kunit/clk.h b/include/kunit/clk.h index f226044cc78d..0b5ab8e971c9 100644 --- a/include/kunit/clk.h +++ b/include/kunit/clk.h @@ -29,5 +29,7 @@ int of_clk_hw_register_kunit(struct kunit *test, struct device_node *node, int of_clk_add_hw_provider_kunit(struct kunit *test, struct device_node *np, struct clk_hw *(*get)(struct of_phandle_args *clkspec, void *data), void *data); +struct device_node *clk_of_find_node_by_name_kunit(struct kunit *test, struct device_node *from, + const char *name); #endif diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index dc8e161f9c2c..a355d1ee5189 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -7,6 +7,7 @@ #define __LINUX_CLK_PROVIDER_H #include +#include #include #include @@ -50,6 +51,7 @@ struct clk; struct clk_hw; struct clk_core; struct dentry; +struct module; /** * struct clk_rate_request - Structure encoding the clk constraints that @@ -351,8 +353,9 @@ struct clk_init_data { * @core: pointer to the struct clk_core instance that points back to this * struct clk_hw instance * - * @clk: pointer to the per-user struct clk instance that can be used to call - * into the clk API + * @clk: pointer to the per-user struct clk instance. This will be removed at + * some point in the future, Please consider the field obsolete and do not use + * it. Use clk_hw_get_clk() to get a per-user struct clk from a struct clk_hw. * * @init: pointer to struct clk_init_data that contains the init data shared * with the common clock framework. This pointer will be set to NULL once @@ -755,7 +758,7 @@ struct clk_divider { spinlock_t *lock; }; -#define clk_div_mask(width) ((1 << (width)) - 1) +#define clk_div_mask(width) GENMASK((width) - 1, 0) #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) #define CLK_DIVIDER_ONE_BASED BIT(0) @@ -1474,10 +1477,24 @@ static inline struct clk_hw *__clk_get_hw(struct clk *clk) } #endif -struct clk *clk_hw_get_clk(struct clk_hw *hw, const char *con_id); +struct clk *__clk_hw_get_clk(struct clk_hw *hw, const char *con_id, + struct module *owner); struct clk *devm_clk_hw_get_clk(struct device *dev, struct clk_hw *hw, const char *con_id); +/** + * clk_hw_get_clk - get clk consumer given a clk_hw + * @hw: clk_hw associated with the clk being consumed + * @con_id: connection ID string on device + * + * Return: new clk consumer + * This is the function to be used by providers which need + * to get a consumer clk and act on the clock element + * Calls to this function must be balanced with calls to clk_put() + */ +#define clk_hw_get_clk(hw, con_id) \ + __clk_hw_get_clk((hw), (con_id), THIS_MODULE) + unsigned int clk_hw_get_num_parents(const struct clk_hw *hw); struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw); struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw, diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h index 3650e926e93f..f1034e14c1a4 100644 --- a/include/linux/clk/tegra.h +++ b/include/linux/clk/tegra.h @@ -170,7 +170,7 @@ struct tegra210_clk_emc_provider { struct module *owner; struct device *dev; - struct tegra210_clk_emc_config *configs; + struct tegra210_clk_emc_config *configs __counted_by_ptr(num_configs); unsigned int num_configs; int (*set_rate)(struct device *dev, diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index 54a3fa370004..61c4abf19995 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -51,7 +51,7 @@ struct clk_omap_reg { * @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg * @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg * @dcc_mask: mask of the DPLL DCC correction bitfield @mult_div1_reg - * @dcc_rate: rate atleast which DCC @dcc_mask must be set + * @dcc_rate: rate at least which DCC @dcc_mask must be set * @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg * @lpmode_mask: mask of the DPLL low-power mode bitfield in @control_reg * @m4xen_mask: mask of the DPLL M4X multiplier bitfield in @control_reg diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h index 768a1334c0a1..29fbc01ef06f 100644 --- a/include/linux/device/driver.h +++ b/include/linux/device/driver.h @@ -297,4 +297,35 @@ static int __init __driver##_init(void) \ } \ device_initcall(__driver##_init); +/** + * subsys_driver() - Helper macro for drivers that don't do anything special + * in init/exit but have to register earlier, at subsys_initcall level, when + * built in. This eliminates a lot of boilerplate. Each driver may only use + * this macro once, and calling it replaces the init/exit boilerplate. + * + * @__driver: driver name + * @__register: register function for this driver type + * @__unregister: unregister function for this driver type + * @...: Additional arguments to be passed to __register and __unregister. + * + * This is meant to be a direct parallel of module_driver() above, but with + * the init call promoted to subsys_initcall() for built-in drivers so they + * are available earlier during boot. When built as a module subsys_initcall() + * collapses to module_init() and the normal module init/exit paths are used. + * + * Use this macro to construct bus specific macros for registering drivers, + * and do not use it on its own. + */ +#define subsys_driver(__driver, __register, __unregister, ...) \ +static int __init __driver##_init(void) \ +{ \ + return __register(&(__driver), ##__VA_ARGS__); \ +} \ +subsys_initcall(__driver##_init) \ +static void __exit __driver##_exit(void) \ +{ \ + __unregister(&(__driver), ##__VA_ARGS__); \ +} \ +module_exit(__driver##_exit) + #endif /* _DEVICE_DRIVER_H_ */ diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 3d5bbcbae730..3bd0f1f0d870 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -344,6 +344,19 @@ static inline void platform_set_drvdata(struct platform_device *pdev, #define builtin_platform_driver(__platform_driver) \ builtin_driver(__platform_driver, platform_driver_register) +/* + * subsys_platform_driver() - Helper macro for drivers that don't do anything + * special in module init/exit but need to register earlier, at + * subsys_initcall level, when built in. This eliminates a lot of + * boilerplate. Each driver may only use this macro once, and calling it + * replaces module_init() and module_exit(). This is meant to be a parallel + * of module_platform_driver() above, but with the init call promoted to + * subsys_initcall() so built-in providers are available earlier during boot. + */ +#define subsys_platform_driver(__platform_driver) \ + subsys_driver(__platform_driver, platform_driver_register, \ + platform_driver_unregister) + /* module_platform_driver_probe() - Helper macro for drivers that don't do * anything special in module init/exit. This eliminates a lot of * boilerplate. Each module may only use this macro once, and @@ -376,6 +389,23 @@ static int __init __platform_driver##_init(void) \ } \ device_initcall(__platform_driver##_init); \ +/* + * subsys_platform_driver_probe() - Helper macro for drivers that don't do + * anything special in device init and have no exit, but need to register + * earlier, at subsys_initcall level. This eliminates some boilerplate. Each + * driver may only use this macro once, and using it replaces subsys_initcall. + * This is meant to be a parallel of builtin_platform_driver_probe above, but + * with the init call promoted to subsys_initcall so the provider is available + * earlier during boot. + */ +#define subsys_platform_driver_probe(__platform_driver, __platform_probe) \ +static int __init __platform_driver##_init(void) \ +{ \ + return platform_driver_probe(&(__platform_driver), \ + __platform_probe); \ +} \ +subsys_initcall(__platform_driver##_init) \ + #define platform_create_bundle(driver, probe, res, n_res, data, size) \ __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE, KBUILD_MODNAME) extern struct platform_device *__platform_create_bundle( diff --git a/rust/kernel/clk.rs b/rust/kernel/clk.rs index 7abbd0767d8c..f04f5c4a03d6 100644 --- a/rust/kernel/clk.rs +++ b/rust/kernel/clk.rs @@ -35,16 +35,31 @@ impl Hertz { const GHZ_TO_HZ: c_ulong = 1_000_000_000; /// Create a new instance from kilohertz (kHz) + /// + /// # Panics + /// + /// Panics if `CONFIG_RUST_OVERFLOW_CHECKS` is enabled and `khz` is greater + /// than `c_ulong::MAX / 1_000`. pub const fn from_khz(khz: c_ulong) -> Self { Self(khz * Self::KHZ_TO_HZ) } /// Create a new instance from megahertz (MHz) + /// + /// # Panics + /// + /// Panics if `CONFIG_RUST_OVERFLOW_CHECKS` is enabled and `mhz` is greater + /// than `c_ulong::MAX / 1_000_000`. pub const fn from_mhz(mhz: c_ulong) -> Self { Self(mhz * Self::MHZ_TO_HZ) } /// Create a new instance from gigahertz (GHz) + /// + /// # Panics + /// + /// Panics if `CONFIG_RUST_OVERFLOW_CHECKS` is enabled and `ghz` is greater + /// than `c_ulong::MAX / 1_000_000_000`. pub const fn from_ghz(ghz: c_ulong) -> Self { Self(ghz * Self::GHZ_TO_HZ) }