From 5437753728ac40a0410f3a4c6c471d0ab9919ceb Mon Sep 17 00:00:00 2001 From: Jian Hu Date: Fri, 12 Dec 2025 10:26:14 +0800 Subject: [PATCH 001/165] dt-bindings: clock: add Amlogic T7 PLL clock controller Add DT bindings for the PLL clock controller of the Amlogic T7 SoC family. Signed-off-by: Jian Hu Reviewed-by: Conor Dooley Link: https://lore.kernel.org/r/20251212022619.3072132-2-jian.hu@amlogic.com Signed-off-by: Jerome Brunet --- .../bindings/clock/amlogic,t7-pll-clkc.yaml | 114 ++++++++++++++++++ .../dt-bindings/clock/amlogic,t7-pll-clkc.h | 56 +++++++++ 2 files changed, 170 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/amlogic,t7-pll-clkc.yaml create mode 100644 include/dt-bindings/clock/amlogic,t7-pll-clkc.h diff --git a/Documentation/devicetree/bindings/clock/amlogic,t7-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,t7-pll-clkc.yaml new file mode 100644 index 000000000000..49c61f65deff --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,t7-pll-clkc.yaml @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/amlogic,t7-pll-clkc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic T7 PLL Clock Control Controller + +maintainers: + - Neil Armstrong + - Jerome Brunet + - Jian Hu + - Xianwei Zhao + +properties: + compatible: + enum: + - amlogic,t7-gp0-pll + - amlogic,t7-gp1-pll + - amlogic,t7-hifi-pll + - amlogic,t7-pcie-pll + - amlogic,t7-mpll + - amlogic,t7-hdmi-pll + - amlogic,t7-mclk-pll + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + + clocks: + items: + - description: mclk pll input oscillator gate + - description: oscillator input clock source for mclk_sel_0 + - description: fixed input clock source for mclk_sel_0 + minItems: 1 + + clock-names: + items: + - const: in0 + - const: in1 + - const: in2 + minItems: 1 + +required: + - compatible + - '#clock-cells' + - reg + - clocks + - clock-names + +allOf: + - if: + properties: + compatible: + contains: + const: amlogic,t7-mclk-pll + + then: + properties: + clocks: + minItems: 3 + + clock-names: + minItems: 3 + + - if: + properties: + compatible: + contains: + enum: + - amlogic,t7-gp0-pll + - amlogic,t7-gp1--pll + - amlogic,t7-hifi-pll + - amlogic,t7-pcie-pll + - amlogic,t7-mpll + - amlogic,t7-hdmi-pll + + then: + properties: + clocks: + maxItems: 1 + + clock-names: + maxItems: 1 + +additionalProperties: false + +examples: + - | + apb { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@8080 { + compatible = "amlogic,t7-gp0-pll"; + reg = <0 0x8080 0 0x20>; + clocks = <&scmi_clk 2>; + clock-names = "in0"; + #clock-cells = <1>; + }; + + clock-controller@8300 { + compatible = "amlogic,t7-mclk-pll"; + reg = <0 0x8300 0 0x18>; + clocks = <&scmi_clk 2>, + <&xtal>, + <&scmi_clk 31>; + clock-names = "in0", "in1", "in2"; + #clock-cells = <1>; + }; + }; diff --git a/include/dt-bindings/clock/amlogic,t7-pll-clkc.h b/include/dt-bindings/clock/amlogic,t7-pll-clkc.h new file mode 100644 index 000000000000..e2481f2f1163 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,t7-pll-clkc.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved + */ + +#ifndef __T7_PLL_CLKC_H +#define __T7_PLL_CLKC_H + +/* GP0 */ +#define CLKID_GP0_PLL_DCO 0 +#define CLKID_GP0_PLL 1 + +/* GP1 */ +#define CLKID_GP1_PLL_DCO 0 +#define CLKID_GP1_PLL 1 + +/* HIFI */ +#define CLKID_HIFI_PLL_DCO 0 +#define CLKID_HIFI_PLL 1 + +/* PCIE */ +#define CLKID_PCIE_PLL_DCO 0 +#define CLKID_PCIE_PLL_DCO_DIV2 1 +#define CLKID_PCIE_PLL_OD 2 +#define CLKID_PCIE_PLL 3 + +/* MPLL */ +#define CLKID_MPLL_PREDIV 0 +#define CLKID_MPLL0_DIV 1 +#define CLKID_MPLL0 2 +#define CLKID_MPLL1_DIV 3 +#define CLKID_MPLL1 4 +#define CLKID_MPLL2_DIV 5 +#define CLKID_MPLL2 6 +#define CLKID_MPLL3_DIV 7 +#define CLKID_MPLL3 8 + +/* HDMI */ +#define CLKID_HDMI_PLL_DCO 0 +#define CLKID_HDMI_PLL_OD 1 +#define CLKID_HDMI_PLL 2 + +/* MCLK */ +#define CLKID_MCLK_PLL_DCO 0 +#define CLKID_MCLK_PRE 1 +#define CLKID_MCLK_PLL 2 +#define CLKID_MCLK_0_SEL 3 +#define CLKID_MCLK_0_DIV2 4 +#define CLKID_MCLK_0_PRE 5 +#define CLKID_MCLK_0 6 +#define CLKID_MCLK_1_SEL 7 +#define CLKID_MCLK_1_DIV2 8 +#define CLKID_MCLK_1_PRE 9 +#define CLKID_MCLK_1 10 + +#endif /* __T7_PLL_CLKC_H */ From f5d473e96fe0ae46a2da79c96b3623b3be37b5a0 Mon Sep 17 00:00:00 2001 From: Jian Hu Date: Fri, 12 Dec 2025 10:26:15 +0800 Subject: [PATCH 002/165] dt-bindings: clock: add Amlogic T7 SCMI clock controller Add DT bindings for the SCMI clock controller of the Amlogic T7 SoC family. Signed-off-by: Jian Hu Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20251212022619.3072132-3-jian.hu@amlogic.com Signed-off-by: Jerome Brunet --- include/dt-bindings/clock/amlogic,t7-scmi.h | 47 +++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 include/dt-bindings/clock/amlogic,t7-scmi.h diff --git a/include/dt-bindings/clock/amlogic,t7-scmi.h b/include/dt-bindings/clock/amlogic,t7-scmi.h new file mode 100644 index 000000000000..27bd257bd4ea --- /dev/null +++ b/include/dt-bindings/clock/amlogic,t7-scmi.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved + */ + +#ifndef __T7_SCMI_CLKC_H +#define __T7_SCMI_CLKC_H + +#define CLKID_DDR_PLL_OSC 0 +#define CLKID_AUD_PLL_OSC 1 +#define CLKID_TOP_PLL_OSC 2 +#define CLKID_TCON_PLL_OSC 3 +#define CLKID_USB_PLL0_OSC 4 +#define CLKID_USB_PLL1_OSC 5 +#define CLKID_MCLK_PLL_OSC 6 +#define CLKID_PCIE_OSC 7 +#define CLKID_ETH_PLL_OSC 8 +#define CLKID_PCIE_REFCLK_PLL_OSC 9 +#define CLKID_EARC_OSC 10 +#define CLKID_SYS1_PLL_OSC 11 +#define CLKID_HDMI_PLL_OSC 12 +#define CLKID_SYS_CLK 13 +#define CLKID_AXI_CLK 14 +#define CLKID_FIXED_PLL_DCO 15 +#define CLKID_FIXED_PLL 16 +#define CLKID_FCLK_DIV2_DIV 17 +#define CLKID_FCLK_DIV2 18 +#define CLKID_FCLK_DIV2P5_DIV 19 +#define CLKID_FCLK_DIV2P5 20 +#define CLKID_FCLK_DIV3_DIV 21 +#define CLKID_FCLK_DIV3 22 +#define CLKID_FCLK_DIV4_DIV 23 +#define CLKID_FCLK_DIV4 24 +#define CLKID_FCLK_DIV5_DIV 25 +#define CLKID_FCLK_DIV5 26 +#define CLKID_FCLK_DIV7_DIV 27 +#define CLKID_FCLK_DIV7 28 +#define CLKID_FCLK_50M_DIV 29 +#define CLKID_FCLK_50M 30 +#define CLKID_CPU_CLK 31 +#define CLKID_A73_CLK 32 +#define CLKID_CPU_CLK_DIV16_DIV 33 +#define CLKID_CPU_CLK_DIV16 34 +#define CLKID_A73_CLK_DIV16_DIV 35 +#define CLKID_A73_CLK_DIV16 36 + +#endif /* __T7_SCMI_CLKC_H */ From b4156204e0f5d66e5943d9836e42d01d6e5e12fb Mon Sep 17 00:00:00 2001 From: Jian Hu Date: Fri, 12 Dec 2025 10:26:16 +0800 Subject: [PATCH 003/165] dt-bindings: clock: add Amlogic T7 peripherals clock controller Add DT bindings for the peripheral clock controller of the Amlogic T7 SoC family. Signed-off-by: Jian Hu Reviewed-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20251212022619.3072132-4-jian.hu@amlogic.com Signed-off-by: Jerome Brunet --- .../clock/amlogic,t7-peripherals-clkc.yaml | 116 +++++++++ .../clock/amlogic,t7-peripherals-clkc.h | 228 ++++++++++++++++++ 2 files changed, 344 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/amlogic,t7-peripherals-clkc.yaml create mode 100644 include/dt-bindings/clock/amlogic,t7-peripherals-clkc.h diff --git a/Documentation/devicetree/bindings/clock/amlogic,t7-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,t7-peripherals-clkc.yaml new file mode 100644 index 000000000000..55bb73707d58 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,t7-peripherals-clkc.yaml @@ -0,0 +1,116 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/amlogic,t7-peripherals-clkc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic T7 Peripherals Clock Controller + +maintainers: + - Neil Armstrong + - Jerome Brunet + - Xianwei Zhao + - Jian Hu + +properties: + compatible: + const: amlogic,t7-peripherals-clkc + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + + clocks: + minItems: 14 + items: + - description: input oscillator + - description: input sys clk + - description: input fixed pll + - description: input fclk div 2 + - description: input fclk div 2p5 + - description: input fclk div 3 + - description: input fclk div 4 + - description: input fclk div 5 + - description: input fclk div 7 + - description: input hifi pll + - description: input gp0 pll + - description: input gp1 pll + - description: input mpll1 + - description: input mpll2 + - description: external input rmii oscillator (optional) + - description: input video pll0 (optional) + - description: external pad input for rtc (optional) + + clock-names: + minItems: 14 + items: + - const: xtal + - const: sys + - const: fix + - const: fdiv2 + - const: fdiv2p5 + - const: fdiv3 + - const: fdiv4 + - const: fdiv5 + - const: fdiv7 + - const: hifi + - const: gp0 + - const: gp1 + - const: mpll1 + - const: mpll2 + - const: ext_rmii + - const: vid_pll0 + - const: ext_rtc + +required: + - compatible + - '#clock-cells' + - reg + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + apb { + #address-cells = <2>; + #size-cells = <2>; + + clkc_periphs:clock-controller@0 { + compatible = "amlogic,t7-peripherals-clkc"; + reg = <0 0x0 0 0x1c8>; + #clock-cells = <1>; + clocks = <&xtal>, + <&scmi_clk 13>, + <&scmi_clk 16>, + <&scmi_clk 18>, + <&scmi_clk 20>, + <&scmi_clk 22>, + <&scmi_clk 24>, + <&scmi_clk 26>, + <&scmi_clk 28>, + <&hifi 1>, + <&gp0 1>, + <&gp1 1>, + <&mpll 4>, + <&mpll 6>; + clock-names = "xtal", + "sys", + "fix", + "fdiv2", + "fdiv2p5", + "fdiv3", + "fdiv4", + "fdiv5", + "fdiv7", + "hifi", + "gp0", + "gp1", + "mpll1", + "mpll2"; + }; + }; diff --git a/include/dt-bindings/clock/amlogic,t7-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,t7-peripherals-clkc.h new file mode 100644 index 000000000000..32c4b62037de --- /dev/null +++ b/include/dt-bindings/clock/amlogic,t7-peripherals-clkc.h @@ -0,0 +1,228 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved + */ + +#ifndef __T7_PERIPHERALS_CLKC_H +#define __T7_PERIPHERALS_CLKC_H + +#define CLKID_RTC_DUALDIV_IN 0 +#define CLKID_RTC_DUALDIV_DIV 1 +#define CLKID_RTC_DUALDIV_SEL 2 +#define CLKID_RTC_DUALDIV 3 +#define CLKID_RTC 4 +#define CLKID_CECA_DUALDIV_IN 5 +#define CLKID_CECA_DUALDIV_DIV 6 +#define CLKID_CECA_DUALDIV_SEL 7 +#define CLKID_CECA_DUALDIV 8 +#define CLKID_CECA 9 +#define CLKID_CECB_DUALDIV_IN 10 +#define CLKID_CECB_DUALDIV_DIV 11 +#define CLKID_CECB_DUALDIV_SEL 12 +#define CLKID_CECB_DUALDIV 13 +#define CLKID_CECB 14 +#define CLKID_SC_SEL 15 +#define CLKID_SC_DIV 16 +#define CLKID_SC 17 +#define CLKID_DSPA_0_SEL 18 +#define CLKID_DSPA_0_DIV 19 +#define CLKID_DSPA_0 20 +#define CLKID_DSPA_1_SEL 21 +#define CLKID_DSPA_1_DIV 22 +#define CLKID_DSPA_1 23 +#define CLKID_DSPA 24 +#define CLKID_DSPB_0_SEL 25 +#define CLKID_DSPB_0_DIV 26 +#define CLKID_DSPB_0 27 +#define CLKID_DSPB_1_SEL 28 +#define CLKID_DSPB_1_DIV 29 +#define CLKID_DSPB_1 30 +#define CLKID_DSPB 31 +#define CLKID_24M 32 +#define CLKID_24M_DIV2 33 +#define CLKID_12M 34 +#define CLKID_25M_DIV 35 +#define CLKID_25M 36 +#define CLKID_ANAKIN_0_SEL 37 +#define CLKID_ANAKIN_0_DIV 38 +#define CLKID_ANAKIN_0 39 +#define CLKID_ANAKIN_1_SEL 40 +#define CLKID_ANAKIN_1_DIV 41 +#define CLKID_ANAKIN_1 42 +#define CLKID_ANAKIN_01_SEL 43 +#define CLKID_ANAKIN 44 +#define CLKID_TS_DIV 45 +#define CLKID_TS 46 +#define CLKID_MIPI_CSI_PHY_0_SEL 47 +#define CLKID_MIPI_CSI_PHY_0_DIV 48 +#define CLKID_MIPI_CSI_PHY_0 49 +#define CLKID_MIPI_CSI_PHY_1_SEL 50 +#define CLKID_MIPI_CSI_PHY_1_DIV 51 +#define CLKID_MIPI_CSI_PHY_1 52 +#define CLKID_MIPI_CSI_PHY 53 +#define CLKID_MIPI_ISP_SEL 54 +#define CLKID_MIPI_ISP_DIV 55 +#define CLKID_MIPI_ISP 56 +#define CLKID_MALI_0_SEL 57 +#define CLKID_MALI_0_DIV 58 +#define CLKID_MALI_0 59 +#define CLKID_MALI_1_SEL 60 +#define CLKID_MALI_1_DIV 61 +#define CLKID_MALI_1 62 +#define CLKID_MALI 63 +#define CLKID_ETH_RMII_SEL 64 +#define CLKID_ETH_RMII_DIV 65 +#define CLKID_ETH_RMII 66 +#define CLKID_FCLK_DIV2_DIV8 67 +#define CLKID_ETH_125M 68 +#define CLKID_SD_EMMC_A_SEL 69 +#define CLKID_SD_EMMC_A_DIV 70 +#define CLKID_SD_EMMC_A 71 +#define CLKID_SD_EMMC_B_SEL 72 +#define CLKID_SD_EMMC_B_DIV 73 +#define CLKID_SD_EMMC_B 74 +#define CLKID_SD_EMMC_C_SEL 75 +#define CLKID_SD_EMMC_C_DIV 76 +#define CLKID_SD_EMMC_C 77 +#define CLKID_SPICC0_SEL 78 +#define CLKID_SPICC0_DIV 79 +#define CLKID_SPICC0 80 +#define CLKID_SPICC1_SEL 81 +#define CLKID_SPICC1_DIV 82 +#define CLKID_SPICC1 83 +#define CLKID_SPICC2_SEL 84 +#define CLKID_SPICC2_DIV 85 +#define CLKID_SPICC2 86 +#define CLKID_SPICC3_SEL 87 +#define CLKID_SPICC3_DIV 88 +#define CLKID_SPICC3 89 +#define CLKID_SPICC4_SEL 90 +#define CLKID_SPICC4_DIV 91 +#define CLKID_SPICC4 92 +#define CLKID_SPICC5_SEL 93 +#define CLKID_SPICC5_DIV 94 +#define CLKID_SPICC5 95 +#define CLKID_SARADC_SEL 96 +#define CLKID_SARADC_DIV 97 +#define CLKID_SARADC 98 +#define CLKID_PWM_A_SEL 99 +#define CLKID_PWM_A_DIV 100 +#define CLKID_PWM_A 101 +#define CLKID_PWM_B_SEL 102 +#define CLKID_PWM_B_DIV 103 +#define CLKID_PWM_B 104 +#define CLKID_PWM_C_SEL 105 +#define CLKID_PWM_C_DIV 106 +#define CLKID_PWM_C 107 +#define CLKID_PWM_D_SEL 108 +#define CLKID_PWM_D_DIV 109 +#define CLKID_PWM_D 110 +#define CLKID_PWM_E_SEL 111 +#define CLKID_PWM_E_DIV 112 +#define CLKID_PWM_E 113 +#define CLKID_PWM_F_SEL 114 +#define CLKID_PWM_F_DIV 115 +#define CLKID_PWM_F 116 +#define CLKID_PWM_AO_A_SEL 117 +#define CLKID_PWM_AO_A_DIV 118 +#define CLKID_PWM_AO_A 119 +#define CLKID_PWM_AO_B_SEL 120 +#define CLKID_PWM_AO_B_DIV 121 +#define CLKID_PWM_AO_B 122 +#define CLKID_PWM_AO_C_SEL 123 +#define CLKID_PWM_AO_C_DIV 124 +#define CLKID_PWM_AO_C 125 +#define CLKID_PWM_AO_D_SEL 126 +#define CLKID_PWM_AO_D_DIV 127 +#define CLKID_PWM_AO_D 128 +#define CLKID_PWM_AO_E_SEL 129 +#define CLKID_PWM_AO_E_DIV 130 +#define CLKID_PWM_AO_E 131 +#define CLKID_PWM_AO_F_SEL 132 +#define CLKID_PWM_AO_F_DIV 133 +#define CLKID_PWM_AO_F 134 +#define CLKID_PWM_AO_G_SEL 135 +#define CLKID_PWM_AO_G_DIV 136 +#define CLKID_PWM_AO_G 137 +#define CLKID_PWM_AO_H_SEL 138 +#define CLKID_PWM_AO_H_DIV 139 +#define CLKID_PWM_AO_H 140 +#define CLKID_SYS_DDR 141 +#define CLKID_SYS_DOS 142 +#define CLKID_SYS_MIPI_DSI_A 143 +#define CLKID_SYS_MIPI_DSI_B 144 +#define CLKID_SYS_ETHPHY 145 +#define CLKID_SYS_MALI 146 +#define CLKID_SYS_AOCPU 147 +#define CLKID_SYS_AUCPU 148 +#define CLKID_SYS_CEC 149 +#define CLKID_SYS_GDC 150 +#define CLKID_SYS_DESWARP 151 +#define CLKID_SYS_AMPIPE_NAND 152 +#define CLKID_SYS_AMPIPE_ETH 153 +#define CLKID_SYS_AM2AXI0 154 +#define CLKID_SYS_AM2AXI1 155 +#define CLKID_SYS_AM2AXI2 156 +#define CLKID_SYS_SD_EMMC_A 157 +#define CLKID_SYS_SD_EMMC_B 158 +#define CLKID_SYS_SD_EMMC_C 159 +#define CLKID_SYS_SMARTCARD 160 +#define CLKID_SYS_ACODEC 161 +#define CLKID_SYS_SPIFC 162 +#define CLKID_SYS_MSR_CLK 163 +#define CLKID_SYS_IR_CTRL 164 +#define CLKID_SYS_AUDIO 165 +#define CLKID_SYS_ETH 166 +#define CLKID_SYS_UART_A 167 +#define CLKID_SYS_UART_B 168 +#define CLKID_SYS_UART_C 169 +#define CLKID_SYS_UART_D 170 +#define CLKID_SYS_UART_E 171 +#define CLKID_SYS_UART_F 172 +#define CLKID_SYS_AIFIFO 173 +#define CLKID_SYS_SPICC2 174 +#define CLKID_SYS_SPICC3 175 +#define CLKID_SYS_SPICC4 176 +#define CLKID_SYS_TS_A73 177 +#define CLKID_SYS_TS_A53 178 +#define CLKID_SYS_SPICC5 179 +#define CLKID_SYS_G2D 180 +#define CLKID_SYS_SPICC0 181 +#define CLKID_SYS_SPICC1 182 +#define CLKID_SYS_PCIE 183 +#define CLKID_SYS_USB 184 +#define CLKID_SYS_PCIE_PHY 185 +#define CLKID_SYS_I2C_AO_A 186 +#define CLKID_SYS_I2C_AO_B 187 +#define CLKID_SYS_I2C_M_A 188 +#define CLKID_SYS_I2C_M_B 189 +#define CLKID_SYS_I2C_M_C 190 +#define CLKID_SYS_I2C_M_D 191 +#define CLKID_SYS_I2C_M_E 192 +#define CLKID_SYS_I2C_M_F 193 +#define CLKID_SYS_HDMITX_APB 194 +#define CLKID_SYS_I2C_S_A 195 +#define CLKID_SYS_HDMIRX_PCLK 196 +#define CLKID_SYS_MMC_APB 197 +#define CLKID_SYS_MIPI_ISP_PCLK 198 +#define CLKID_SYS_RSA 199 +#define CLKID_SYS_PCLK_SYS_APB 200 +#define CLKID_SYS_A73PCLK_APB 201 +#define CLKID_SYS_DSPA 202 +#define CLKID_SYS_DSPB 203 +#define CLKID_SYS_VPU_INTR 204 +#define CLKID_SYS_SAR_ADC 205 +#define CLKID_SYS_GIC 206 +#define CLKID_SYS_TS_GPU 207 +#define CLKID_SYS_TS_NNA 208 +#define CLKID_SYS_TS_VPU 209 +#define CLKID_SYS_TS_HEVC 210 +#define CLKID_SYS_PWM_AB 211 +#define CLKID_SYS_PWM_CD 212 +#define CLKID_SYS_PWM_EF 213 +#define CLKID_SYS_PWM_AO_AB 214 +#define CLKID_SYS_PWM_AO_CD 215 +#define CLKID_SYS_PWM_AO_EF 216 +#define CLKID_SYS_PWM_AO_GH 217 + +#endif /* __T7_PERIPHERALS_CLKC_H */ From 140f074c312702a1837136e024f5df1309e37251 Mon Sep 17 00:00:00 2001 From: Jian Hu Date: Fri, 12 Dec 2025 10:26:17 +0800 Subject: [PATCH 004/165] clk: meson: t7: add support for the T7 SoC PLL clock Add PLL clock controller driver for the Amlogic T7 SoC family. Signed-off-by: Jian Hu Link: https://lore.kernel.org/r/20251212022619.3072132-5-jian.hu@amlogic.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/Kconfig | 15 + drivers/clk/meson/Makefile | 1 + drivers/clk/meson/t7-pll.c | 1074 ++++++++++++++++++++++++++++++++++++ 3 files changed, 1090 insertions(+) create mode 100644 drivers/clk/meson/t7-pll.c diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 71481607a6d5..e6a059bcf636 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -201,4 +201,19 @@ config COMMON_CLK_S4_PERIPHERALS help Support for the peripherals clock controller on Amlogic S805X2 and S905Y4 devices, AKA S4. Say Y if you want S4 peripherals clock controller to work. + +config COMMON_CLK_T7_PLL + tristate "Amlogic T7 SoC PLL controller support" + depends on ARM64 + default ARCH_MESON + select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_CLKC_UTILS + select COMMON_CLK_MESON_MPLL + select COMMON_CLK_MESON_PLL + imply COMMON_CLK_SCMI + help + Support for the PLL clock controller on Amlogic A311D2 based + device, AKA T7. PLLs are required by most peripheral to operate. + Say Y if you want T7 PLL clock controller to work. + endmenu diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index c6998e752c68..8e3f7f94c639 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -26,3 +26,4 @@ obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o obj-$(CONFIG_COMMON_CLK_S4_PLL) += s4-pll.o obj-$(CONFIG_COMMON_CLK_S4_PERIPHERALS) += s4-peripherals.o +obj-$(CONFIG_COMMON_CLK_T7_PLL) += t7-pll.o diff --git a/drivers/clk/meson/t7-pll.c b/drivers/clk/meson/t7-pll.c new file mode 100644 index 000000000000..0a622f45fa36 --- /dev/null +++ b/drivers/clk/meson/t7-pll.c @@ -0,0 +1,1074 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved. + * Author: Jian Hu + */ + +#include +#include +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-mpll.h" +#include "meson-clkc-utils.h" +#include + +#define GP0PLL_CTRL0 0x00 +#define GP0PLL_CTRL1 0x04 +#define GP0PLL_CTRL2 0x08 +#define GP0PLL_CTRL3 0x0c +#define GP0PLL_CTRL4 0x10 +#define GP0PLL_CTRL5 0x14 +#define GP0PLL_CTRL6 0x18 +#define GP0PLL_STS 0x1c + +#define GP1PLL_CTRL0 0x00 +#define GP1PLL_CTRL1 0x04 +#define GP1PLL_CTRL2 0x08 +#define GP1PLL_CTRL3 0x0c +#define GP1PLL_STS 0x1c + +#define HIFIPLL_CTRL0 0x00 +#define HIFIPLL_CTRL1 0x04 +#define HIFIPLL_CTRL2 0x08 +#define HIFIPLL_CTRL3 0x0c +#define HIFIPLL_CTRL4 0x10 +#define HIFIPLL_CTRL5 0x14 +#define HIFIPLL_CTRL6 0x18 +#define HIFIPLL_STS 0x1c + +#define PCIEPLL_CTRL0 0x00 +#define PCIEPLL_CTRL1 0x04 +#define PCIEPLL_CTRL2 0x08 +#define PCIEPLL_CTRL3 0x0c +#define PCIEPLL_CTRL4 0x10 +#define PCIEPLL_CTRL5 0x14 +#define PCIEPLL_STS 0x18 + +#define MPLL_CTRL0 0x00 +#define MPLL_CTRL1 0x04 +#define MPLL_CTRL2 0x08 +#define MPLL_CTRL3 0x0c +#define MPLL_CTRL4 0x10 +#define MPLL_CTRL5 0x14 +#define MPLL_CTRL6 0x18 +#define MPLL_CTRL7 0x1c +#define MPLL_CTRL8 0x20 +#define MPLL_STS 0x24 + +#define HDMIPLL_CTRL0 0x00 +#define HDMIPLL_CTRL1 0x04 +#define HDMIPLL_CTRL2 0x08 +#define HDMIPLL_CTRL3 0x0c +#define HDMIPLL_CTRL4 0x10 +#define HDMIPLL_CTRL5 0x14 +#define HDMIPLL_CTRL6 0x18 +#define HDMIPLL_STS 0x1c + +#define MCLK_PLL_CNTL0 0x00 +#define MCLK_PLL_CNTL1 0x04 +#define MCLK_PLL_CNTL2 0x08 +#define MCLK_PLL_CNTL3 0x0c +#define MCLK_PLL_CNTL4 0x10 +#define MCLK_PLL_STS 0x14 + +static const struct pll_mult_range t7_media_pll_mult_range = { + .min = 125, + .max = 250, +}; + +static const struct reg_sequence t7_gp0_init_regs[] = { + { .reg = GP0PLL_CTRL1, .def = 0x00000000 }, + { .reg = GP0PLL_CTRL2, .def = 0x00000000 }, + { .reg = GP0PLL_CTRL3, .def = 0x48681c00 }, + { .reg = GP0PLL_CTRL4, .def = 0x88770290 }, + { .reg = GP0PLL_CTRL5, .def = 0x3927200a }, + { .reg = GP0PLL_CTRL6, .def = 0x56540000 }, +}; + +static struct clk_regmap t7_gp0_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = GP0PLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = GP0PLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = GP0PLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = GP0PLL_STS, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = GP0PLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &t7_media_pll_mult_range, + .init_regs = t7_gp0_init_regs, + .init_count = ARRAY_SIZE(t7_gp0_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_gp0_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = GP0PLL_CTRL0, + .shift = 16, + .width = 3, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data) { + .name = "gp0_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_gp0_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * Compared with GP0 PLL, GP1 PLL is a newly designed PLL with + * a DCO range of 1.6GHz to 3.2GHz. + */ +static const struct pll_mult_range t7_gp1_pll_mult_range = { + .min = 67, + .max = 133, +}; + +static const struct reg_sequence t7_gp1_init_regs[] = { + { .reg = GP1PLL_CTRL1, .def = 0x1420500f }, + { .reg = GP1PLL_CTRL2, .def = 0x00023001 }, + { .reg = GP1PLL_CTRL3, .def = 0x00000000 }, +}; + +static struct clk_regmap t7_gp1_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = GP1PLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = GP1PLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = GP1PLL_CTRL0, + .shift = 16, + .width = 5, + }, + .l = { + .reg_off = GP1PLL_STS, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = GP1PLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &t7_gp1_pll_mult_range, + .init_regs = t7_gp1_init_regs, + .init_count = ARRAY_SIZE(t7_gp1_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "gp1_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_gp1_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = GP1PLL_CTRL0, + .shift = 12, + .width = 3, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data) { + .name = "gp1_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_gp1_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence t7_hifi_init_regs[] = { + { .reg = HIFIPLL_CTRL1, .def = 0x00000000 }, + { .reg = HIFIPLL_CTRL2, .def = 0x00000000 }, + { .reg = HIFIPLL_CTRL3, .def = 0x6a285c00 }, + { .reg = HIFIPLL_CTRL4, .def = 0x65771290 }, + { .reg = HIFIPLL_CTRL5, .def = 0x3927200a }, + { .reg = HIFIPLL_CTRL6, .def = 0x56540000 } +}; + +static struct clk_regmap t7_hifi_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HIFIPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HIFIPLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HIFIPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HIFIPLL_CTRL1, + .shift = 0, + .width = 17, + }, + .l = { + .reg_off = HIFIPLL_STS, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HIFIPLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &t7_media_pll_mult_range, + .init_regs = t7_hifi_init_regs, + .init_count = ARRAY_SIZE(t7_hifi_init_regs), + .frac_max = 100000, + }, + .hw.init = &(struct clk_init_data){ + .name = "hifi_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_hifi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HIFIPLL_CTRL0, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data) { + .name = "hifi_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_hifi_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * The T7 PCIE PLL is fined tuned to deliver a very precise + * 100MHz reference clock for the PCIe Analog PHY, and thus requires + * a strict register sequence to enable the PLL. + */ +static const struct reg_sequence t7_pcie_pll_init_regs[] = { + { .reg = PCIEPLL_CTRL0, .def = 0x200c04c8 }, + { .reg = PCIEPLL_CTRL0, .def = 0x300c04c8 }, + { .reg = PCIEPLL_CTRL1, .def = 0x30000000 }, + { .reg = PCIEPLL_CTRL2, .def = 0x00001100 }, + { .reg = PCIEPLL_CTRL3, .def = 0x10058e00 }, + { .reg = PCIEPLL_CTRL4, .def = 0x000100c0 }, + { .reg = PCIEPLL_CTRL5, .def = 0x68000048 }, + { .reg = PCIEPLL_CTRL5, .def = 0x68000068, .delay_us = 20 }, + { .reg = PCIEPLL_CTRL4, .def = 0x008100c0, .delay_us = 20 }, + { .reg = PCIEPLL_CTRL0, .def = 0x340c04c8 }, + { .reg = PCIEPLL_CTRL0, .def = 0x140c04c8, .delay_us = 20 }, + { .reg = PCIEPLL_CTRL2, .def = 0x00001000 } +}; + +static struct clk_regmap t7_pcie_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = PCIEPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = PCIEPLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = PCIEPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = PCIEPLL_CTRL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = PCIEPLL_CTRL0, + .shift = 29, + .width = 1, + }, + .init_regs = t7_pcie_pll_init_regs, + .init_count = ARRAY_SIZE(t7_pcie_pll_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_dco", + .ops = &meson_clk_pcie_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor t7_pcie_pll_dco_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_dco_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_pcie_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_pcie_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = PCIEPLL_CTRL0, + .shift = 16, + .width = 5, + /* the divisor is 32 when [16:21] = 0 */ + .flags = CLK_DIVIDER_MAX_AT_ZERO, + }, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_od", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_pcie_pll_dco_div2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor t7_pcie_pll = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_pcie_pll_od.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor t7_mpll_prediv = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "mpll_prediv", + .ops = &clk_fixed_factor_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +static const struct reg_sequence t7_mpll0_init_regs[] = { + { .reg = MPLL_CTRL2, .def = 0x40000033 } +}; + +static struct clk_regmap t7_mpll0_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = MPLL_CTRL1, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = MPLL_CTRL1, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = MPLL_CTRL1, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = MPLL_CTRL1, + .shift = 29, + .width = 1, + }, + .init_regs = t7_mpll0_init_regs, + .init_count = ARRAY_SIZE(t7_mpll0_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll0_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_mpll0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MPLL_CTRL1, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mpll0_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence t7_mpll1_init_regs[] = { + { .reg = MPLL_CTRL4, .def = 0x40000033 } +}; + +static struct clk_regmap t7_mpll1_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = MPLL_CTRL3, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = MPLL_CTRL3, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = MPLL_CTRL3, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = MPLL_CTRL3, + .shift = 29, + .width = 1, + }, + .init_regs = t7_mpll1_init_regs, + .init_count = ARRAY_SIZE(t7_mpll1_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll1_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_mpll1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MPLL_CTRL3, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mpll1_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence t7_mpll2_init_regs[] = { + { .reg = MPLL_CTRL6, .def = 0x40000033 } +}; + +static struct clk_regmap t7_mpll2_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = MPLL_CTRL5, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = MPLL_CTRL5, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = MPLL_CTRL5, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = MPLL_CTRL5, + .shift = 29, + .width = 1, + }, + .init_regs = t7_mpll2_init_regs, + .init_count = ARRAY_SIZE(t7_mpll2_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll2_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_mpll2 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MPLL_CTRL5, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll2", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mpll2_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence t7_mpll3_init_regs[] = { + { .reg = MPLL_CTRL8, .def = 0x40000033 } +}; + +static struct clk_regmap t7_mpll3_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = MPLL_CTRL7, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = MPLL_CTRL7, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = MPLL_CTRL7, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = MPLL_CTRL7, + .shift = 29, + .width = 1, + }, + .init_regs = t7_mpll3_init_regs, + .init_count = ARRAY_SIZE(t7_mpll3_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll3_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_mpll3 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MPLL_CTRL7, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll3", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mpll3_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence t7_hdmi_init_regs[] = { + { .reg = HDMIPLL_CTRL1, .def = 0x00000000 }, + { .reg = HDMIPLL_CTRL2, .def = 0x00000000 }, + { .reg = HDMIPLL_CTRL3, .def = 0x6a28dc00 }, + { .reg = HDMIPLL_CTRL4, .def = 0x65771290 }, + { .reg = HDMIPLL_CTRL5, .def = 0x39272000 }, + { .reg = HDMIPLL_CTRL6, .def = 0x56540000 } +}; + +static struct clk_regmap t7_hdmi_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HDMIPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HDMIPLL_CTRL0, + .shift = 0, + .width = 9, + }, + .n = { + .reg_off = HDMIPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = HDMIPLL_CTRL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HDMIPLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &t7_media_pll_mult_range, + .init_regs = t7_hdmi_init_regs, + .init_count = ARRAY_SIZE(t7_hdmi_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "in0", } + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_hdmi_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = HDMIPLL_CTRL0, + .shift = 16, + .width = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_hdmi_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_hdmi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HDMIPLL_CTRL0, + .shift = 20, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_hdmi_pll_od.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct pll_mult_range t7_mclk_pll_mult_range = { + .min = 67, + .max = 133, +}; + +static const struct reg_sequence t7_mclk_init_regs[] = { + { .reg = MCLK_PLL_CNTL1, .def = 0x1470500f }, + { .reg = MCLK_PLL_CNTL2, .def = 0x00023001 }, + { .reg = MCLK_PLL_CNTL3, .def = 0x18180000 }, + { .reg = MCLK_PLL_CNTL4, .def = 0x00180303 }, +}; + +static struct clk_regmap t7_mclk_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = MCLK_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = MCLK_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = MCLK_PLL_CNTL0, + .shift = 16, + .width = 5, + }, + .l = { + .reg_off = MCLK_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = MCLK_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + .l_detect = { + .reg_off = MCLK_PLL_CNTL2, + .shift = 6, + .width = 1, + }, + .range = &t7_mclk_pll_mult_range, + .init_regs = t7_mclk_init_regs, + .init_count = ARRAY_SIZE(t7_mclk_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mclk_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +/* max div is 16 */ +static const struct clk_div_table t7_mclk_div[] = { + { .val = 0, .div = 1 }, + { .val = 1, .div = 2 }, + { .val = 2, .div = 4 }, + { .val = 3, .div = 8 }, + { .val = 4, .div = 16 }, + { /* sentinel */ } +}; + +static struct clk_regmap t7_mclk_pre_od = { + .data = &(struct clk_regmap_div_data){ + .offset = MCLK_PLL_CNTL0, + .shift = 12, + .width = 3, + .table = t7_mclk_div, + }, + .hw.init = &(struct clk_init_data){ + .name = "mclk_pre_od", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = MCLK_PLL_CNTL4, + .shift = 16, + .width = 5, + .flags = CLK_DIVIDER_ONE_BASED, + }, + .hw.init = &(struct clk_init_data){ + .name = "mclk_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_pre_od.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = MCLK_PLL_CNTL4, + .mask = 0x3, + .shift = 4, + }, + .hw.init = &(struct clk_init_data){ + .name = "mclk_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &t7_mclk_pll.hw }, + { .fw_name = "in1", }, + { .fw_name = "in2", }, + }, + .num_parents = 3, + }, +}; + +static struct clk_fixed_factor t7_mclk_0_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "mclk_0_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mclk_0_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_0_pre = { + .data = &(struct clk_regmap_gate_data){ + .offset = MCLK_PLL_CNTL4, + .bit_idx = 2, + }, + .hw.init = &(struct clk_init_data) { + .name = "mclk_0_pre", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_0_div2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MCLK_PLL_CNTL4, + .bit_idx = 0, + }, + .hw.init = &(struct clk_init_data) { + .name = "mclk_0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_0_pre.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = MCLK_PLL_CNTL4, + .mask = 0x3, + .shift = 12, + }, + .hw.init = &(struct clk_init_data){ + .name = "mclk_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &t7_mclk_pll.hw }, + { .fw_name = "in1", }, + { .fw_name = "in2", }, + }, + .num_parents = 3, + }, +}; + +static struct clk_fixed_factor t7_mclk_1_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "mclk_1_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mclk_1_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_1_pre = { + .data = &(struct clk_regmap_gate_data){ + .offset = MCLK_PLL_CNTL4, + .bit_idx = 10, + }, + .hw.init = &(struct clk_init_data) { + .name = "mclk_1_pre", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_1_div2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MCLK_PLL_CNTL4, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "mclk_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_1_pre.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_hw *t7_gp0_hw_clks[] = { + [CLKID_GP0_PLL_DCO] = &t7_gp0_pll_dco.hw, + [CLKID_GP0_PLL] = &t7_gp0_pll.hw, +}; + +static struct clk_hw *t7_gp1_hw_clks[] = { + [CLKID_GP1_PLL_DCO] = &t7_gp1_pll_dco.hw, + [CLKID_GP1_PLL] = &t7_gp1_pll.hw, +}; + +static struct clk_hw *t7_hifi_hw_clks[] = { + [CLKID_HIFI_PLL_DCO] = &t7_hifi_pll_dco.hw, + [CLKID_HIFI_PLL] = &t7_hifi_pll.hw, +}; + +static struct clk_hw *t7_pcie_hw_clks[] = { + [CLKID_PCIE_PLL_DCO] = &t7_pcie_pll_dco.hw, + [CLKID_PCIE_PLL_DCO_DIV2] = &t7_pcie_pll_dco_div2.hw, + [CLKID_PCIE_PLL_OD] = &t7_pcie_pll_od.hw, + [CLKID_PCIE_PLL] = &t7_pcie_pll.hw, +}; + +static struct clk_hw *t7_mpll_hw_clks[] = { + [CLKID_MPLL_PREDIV] = &t7_mpll_prediv.hw, + [CLKID_MPLL0_DIV] = &t7_mpll0_div.hw, + [CLKID_MPLL0] = &t7_mpll0.hw, + [CLKID_MPLL1_DIV] = &t7_mpll1_div.hw, + [CLKID_MPLL1] = &t7_mpll1.hw, + [CLKID_MPLL2_DIV] = &t7_mpll2_div.hw, + [CLKID_MPLL2] = &t7_mpll2.hw, + [CLKID_MPLL3_DIV] = &t7_mpll3_div.hw, + [CLKID_MPLL3] = &t7_mpll3.hw, +}; + +static struct clk_hw *t7_hdmi_hw_clks[] = { + [CLKID_HDMI_PLL_DCO] = &t7_hdmi_pll_dco.hw, + [CLKID_HDMI_PLL_OD] = &t7_hdmi_pll_od.hw, + [CLKID_HDMI_PLL] = &t7_hdmi_pll.hw, +}; + +static struct clk_hw *t7_mclk_hw_clks[] = { + [CLKID_MCLK_PLL_DCO] = &t7_mclk_pll_dco.hw, + [CLKID_MCLK_PRE] = &t7_mclk_pre_od.hw, + [CLKID_MCLK_PLL] = &t7_mclk_pll.hw, + [CLKID_MCLK_0_SEL] = &t7_mclk_0_sel.hw, + [CLKID_MCLK_0_DIV2] = &t7_mclk_0_div2.hw, + [CLKID_MCLK_0_PRE] = &t7_mclk_0_pre.hw, + [CLKID_MCLK_0] = &t7_mclk_0.hw, + [CLKID_MCLK_1_SEL] = &t7_mclk_1_sel.hw, + [CLKID_MCLK_1_DIV2] = &t7_mclk_1_div2.hw, + [CLKID_MCLK_1_PRE] = &t7_mclk_1_pre.hw, + [CLKID_MCLK_1] = &t7_mclk_1.hw, +}; + +static const struct meson_clkc_data t7_gp0_data = { + .hw_clks = { + .hws = t7_gp0_hw_clks, + .num = ARRAY_SIZE(t7_gp0_hw_clks), + }, +}; + +static const struct meson_clkc_data t7_gp1_data = { + .hw_clks = { + .hws = t7_gp1_hw_clks, + .num = ARRAY_SIZE(t7_gp1_hw_clks), + }, +}; + +static const struct meson_clkc_data t7_hifi_data = { + .hw_clks = { + .hws = t7_hifi_hw_clks, + .num = ARRAY_SIZE(t7_hifi_hw_clks), + }, +}; + +static const struct meson_clkc_data t7_pcie_data = { + .hw_clks = { + .hws = t7_pcie_hw_clks, + .num = ARRAY_SIZE(t7_pcie_hw_clks), + }, +}; + +static const struct reg_sequence t7_mpll_init_regs[] = { + { .reg = MPLL_CTRL0, .def = 0x00000543 } +}; + +static const struct meson_clkc_data t7_mpll_data = { + .hw_clks = { + .hws = t7_mpll_hw_clks, + .num = ARRAY_SIZE(t7_mpll_hw_clks), + }, + .init_regs = t7_mpll_init_regs, + .init_count = ARRAY_SIZE(t7_mpll_init_regs), +}; + +static const struct meson_clkc_data t7_hdmi_data = { + .hw_clks = { + .hws = t7_hdmi_hw_clks, + .num = ARRAY_SIZE(t7_hdmi_hw_clks), + }, +}; + +static const struct meson_clkc_data t7_mclk_data = { + .hw_clks = { + .hws = t7_mclk_hw_clks, + .num = ARRAY_SIZE(t7_mclk_hw_clks), + }, +}; + +static const struct of_device_id t7_pll_clkc_match_table[] = { + { .compatible = "amlogic,t7-gp0-pll", .data = &t7_gp0_data, }, + { .compatible = "amlogic,t7-gp1-pll", .data = &t7_gp1_data, }, + { .compatible = "amlogic,t7-hifi-pll", .data = &t7_hifi_data, }, + { .compatible = "amlogic,t7-pcie-pll", .data = &t7_pcie_data, }, + { .compatible = "amlogic,t7-mpll", .data = &t7_mpll_data, }, + { .compatible = "amlogic,t7-hdmi-pll", .data = &t7_hdmi_data, }, + { .compatible = "amlogic,t7-mclk-pll", .data = &t7_mclk_data, }, + {} +}; +MODULE_DEVICE_TABLE(of, t7_pll_clkc_match_table); + +static struct platform_driver t7_pll_clkc_driver = { + .probe = meson_clkc_mmio_probe, + .driver = { + .name = "t7-pll-clkc", + .of_match_table = t7_pll_clkc_match_table, + }, +}; +module_platform_driver(t7_pll_clkc_driver); + +MODULE_DESCRIPTION("Amlogic T7 PLL Clock Controller driver"); +MODULE_AUTHOR("Jian Hu "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("CLK_MESON"); From fab4d651b592b3ebc836e410ae27b8b832a5bff2 Mon Sep 17 00:00:00 2001 From: Jian Hu Date: Fri, 12 Dec 2025 10:26:18 +0800 Subject: [PATCH 005/165] clk: meson: t7: add t7 clock peripherals controller driver Add Peripheral clock controller driver for the Amlogic T7 SoC family. Signed-off-by: Jian Hu Link: https://lore.kernel.org/r/20251212022619.3072132-6-jian.hu@amlogic.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/Kconfig | 13 + drivers/clk/meson/Makefile | 1 + drivers/clk/meson/t7-peripherals.c | 1271 ++++++++++++++++++++++++++++ 3 files changed, 1285 insertions(+) create mode 100644 drivers/clk/meson/t7-peripherals.c diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index e6a059bcf636..cf8cf3f9e4ee 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -216,4 +216,17 @@ config COMMON_CLK_T7_PLL device, AKA T7. PLLs are required by most peripheral to operate. Say Y if you want T7 PLL clock controller to work. +config COMMON_CLK_T7_PERIPHERALS + tristate "Amlogic T7 SoC peripherals clock controller support" + depends on ARM64 + default ARCH_MESON + select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_CLKC_UTILS + select COMMON_CLK_MESON_DUALDIV + imply COMMON_CLK_SCMI + imply COMMON_CLK_T7_PLL + help + Support for the peripherals clock controller on Amlogic A311D2 based + device, AKA T7. Peripherals are required by most peripheral to operate. + Say Y if you want T7 peripherals clock controller to work. endmenu diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index 8e3f7f94c639..c6719694a242 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -27,3 +27,4 @@ obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o obj-$(CONFIG_COMMON_CLK_S4_PLL) += s4-pll.o obj-$(CONFIG_COMMON_CLK_S4_PERIPHERALS) += s4-peripherals.o obj-$(CONFIG_COMMON_CLK_T7_PLL) += t7-pll.o +obj-$(CONFIG_COMMON_CLK_T7_PERIPHERALS) += t7-peripherals.o diff --git a/drivers/clk/meson/t7-peripherals.c b/drivers/clk/meson/t7-peripherals.c new file mode 100644 index 000000000000..214db7850d86 --- /dev/null +++ b/drivers/clk/meson/t7-peripherals.c @@ -0,0 +1,1271 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved. + * Author: Jian Hu + */ + +#include +#include +#include "clk-dualdiv.h" +#include "clk-regmap.h" +#include "meson-clkc-utils.h" +#include + +#define RTC_BY_OSCIN_CTRL0 0x8 +#define RTC_BY_OSCIN_CTRL1 0xc +#define RTC_CTRL 0x10 +#define SYS_CLK_CTRL0 0x40 +#define SYS_CLK_EN0_REG0 0x44 +#define SYS_CLK_EN0_REG1 0x48 +#define SYS_CLK_EN0_REG2 0x4c +#define SYS_CLK_EN0_REG3 0x50 +#define CECA_CTRL0 0x88 +#define CECA_CTRL1 0x8c +#define CECB_CTRL0 0x90 +#define CECB_CTRL1 0x94 +#define SC_CLK_CTRL 0x98 +#define DSPA_CLK_CTRL0 0x9c +#define DSPB_CLK_CTRL0 0xa0 +#define CLK12_24_CTRL 0xa8 +#define ANAKIN_CLK_CTRL 0xac +#define MIPI_CSI_PHY_CLK_CTRL 0x10c +#define MIPI_ISP_CLK_CTRL 0x110 +#define TS_CLK_CTRL 0x158 +#define MALI_CLK_CTRL 0x15c +#define ETH_CLK_CTRL 0x164 +#define NAND_CLK_CTRL 0x168 +#define SD_EMMC_CLK_CTRL 0x16c +#define SPICC_CLK_CTRL 0x174 +#define SAR_CLK_CTRL0 0x17c +#define PWM_CLK_AB_CTRL 0x180 +#define PWM_CLK_CD_CTRL 0x184 +#define PWM_CLK_EF_CTRL 0x188 +#define PWM_CLK_AO_AB_CTRL 0x1a0 +#define PWM_CLK_AO_CD_CTRL 0x1a4 +#define PWM_CLK_AO_EF_CTRL 0x1a8 +#define PWM_CLK_AO_GH_CTRL 0x1ac +#define SPICC_CLK_CTRL1 0x1c0 +#define SPICC_CLK_CTRL2 0x1c4 + +#define T7_COMP_SEL(_name, _reg, _shift, _mask, _pdata) \ + MESON_COMP_SEL(t7_, _name, _reg, _shift, _mask, _pdata, NULL, 0, 0) + +#define T7_COMP_DIV(_name, _reg, _shift, _width) \ + MESON_COMP_DIV(t7_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT) + +#define T7_COMP_GATE(_name, _reg, _bit, _iflags) \ + MESON_COMP_GATE(t7_, _name, _reg, _bit, CLK_SET_RATE_PARENT | (_iflags)) + +static struct clk_regmap t7_rtc_dualdiv_in = { + .data = &(struct clk_regmap_gate_data){ + .offset = RTC_BY_OSCIN_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_duandiv_in", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static const struct meson_clk_dualdiv_param t7_dualdiv_table[] = { + { + .n1 = 733, .m1 = 8, + .n2 = 732, .m2 = 11, + .dual = 1, + }, + {} +}; + +static struct clk_regmap t7_rtc_dualdiv_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = RTC_BY_OSCIN_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = RTC_BY_OSCIN_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = RTC_BY_OSCIN_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = RTC_BY_OSCIN_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = RTC_BY_OSCIN_CTRL0, + .shift = 28, + .width = 1, + }, + .table = t7_dualdiv_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc_dualdiv_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_rtc_dualdiv_in.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_rtc_dualdiv_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = RTC_BY_OSCIN_CTRL1, + .mask = 0x1, + .shift = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc_dualdiv_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_rtc_dualdiv_div.hw, + &t7_rtc_dualdiv_in.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_rtc_dualdiv = { + .data = &(struct clk_regmap_gate_data){ + .offset = RTC_BY_OSCIN_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_dualdiv", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_rtc_dualdiv_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_rtc = { + .data = &(struct clk_regmap_mux_data) { + .offset = RTC_CTRL, + .mask = 0x3, + .shift = 0, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc", + .ops = &clk_regmap_mux_ops, + /* + * xtal is also on parent input #3 but that it is not useful to CCF since + * the same parent is available with parent input #0 + */ + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &t7_rtc_dualdiv.hw }, + { .fw_name = "ext_rtc", }, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap t7_ceca_dualdiv_in = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECA_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "ceca_dualdiv_in", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_ceca_dualdiv_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = CECA_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = CECA_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = CECA_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = CECA_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = CECA_CTRL0, + .shift = 28, + .width = 1, + }, + .table = t7_dualdiv_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_dualdiv_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_ceca_dualdiv_in.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_ceca_dualdiv_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECA_CTRL1, + .mask = 0x1, + .shift = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_dualdiv_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_ceca_dualdiv_div.hw, + &t7_ceca_dualdiv_in.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_ceca_dualdiv = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECA_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_dualdiv", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_ceca_dualdiv_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_ceca = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECA_CTRL1, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_ceca_dualdiv.hw, + &t7_rtc.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_cecb_dualdiv_in = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECB_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "cecb_dualdiv_in", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_cecb_dualdiv_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = CECB_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = CECB_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = CECB_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = CECB_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = CECB_CTRL0, + .shift = 28, + .width = 1, + }, + .table = t7_dualdiv_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_dualdiv_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_cecb_dualdiv_in.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_cecb_dualdiv_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECB_CTRL1, + .mask = 0x1, + .shift = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_dualdiv_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_cecb_dualdiv_div.hw, + &t7_cecb_dualdiv_in.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_cecb_dualdiv = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECB_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_dualdiv", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_cecb_dualdiv_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_cecb = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECB_CTRL1, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_cecb_dualdiv.hw, + &t7_rtc.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data t7_sc_parents[] = { + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "xtal", }, +}; + +static T7_COMP_SEL(sc, SC_CLK_CTRL, 9, 0x3, t7_sc_parents); +static T7_COMP_DIV(sc, SC_CLK_CTRL, 0, 8); +static T7_COMP_GATE(sc, SC_CLK_CTRL, 8, 0); + +static const struct clk_parent_data t7_dsp_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "hifi", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv7", }, + { .hw = &t7_rtc.hw }, +}; + +static T7_COMP_SEL(dspa_0, DSPA_CLK_CTRL0, 10, 0x7, t7_dsp_parents); +static T7_COMP_DIV(dspa_0, DSPA_CLK_CTRL0, 0, 10); +static T7_COMP_GATE(dspa_0, DSPA_CLK_CTRL0, 13, CLK_SET_RATE_GATE); + +static T7_COMP_SEL(dspa_1, DSPA_CLK_CTRL0, 26, 0x7, t7_dsp_parents); +static T7_COMP_DIV(dspa_1, DSPA_CLK_CTRL0, 16, 10); +static T7_COMP_GATE(dspa_1, DSPA_CLK_CTRL0, 29, CLK_SET_RATE_GATE); + +static struct clk_regmap t7_dspa = { + .data = &(struct clk_regmap_mux_data){ + .offset = DSPA_CLK_CTRL0, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspa", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_dspa_0.hw, + &t7_dspa_1.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static T7_COMP_SEL(dspb_0, DSPB_CLK_CTRL0, 10, 0x7, t7_dsp_parents); +static T7_COMP_DIV(dspb_0, DSPB_CLK_CTRL0, 0, 10); +static T7_COMP_GATE(dspb_0, DSPB_CLK_CTRL0, 13, CLK_SET_RATE_GATE); + +static T7_COMP_SEL(dspb_1, DSPB_CLK_CTRL0, 26, 0x7, t7_dsp_parents); +static T7_COMP_DIV(dspb_1, DSPB_CLK_CTRL0, 16, 10); +static T7_COMP_GATE(dspb_1, DSPB_CLK_CTRL0, 29, CLK_SET_RATE_GATE); + +static struct clk_regmap t7_dspb = { + .data = &(struct clk_regmap_mux_data){ + .offset = DSPB_CLK_CTRL0, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspb", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_dspb_0.hw, + &t7_dspb_1.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_24m = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLK12_24_CTRL, + .bit_idx = 11, + }, + .hw.init = &(struct clk_init_data) { + .name = "24m", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor t7_24m_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "24m_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_24m.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_12m = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLK12_24_CTRL, + .bit_idx = 10, + }, + .hw.init = &(struct clk_init_data) { + .name = "12m", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_24m_div2.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_25m_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLK12_24_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "25m_div", + .ops = &clk_regmap_divider_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "fix", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_25m = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLK12_24_CTRL, + .bit_idx = 12, + }, + .hw.init = &(struct clk_init_data){ + .name = "25m", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_25m_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data t7_anakin_parents[] = { + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv2", }, + { .fw_name = "vid_pll0", }, + { .fw_name = "mpll1", }, + { .fw_name = "mpll2", }, + { .fw_name = "fdiv2p5", }, +}; + +static T7_COMP_SEL(anakin_0, ANAKIN_CLK_CTRL, 9, 0x7, t7_anakin_parents); +static T7_COMP_DIV(anakin_0, ANAKIN_CLK_CTRL, 0, 7); +static T7_COMP_GATE(anakin_0, ANAKIN_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static T7_COMP_SEL(anakin_1, ANAKIN_CLK_CTRL, 25, 0x7, t7_anakin_parents); +static T7_COMP_DIV(anakin_1, ANAKIN_CLK_CTRL, 16, 7); +static T7_COMP_GATE(anakin_1, ANAKIN_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap t7_anakin_01_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = ANAKIN_CLK_CTRL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "anakin_01_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_anakin_0.hw, + &t7_anakin_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT + }, +}; + +static struct clk_regmap t7_anakin = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANAKIN_CLK_CTRL, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "anakin", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_anakin_01_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT + }, +}; + +static const struct clk_parent_data t7_mipi_csi_phy_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "gp1", }, + { .fw_name = "mpll1", }, + { .fw_name = "mpll2", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, +}; + +static T7_COMP_SEL(mipi_csi_phy_0, MIPI_CSI_PHY_CLK_CTRL, 9, 0x7, t7_mipi_csi_phy_parents); +static T7_COMP_DIV(mipi_csi_phy_0, MIPI_CSI_PHY_CLK_CTRL, 0, 7); +static T7_COMP_GATE(mipi_csi_phy_0, MIPI_CSI_PHY_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static T7_COMP_SEL(mipi_csi_phy_1, MIPI_CSI_PHY_CLK_CTRL, 25, 0x7, t7_mipi_csi_phy_parents); +static T7_COMP_DIV(mipi_csi_phy_1, MIPI_CSI_PHY_CLK_CTRL, 16, 7); +static T7_COMP_GATE(mipi_csi_phy_1, MIPI_CSI_PHY_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap t7_mipi_csi_phy = { + .data = &(struct clk_regmap_mux_data){ + .offset = MIPI_CSI_PHY_CLK_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mipi_csi_phy", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mipi_csi_phy_0.hw, + &t7_mipi_csi_phy_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data t7_mipi_isp_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, + { .fw_name = "mpll2", }, + { .fw_name = "mpll3", }, + { .fw_name = "gp1", }, +}; + +static T7_COMP_SEL(mipi_isp, MIPI_ISP_CLK_CTRL, 9, 0x7, t7_mipi_isp_parents); +static T7_COMP_DIV(mipi_isp, MIPI_ISP_CLK_CTRL, 0, 7); +static T7_COMP_GATE(mipi_isp, MIPI_ISP_CLK_CTRL, 8, 0); + +static struct clk_regmap t7_ts_div = { + .data = &(struct clk_regmap_div_data){ + .offset = TS_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "ts_div", + .ops = &clk_regmap_divider_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_ts = { + .data = &(struct clk_regmap_gate_data){ + .offset = TS_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "ts", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_ts_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data t7_mali_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "gp0", }, + { .fw_name = "gp1", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, +}; + +static T7_COMP_SEL(mali_0, MALI_CLK_CTRL, 9, 0x7, t7_mali_parents); +static T7_COMP_DIV(mali_0, MALI_CLK_CTRL, 0, 7); +static T7_COMP_GATE(mali_0, MALI_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static T7_COMP_SEL(mali_1, MALI_CLK_CTRL, 25, 0x7, t7_mali_parents); +static T7_COMP_DIV(mali_1, MALI_CLK_CTRL, 16, 7); +static T7_COMP_GATE(mali_1, MALI_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap t7_mali = { + .data = &(struct clk_regmap_mux_data){ + .offset = MALI_CLK_CTRL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mali", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mali_0.hw, + &t7_mali_1.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * parent index 2, 3, 4, 5, 6 not connect any clock signal, + * the last parent connect external PAD + */ +static u32 t7_eth_rmii_parents_val_table[] = { 0, 1, 7 }; +static const struct clk_parent_data t7_eth_rmii_parents[] = { + { .fw_name = "fdiv2", }, + { .fw_name = "gp1", }, + { .fw_name = "ext_rmii", }, +}; + +static struct clk_regmap t7_eth_rmii_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = ETH_CLK_CTRL, + .mask = 0x7, + .shift = 9, + .table = t7_eth_rmii_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "eth_rmii_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = t7_eth_rmii_parents, + .num_parents = ARRAY_SIZE(t7_eth_rmii_parents), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap t7_eth_rmii_div = { + .data = &(struct clk_regmap_div_data) { + .offset = ETH_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "eth_rmii_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_eth_rmii_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_eth_rmii = { + .data = &(struct clk_regmap_gate_data) { + .offset = ETH_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "eth_rmii", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_eth_rmii_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor t7_fdiv2_div8 = { + .mult = 1, + .div = 8, + .hw.init = &(struct clk_init_data){ + .name = "fdiv2_div8", + .ops = &clk_fixed_factor_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "fdiv2", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_eth_125m = { + .data = &(struct clk_regmap_gate_data) { + .offset = ETH_CLK_CTRL, + .bit_idx = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "eth_125m", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_fdiv2_div8.hw + }, + .num_parents = 1, + }, +}; + +static const struct clk_parent_data t7_sd_emmc_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv3", }, + { .fw_name = "hifi", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "mpll2", }, + { .fw_name = "mpll3", }, + { .fw_name = "gp0", }, +}; + +static T7_COMP_SEL(sd_emmc_a, SD_EMMC_CLK_CTRL, 9, 0x7, t7_sd_emmc_parents); +static T7_COMP_DIV(sd_emmc_a, SD_EMMC_CLK_CTRL, 0, 7); +static T7_COMP_GATE(sd_emmc_a, SD_EMMC_CLK_CTRL, 7, 0); + +static T7_COMP_SEL(sd_emmc_b, SD_EMMC_CLK_CTRL, 25, 0x7, t7_sd_emmc_parents); +static T7_COMP_DIV(sd_emmc_b, SD_EMMC_CLK_CTRL, 16, 7); +static T7_COMP_GATE(sd_emmc_b, SD_EMMC_CLK_CTRL, 23, 0); + +static T7_COMP_SEL(sd_emmc_c, NAND_CLK_CTRL, 9, 0x7, t7_sd_emmc_parents); +static T7_COMP_DIV(sd_emmc_c, NAND_CLK_CTRL, 0, 7); +static T7_COMP_GATE(sd_emmc_c, NAND_CLK_CTRL, 7, 0); + +static const struct clk_parent_data t7_spicc_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "sys", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, + { .fw_name = "gp1", }, +}; + +static T7_COMP_SEL(spicc0, SPICC_CLK_CTRL, 7, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc0, SPICC_CLK_CTRL, 0, 6); +static T7_COMP_GATE(spicc0, SPICC_CLK_CTRL, 6, 0); + +static T7_COMP_SEL(spicc1, SPICC_CLK_CTRL, 23, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc1, SPICC_CLK_CTRL, 16, 6); +static T7_COMP_GATE(spicc1, SPICC_CLK_CTRL, 22, 0); + +static T7_COMP_SEL(spicc2, SPICC_CLK_CTRL1, 7, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc2, SPICC_CLK_CTRL1, 0, 6); +static T7_COMP_GATE(spicc2, SPICC_CLK_CTRL1, 6, 0); + +static T7_COMP_SEL(spicc3, SPICC_CLK_CTRL1, 23, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc3, SPICC_CLK_CTRL1, 16, 6); +static T7_COMP_GATE(spicc3, SPICC_CLK_CTRL1, 22, 0); + +static T7_COMP_SEL(spicc4, SPICC_CLK_CTRL2, 7, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc4, SPICC_CLK_CTRL2, 0, 6); +static T7_COMP_GATE(spicc4, SPICC_CLK_CTRL2, 6, 0); + +static T7_COMP_SEL(spicc5, SPICC_CLK_CTRL2, 23, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc5, SPICC_CLK_CTRL2, 16, 6); +static T7_COMP_GATE(spicc5, SPICC_CLK_CTRL2, 22, 0); + +static const struct clk_parent_data t7_saradc_parents[] = { + { .fw_name = "xtal" }, + { .fw_name = "sys" }, +}; + +static T7_COMP_SEL(saradc, SAR_CLK_CTRL0, 9, 0x1, t7_saradc_parents); +static T7_COMP_DIV(saradc, SAR_CLK_CTRL0, 0, 8); +static T7_COMP_GATE(saradc, SAR_CLK_CTRL0, 8, 0); + +static const struct clk_parent_data t7_pwm_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "vid_pll0", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, +}; + +static T7_COMP_SEL(pwm_a, PWM_CLK_AB_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_a, PWM_CLK_AB_CTRL, 0, 8); +static T7_COMP_GATE(pwm_a, PWM_CLK_AB_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_b, PWM_CLK_AB_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_b, PWM_CLK_AB_CTRL, 16, 8); +static T7_COMP_GATE(pwm_b, PWM_CLK_AB_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_c, PWM_CLK_CD_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_c, PWM_CLK_CD_CTRL, 0, 8); +static T7_COMP_GATE(pwm_c, PWM_CLK_CD_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_d, PWM_CLK_CD_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_d, PWM_CLK_CD_CTRL, 16, 8); +static T7_COMP_GATE(pwm_d, PWM_CLK_CD_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_e, PWM_CLK_EF_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_e, PWM_CLK_EF_CTRL, 0, 8); +static T7_COMP_GATE(pwm_e, PWM_CLK_EF_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_f, PWM_CLK_EF_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_f, PWM_CLK_EF_CTRL, 16, 8); +static T7_COMP_GATE(pwm_f, PWM_CLK_EF_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_ao_a, PWM_CLK_AO_AB_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_a, PWM_CLK_AO_AB_CTRL, 0, 8); +static T7_COMP_GATE(pwm_ao_a, PWM_CLK_AO_AB_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_ao_b, PWM_CLK_AO_AB_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_b, PWM_CLK_AO_AB_CTRL, 16, 8); +static T7_COMP_GATE(pwm_ao_b, PWM_CLK_AO_AB_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_ao_c, PWM_CLK_AO_CD_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_c, PWM_CLK_AO_CD_CTRL, 0, 8); +static T7_COMP_GATE(pwm_ao_c, PWM_CLK_AO_CD_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_ao_d, PWM_CLK_AO_CD_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_d, PWM_CLK_AO_CD_CTRL, 16, 8); +static T7_COMP_GATE(pwm_ao_d, PWM_CLK_AO_CD_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_ao_e, PWM_CLK_AO_EF_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_e, PWM_CLK_AO_EF_CTRL, 0, 8); +static T7_COMP_GATE(pwm_ao_e, PWM_CLK_AO_EF_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_ao_f, PWM_CLK_AO_EF_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_f, PWM_CLK_AO_EF_CTRL, 16, 8); +static T7_COMP_GATE(pwm_ao_f, PWM_CLK_AO_EF_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_ao_g, PWM_CLK_AO_GH_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_g, PWM_CLK_AO_GH_CTRL, 0, 8); +static T7_COMP_GATE(pwm_ao_g, PWM_CLK_AO_GH_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_ao_h, PWM_CLK_AO_GH_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_h, PWM_CLK_AO_GH_CTRL, 16, 8); +static T7_COMP_GATE(pwm_ao_h, PWM_CLK_AO_GH_CTRL, 24, 0); + +static const struct clk_parent_data t7_sys_pclk_parents = { .fw_name = "sys" }; + +#define T7_SYS_PCLK(_name, _reg, _bit, _flags) \ + MESON_PCLK(t7_##_name, _reg, _bit, &t7_sys_pclk_parents, _flags) + +static T7_SYS_PCLK(sys_ddr, SYS_CLK_EN0_REG0, 0, 0); +static T7_SYS_PCLK(sys_dos, SYS_CLK_EN0_REG0, 1, 0); +static T7_SYS_PCLK(sys_mipi_dsi_a, SYS_CLK_EN0_REG0, 2, 0); +static T7_SYS_PCLK(sys_mipi_dsi_b, SYS_CLK_EN0_REG0, 3, 0); +static T7_SYS_PCLK(sys_ethphy, SYS_CLK_EN0_REG0, 4, 0); +static T7_SYS_PCLK(sys_mali, SYS_CLK_EN0_REG0, 6, 0); +static T7_SYS_PCLK(sys_aocpu, SYS_CLK_EN0_REG0, 13, 0); +static T7_SYS_PCLK(sys_aucpu, SYS_CLK_EN0_REG0, 14, 0); +static T7_SYS_PCLK(sys_cec, SYS_CLK_EN0_REG0, 16, 0); +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); +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); +static T7_SYS_PCLK(sys_smartcard, SYS_CLK_EN0_REG0, 27, 0); +static T7_SYS_PCLK(sys_acodec, SYS_CLK_EN0_REG0, 28, 0); +static T7_SYS_PCLK(sys_spifc, SYS_CLK_EN0_REG0, 29, 0); +static T7_SYS_PCLK(sys_msr_clk, SYS_CLK_EN0_REG0, 30, 0); +static T7_SYS_PCLK(sys_ir_ctrl, SYS_CLK_EN0_REG0, 31, 0); +static T7_SYS_PCLK(sys_audio, SYS_CLK_EN0_REG1, 0, 0); +static T7_SYS_PCLK(sys_eth, SYS_CLK_EN0_REG1, 3, 0); +static T7_SYS_PCLK(sys_uart_a, SYS_CLK_EN0_REG1, 5, 0); +static T7_SYS_PCLK(sys_uart_b, SYS_CLK_EN0_REG1, 6, 0); +static T7_SYS_PCLK(sys_uart_c, SYS_CLK_EN0_REG1, 7, 0); +static T7_SYS_PCLK(sys_uart_d, SYS_CLK_EN0_REG1, 8, 0); +static T7_SYS_PCLK(sys_uart_e, SYS_CLK_EN0_REG1, 9, 0); +static T7_SYS_PCLK(sys_uart_f, SYS_CLK_EN0_REG1, 10, 0); +static T7_SYS_PCLK(sys_aififo, SYS_CLK_EN0_REG1, 11, 0); +static T7_SYS_PCLK(sys_spicc2, SYS_CLK_EN0_REG1, 12, 0); +static T7_SYS_PCLK(sys_spicc3, SYS_CLK_EN0_REG1, 13, 0); +static T7_SYS_PCLK(sys_spicc4, SYS_CLK_EN0_REG1, 14, 0); +static T7_SYS_PCLK(sys_ts_a73, SYS_CLK_EN0_REG1, 15, 0); +static T7_SYS_PCLK(sys_ts_a53, SYS_CLK_EN0_REG1, 16, 0); +static T7_SYS_PCLK(sys_spicc5, SYS_CLK_EN0_REG1, 17, 0); +static T7_SYS_PCLK(sys_g2d, SYS_CLK_EN0_REG1, 20, 0); +static T7_SYS_PCLK(sys_spicc0, SYS_CLK_EN0_REG1, 21, 0); +static T7_SYS_PCLK(sys_spicc1, SYS_CLK_EN0_REG1, 22, 0); +static T7_SYS_PCLK(sys_pcie, SYS_CLK_EN0_REG1, 24, 0); +static T7_SYS_PCLK(sys_usb, SYS_CLK_EN0_REG1, 26, 0); +static T7_SYS_PCLK(sys_pcie_phy, SYS_CLK_EN0_REG1, 27, 0); +static T7_SYS_PCLK(sys_i2c_ao_a, SYS_CLK_EN0_REG1, 28, 0); +static T7_SYS_PCLK(sys_i2c_ao_b, SYS_CLK_EN0_REG1, 29, 0); +static T7_SYS_PCLK(sys_i2c_m_a, SYS_CLK_EN0_REG1, 30, 0); +static T7_SYS_PCLK(sys_i2c_m_b, SYS_CLK_EN0_REG1, 31, 0); +static T7_SYS_PCLK(sys_i2c_m_c, SYS_CLK_EN0_REG2, 0, 0); +static T7_SYS_PCLK(sys_i2c_m_d, SYS_CLK_EN0_REG2, 1, 0); +static T7_SYS_PCLK(sys_i2c_m_e, SYS_CLK_EN0_REG2, 2, 0); +static T7_SYS_PCLK(sys_i2c_m_f, SYS_CLK_EN0_REG2, 3, 0); +static T7_SYS_PCLK(sys_hdmitx_apb, SYS_CLK_EN0_REG2, 4, 0); +static T7_SYS_PCLK(sys_i2c_s_a, SYS_CLK_EN0_REG2, 5, 0); +static T7_SYS_PCLK(sys_hdmirx_pclk, SYS_CLK_EN0_REG2, 8, 0); +static T7_SYS_PCLK(sys_mmc_apb, SYS_CLK_EN0_REG2, 11, 0); +static T7_SYS_PCLK(sys_mipi_isp_pclk, SYS_CLK_EN0_REG2, 17, 0); +static T7_SYS_PCLK(sys_rsa, SYS_CLK_EN0_REG2, 18, 0); +static T7_SYS_PCLK(sys_pclk_sys_apb, SYS_CLK_EN0_REG2, 19, 0); +static T7_SYS_PCLK(sys_a73pclk_apb, SYS_CLK_EN0_REG2, 20, 0); +static T7_SYS_PCLK(sys_dspa, SYS_CLK_EN0_REG2, 21, 0); +static T7_SYS_PCLK(sys_dspb, SYS_CLK_EN0_REG2, 22, 0); +static T7_SYS_PCLK(sys_vpu_intr, SYS_CLK_EN0_REG2, 25, 0); +static T7_SYS_PCLK(sys_sar_adc, SYS_CLK_EN0_REG2, 28, 0); +/* + * sys_gic provides the clock for GIC(Generic Interrupt Controller). + * After clock is disabled, The GIC cannot work properly. At present, the driver + * used by our GIC is the public driver in kernel, and there is no management + * clock in the driver. + */ +static T7_SYS_PCLK(sys_gic, SYS_CLK_EN0_REG2, 30, CLK_IS_CRITICAL); +static T7_SYS_PCLK(sys_ts_gpu, SYS_CLK_EN0_REG2, 31, 0); +static T7_SYS_PCLK(sys_ts_nna, SYS_CLK_EN0_REG3, 0, 0); +static T7_SYS_PCLK(sys_ts_vpu, SYS_CLK_EN0_REG3, 1, 0); +static T7_SYS_PCLK(sys_ts_hevc, SYS_CLK_EN0_REG3, 2, 0); +static T7_SYS_PCLK(sys_pwm_ao_ab, SYS_CLK_EN0_REG3, 3, 0); +static T7_SYS_PCLK(sys_pwm_ao_cd, SYS_CLK_EN0_REG3, 4, 0); +static T7_SYS_PCLK(sys_pwm_ao_ef, SYS_CLK_EN0_REG3, 5, 0); +static T7_SYS_PCLK(sys_pwm_ao_gh, SYS_CLK_EN0_REG3, 6, 0); +static T7_SYS_PCLK(sys_pwm_ab, SYS_CLK_EN0_REG3, 7, 0); +static T7_SYS_PCLK(sys_pwm_cd, SYS_CLK_EN0_REG3, 8, 0); +static T7_SYS_PCLK(sys_pwm_ef, SYS_CLK_EN0_REG3, 9, 0); + +/* Array of all clocks registered by this provider */ +static struct clk_hw *t7_peripherals_hw_clks[] = { + [CLKID_RTC_DUALDIV_IN] = &t7_rtc_dualdiv_in.hw, + [CLKID_RTC_DUALDIV_DIV] = &t7_rtc_dualdiv_div.hw, + [CLKID_RTC_DUALDIV_SEL] = &t7_rtc_dualdiv_sel.hw, + [CLKID_RTC_DUALDIV] = &t7_rtc_dualdiv.hw, + [CLKID_RTC] = &t7_rtc.hw, + [CLKID_CECA_DUALDIV_IN] = &t7_ceca_dualdiv_in.hw, + [CLKID_CECA_DUALDIV_DIV] = &t7_ceca_dualdiv_div.hw, + [CLKID_CECA_DUALDIV_SEL] = &t7_ceca_dualdiv_sel.hw, + [CLKID_CECA_DUALDIV] = &t7_ceca_dualdiv.hw, + [CLKID_CECA] = &t7_ceca.hw, + [CLKID_CECB_DUALDIV_IN] = &t7_cecb_dualdiv_in.hw, + [CLKID_CECB_DUALDIV_DIV] = &t7_cecb_dualdiv_div.hw, + [CLKID_CECB_DUALDIV_SEL] = &t7_cecb_dualdiv_sel.hw, + [CLKID_CECB_DUALDIV] = &t7_cecb_dualdiv.hw, + [CLKID_CECB] = &t7_cecb.hw, + [CLKID_SC_SEL] = &t7_sc_sel.hw, + [CLKID_SC_DIV] = &t7_sc_div.hw, + [CLKID_SC] = &t7_sc.hw, + [CLKID_DSPA_0_SEL] = &t7_dspa_0_sel.hw, + [CLKID_DSPA_0_DIV] = &t7_dspa_0_div.hw, + [CLKID_DSPA_0] = &t7_dspa_0.hw, + [CLKID_DSPA_1_SEL] = &t7_dspa_1_sel.hw, + [CLKID_DSPA_1_DIV] = &t7_dspa_1_div.hw, + [CLKID_DSPA_1] = &t7_dspa_1.hw, + [CLKID_DSPA] = &t7_dspa.hw, + [CLKID_DSPB_0_SEL] = &t7_dspb_0_sel.hw, + [CLKID_DSPB_0_DIV] = &t7_dspb_0_div.hw, + [CLKID_DSPB_0] = &t7_dspb_0.hw, + [CLKID_DSPB_1_SEL] = &t7_dspb_1_sel.hw, + [CLKID_DSPB_1_DIV] = &t7_dspb_1_div.hw, + [CLKID_DSPB_1] = &t7_dspb_1.hw, + [CLKID_DSPB] = &t7_dspb.hw, + [CLKID_24M] = &t7_24m.hw, + [CLKID_24M_DIV2] = &t7_24m_div2.hw, + [CLKID_12M] = &t7_12m.hw, + [CLKID_25M_DIV] = &t7_25m_div.hw, + [CLKID_25M] = &t7_25m.hw, + [CLKID_ANAKIN_0_SEL] = &t7_anakin_0_sel.hw, + [CLKID_ANAKIN_0_DIV] = &t7_anakin_0_div.hw, + [CLKID_ANAKIN_0] = &t7_anakin_0.hw, + [CLKID_ANAKIN_1_SEL] = &t7_anakin_1_sel.hw, + [CLKID_ANAKIN_1_DIV] = &t7_anakin_1_div.hw, + [CLKID_ANAKIN_1] = &t7_anakin_1.hw, + [CLKID_ANAKIN_01_SEL] = &t7_anakin_01_sel.hw, + [CLKID_ANAKIN] = &t7_anakin.hw, + [CLKID_MIPI_CSI_PHY_0_SEL] = &t7_mipi_csi_phy_0_sel.hw, + [CLKID_MIPI_CSI_PHY_0_DIV] = &t7_mipi_csi_phy_0_div.hw, + [CLKID_MIPI_CSI_PHY_0] = &t7_mipi_csi_phy_0.hw, + [CLKID_MIPI_CSI_PHY_1_SEL] = &t7_mipi_csi_phy_1_sel.hw, + [CLKID_MIPI_CSI_PHY_1_DIV] = &t7_mipi_csi_phy_1_div.hw, + [CLKID_MIPI_CSI_PHY_1] = &t7_mipi_csi_phy_1.hw, + [CLKID_MIPI_CSI_PHY] = &t7_mipi_csi_phy.hw, + [CLKID_MIPI_ISP_SEL] = &t7_mipi_isp_sel.hw, + [CLKID_MIPI_ISP_DIV] = &t7_mipi_isp_div.hw, + [CLKID_MIPI_ISP] = &t7_mipi_isp.hw, + [CLKID_TS_DIV] = &t7_ts_div.hw, + [CLKID_TS] = &t7_ts.hw, + [CLKID_MALI_0_SEL] = &t7_mali_0_sel.hw, + [CLKID_MALI_0_DIV] = &t7_mali_0_div.hw, + [CLKID_MALI_0] = &t7_mali_0.hw, + [CLKID_MALI_1_SEL] = &t7_mali_1_sel.hw, + [CLKID_MALI_1_DIV] = &t7_mali_1_div.hw, + [CLKID_MALI_1] = &t7_mali_1.hw, + [CLKID_MALI] = &t7_mali.hw, + [CLKID_ETH_RMII_SEL] = &t7_eth_rmii_sel.hw, + [CLKID_ETH_RMII_DIV] = &t7_eth_rmii_div.hw, + [CLKID_ETH_RMII] = &t7_eth_rmii.hw, + [CLKID_FCLK_DIV2_DIV8] = &t7_fdiv2_div8.hw, + [CLKID_ETH_125M] = &t7_eth_125m.hw, + [CLKID_SD_EMMC_A_SEL] = &t7_sd_emmc_a_sel.hw, + [CLKID_SD_EMMC_A_DIV] = &t7_sd_emmc_a_div.hw, + [CLKID_SD_EMMC_A] = &t7_sd_emmc_a.hw, + [CLKID_SD_EMMC_B_SEL] = &t7_sd_emmc_b_sel.hw, + [CLKID_SD_EMMC_B_DIV] = &t7_sd_emmc_b_div.hw, + [CLKID_SD_EMMC_B] = &t7_sd_emmc_b.hw, + [CLKID_SD_EMMC_C_SEL] = &t7_sd_emmc_c_sel.hw, + [CLKID_SD_EMMC_C_DIV] = &t7_sd_emmc_c_div.hw, + [CLKID_SD_EMMC_C] = &t7_sd_emmc_c.hw, + [CLKID_SPICC0_SEL] = &t7_spicc0_sel.hw, + [CLKID_SPICC0_DIV] = &t7_spicc0_div.hw, + [CLKID_SPICC0] = &t7_spicc0.hw, + [CLKID_SPICC1_SEL] = &t7_spicc1_sel.hw, + [CLKID_SPICC1_DIV] = &t7_spicc1_div.hw, + [CLKID_SPICC1] = &t7_spicc1.hw, + [CLKID_SPICC2_SEL] = &t7_spicc2_sel.hw, + [CLKID_SPICC2_DIV] = &t7_spicc2_div.hw, + [CLKID_SPICC2] = &t7_spicc2.hw, + [CLKID_SPICC3_SEL] = &t7_spicc3_sel.hw, + [CLKID_SPICC3_DIV] = &t7_spicc3_div.hw, + [CLKID_SPICC3] = &t7_spicc3.hw, + [CLKID_SPICC4_SEL] = &t7_spicc4_sel.hw, + [CLKID_SPICC4_DIV] = &t7_spicc4_div.hw, + [CLKID_SPICC4] = &t7_spicc4.hw, + [CLKID_SPICC5_SEL] = &t7_spicc5_sel.hw, + [CLKID_SPICC5_DIV] = &t7_spicc5_div.hw, + [CLKID_SPICC5] = &t7_spicc5.hw, + [CLKID_SARADC_SEL] = &t7_saradc_sel.hw, + [CLKID_SARADC_DIV] = &t7_saradc_div.hw, + [CLKID_SARADC] = &t7_saradc.hw, + [CLKID_PWM_A_SEL] = &t7_pwm_a_sel.hw, + [CLKID_PWM_A_DIV] = &t7_pwm_a_div.hw, + [CLKID_PWM_A] = &t7_pwm_a.hw, + [CLKID_PWM_B_SEL] = &t7_pwm_b_sel.hw, + [CLKID_PWM_B_DIV] = &t7_pwm_b_div.hw, + [CLKID_PWM_B] = &t7_pwm_b.hw, + [CLKID_PWM_C_SEL] = &t7_pwm_c_sel.hw, + [CLKID_PWM_C_DIV] = &t7_pwm_c_div.hw, + [CLKID_PWM_C] = &t7_pwm_c.hw, + [CLKID_PWM_D_SEL] = &t7_pwm_d_sel.hw, + [CLKID_PWM_D_DIV] = &t7_pwm_d_div.hw, + [CLKID_PWM_D] = &t7_pwm_d.hw, + [CLKID_PWM_E_SEL] = &t7_pwm_e_sel.hw, + [CLKID_PWM_E_DIV] = &t7_pwm_e_div.hw, + [CLKID_PWM_E] = &t7_pwm_e.hw, + [CLKID_PWM_F_SEL] = &t7_pwm_f_sel.hw, + [CLKID_PWM_F_DIV] = &t7_pwm_f_div.hw, + [CLKID_PWM_F] = &t7_pwm_f.hw, + [CLKID_PWM_AO_A_SEL] = &t7_pwm_ao_a_sel.hw, + [CLKID_PWM_AO_A_DIV] = &t7_pwm_ao_a_div.hw, + [CLKID_PWM_AO_A] = &t7_pwm_ao_a.hw, + [CLKID_PWM_AO_B_SEL] = &t7_pwm_ao_b_sel.hw, + [CLKID_PWM_AO_B_DIV] = &t7_pwm_ao_b_div.hw, + [CLKID_PWM_AO_B] = &t7_pwm_ao_b.hw, + [CLKID_PWM_AO_C_SEL] = &t7_pwm_ao_c_sel.hw, + [CLKID_PWM_AO_C_DIV] = &t7_pwm_ao_c_div.hw, + [CLKID_PWM_AO_C] = &t7_pwm_ao_c.hw, + [CLKID_PWM_AO_D_SEL] = &t7_pwm_ao_d_sel.hw, + [CLKID_PWM_AO_D_DIV] = &t7_pwm_ao_d_div.hw, + [CLKID_PWM_AO_D] = &t7_pwm_ao_d.hw, + [CLKID_PWM_AO_E_SEL] = &t7_pwm_ao_e_sel.hw, + [CLKID_PWM_AO_E_DIV] = &t7_pwm_ao_e_div.hw, + [CLKID_PWM_AO_E] = &t7_pwm_ao_e.hw, + [CLKID_PWM_AO_F_SEL] = &t7_pwm_ao_f_sel.hw, + [CLKID_PWM_AO_F_DIV] = &t7_pwm_ao_f_div.hw, + [CLKID_PWM_AO_F] = &t7_pwm_ao_f.hw, + [CLKID_PWM_AO_G_SEL] = &t7_pwm_ao_g_sel.hw, + [CLKID_PWM_AO_G_DIV] = &t7_pwm_ao_g_div.hw, + [CLKID_PWM_AO_G] = &t7_pwm_ao_g.hw, + [CLKID_PWM_AO_H_SEL] = &t7_pwm_ao_h_sel.hw, + [CLKID_PWM_AO_H_DIV] = &t7_pwm_ao_h_div.hw, + [CLKID_PWM_AO_H] = &t7_pwm_ao_h.hw, + [CLKID_SYS_DDR] = &t7_sys_ddr.hw, + [CLKID_SYS_DOS] = &t7_sys_dos.hw, + [CLKID_SYS_MIPI_DSI_A] = &t7_sys_mipi_dsi_a.hw, + [CLKID_SYS_MIPI_DSI_B] = &t7_sys_mipi_dsi_b.hw, + [CLKID_SYS_ETHPHY] = &t7_sys_ethphy.hw, + [CLKID_SYS_MALI] = &t7_sys_mali.hw, + [CLKID_SYS_AOCPU] = &t7_sys_aocpu.hw, + [CLKID_SYS_AUCPU] = &t7_sys_aucpu.hw, + [CLKID_SYS_CEC] = &t7_sys_cec.hw, + [CLKID_SYS_GDC] = &t7_sys_gdc.hw, + [CLKID_SYS_DESWARP] = &t7_sys_deswarp.hw, + [CLKID_SYS_AMPIPE_NAND] = &t7_sys_ampipe_nand.hw, + [CLKID_SYS_AMPIPE_ETH] = &t7_sys_ampipe_eth.hw, + [CLKID_SYS_AM2AXI0] = &t7_sys_am2axi0.hw, + [CLKID_SYS_AM2AXI1] = &t7_sys_am2axi1.hw, + [CLKID_SYS_AM2AXI2] = &t7_sys_am2axi2.hw, + [CLKID_SYS_SD_EMMC_A] = &t7_sys_sd_emmc_a.hw, + [CLKID_SYS_SD_EMMC_B] = &t7_sys_sd_emmc_b.hw, + [CLKID_SYS_SD_EMMC_C] = &t7_sys_sd_emmc_c.hw, + [CLKID_SYS_SMARTCARD] = &t7_sys_smartcard.hw, + [CLKID_SYS_ACODEC] = &t7_sys_acodec.hw, + [CLKID_SYS_SPIFC] = &t7_sys_spifc.hw, + [CLKID_SYS_MSR_CLK] = &t7_sys_msr_clk.hw, + [CLKID_SYS_IR_CTRL] = &t7_sys_ir_ctrl.hw, + [CLKID_SYS_AUDIO] = &t7_sys_audio.hw, + [CLKID_SYS_ETH] = &t7_sys_eth.hw, + [CLKID_SYS_UART_A] = &t7_sys_uart_a.hw, + [CLKID_SYS_UART_B] = &t7_sys_uart_b.hw, + [CLKID_SYS_UART_C] = &t7_sys_uart_c.hw, + [CLKID_SYS_UART_D] = &t7_sys_uart_d.hw, + [CLKID_SYS_UART_E] = &t7_sys_uart_e.hw, + [CLKID_SYS_UART_F] = &t7_sys_uart_f.hw, + [CLKID_SYS_AIFIFO] = &t7_sys_aififo.hw, + [CLKID_SYS_SPICC2] = &t7_sys_spicc2.hw, + [CLKID_SYS_SPICC3] = &t7_sys_spicc3.hw, + [CLKID_SYS_SPICC4] = &t7_sys_spicc4.hw, + [CLKID_SYS_TS_A73] = &t7_sys_ts_a73.hw, + [CLKID_SYS_TS_A53] = &t7_sys_ts_a53.hw, + [CLKID_SYS_SPICC5] = &t7_sys_spicc5.hw, + [CLKID_SYS_G2D] = &t7_sys_g2d.hw, + [CLKID_SYS_SPICC0] = &t7_sys_spicc0.hw, + [CLKID_SYS_SPICC1] = &t7_sys_spicc1.hw, + [CLKID_SYS_PCIE] = &t7_sys_pcie.hw, + [CLKID_SYS_USB] = &t7_sys_usb.hw, + [CLKID_SYS_PCIE_PHY] = &t7_sys_pcie_phy.hw, + [CLKID_SYS_I2C_AO_A] = &t7_sys_i2c_ao_a.hw, + [CLKID_SYS_I2C_AO_B] = &t7_sys_i2c_ao_b.hw, + [CLKID_SYS_I2C_M_A] = &t7_sys_i2c_m_a.hw, + [CLKID_SYS_I2C_M_B] = &t7_sys_i2c_m_b.hw, + [CLKID_SYS_I2C_M_C] = &t7_sys_i2c_m_c.hw, + [CLKID_SYS_I2C_M_D] = &t7_sys_i2c_m_d.hw, + [CLKID_SYS_I2C_M_E] = &t7_sys_i2c_m_e.hw, + [CLKID_SYS_I2C_M_F] = &t7_sys_i2c_m_f.hw, + [CLKID_SYS_HDMITX_APB] = &t7_sys_hdmitx_apb.hw, + [CLKID_SYS_I2C_S_A] = &t7_sys_i2c_s_a.hw, + [CLKID_SYS_HDMIRX_PCLK] = &t7_sys_hdmirx_pclk.hw, + [CLKID_SYS_MMC_APB] = &t7_sys_mmc_apb.hw, + [CLKID_SYS_MIPI_ISP_PCLK] = &t7_sys_mipi_isp_pclk.hw, + [CLKID_SYS_RSA] = &t7_sys_rsa.hw, + [CLKID_SYS_PCLK_SYS_APB] = &t7_sys_pclk_sys_apb.hw, + [CLKID_SYS_A73PCLK_APB] = &t7_sys_a73pclk_apb.hw, + [CLKID_SYS_DSPA] = &t7_sys_dspa.hw, + [CLKID_SYS_DSPB] = &t7_sys_dspb.hw, + [CLKID_SYS_VPU_INTR] = &t7_sys_vpu_intr.hw, + [CLKID_SYS_SAR_ADC] = &t7_sys_sar_adc.hw, + [CLKID_SYS_GIC] = &t7_sys_gic.hw, + [CLKID_SYS_TS_GPU] = &t7_sys_ts_gpu.hw, + [CLKID_SYS_TS_NNA] = &t7_sys_ts_nna.hw, + [CLKID_SYS_TS_VPU] = &t7_sys_ts_vpu.hw, + [CLKID_SYS_TS_HEVC] = &t7_sys_ts_hevc.hw, + [CLKID_SYS_PWM_AO_AB] = &t7_sys_pwm_ao_ab.hw, + [CLKID_SYS_PWM_AO_CD] = &t7_sys_pwm_ao_cd.hw, + [CLKID_SYS_PWM_AO_EF] = &t7_sys_pwm_ao_ef.hw, + [CLKID_SYS_PWM_AO_GH] = &t7_sys_pwm_ao_gh.hw, + [CLKID_SYS_PWM_AB] = &t7_sys_pwm_ab.hw, + [CLKID_SYS_PWM_CD] = &t7_sys_pwm_cd.hw, + [CLKID_SYS_PWM_EF] = &t7_sys_pwm_ef.hw, +}; + +static const struct meson_clkc_data t7_peripherals_data = { + .hw_clks = { + .hws = t7_peripherals_hw_clks, + .num = ARRAY_SIZE(t7_peripherals_hw_clks), + }, +}; + +static const struct of_device_id t7_peripherals_clkc_match_table[] = { + { + .compatible = "amlogic,t7-peripherals-clkc", + .data = &t7_peripherals_data + }, + {} +}; +MODULE_DEVICE_TABLE(of, t7_peripherals_clkc_match_table); + +static struct platform_driver t7_peripherals_clkc_driver = { + .probe = meson_clkc_mmio_probe, + .driver = { + .name = "t7-peripherals-clkc", + .of_match_table = t7_peripherals_clkc_match_table, + }, +}; +module_platform_driver(t7_peripherals_clkc_driver); + +MODULE_DESCRIPTION("Amlogic T7 Peripherals Clock Controller driver"); +MODULE_AUTHOR("Jian Hu "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("CLK_MESON"); From 29c4f32095d01ec570b05141d20945f22d50da26 Mon Sep 17 00:00:00 2001 From: Chuan Liu Date: Fri, 19 Sep 2025 13:58:59 +0800 Subject: [PATCH 006/165] dt-bindings: clock: add video clock indices for Amlogic S4 SoC Add indices for video encoder, demodulator and CVBS clocks. Acked-by: Rob Herring (Arm) Acked-by: Krzysztof Kozlowski Acked-by: Conor Dooley Signed-off-by: Chuan Liu Link: https://lore.kernel.org/r/20250919-add_video_clk-v6-1-fe223161fb3f@amlogic.com Signed-off-by: Jerome Brunet --- .../dt-bindings/clock/amlogic,s4-peripherals-clkc.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h index 861a331963ac..b0fc549f53e3 100644 --- a/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h +++ b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h @@ -232,5 +232,16 @@ #define CLKID_HDCP22_SKPCLK_SEL 222 #define CLKID_HDCP22_SKPCLK_DIV 223 #define CLKID_HDCP22_SKPCLK 224 +#define CLKID_CTS_ENCL_SEL 225 +#define CLKID_CTS_ENCL 226 +#define CLKID_CDAC_SEL 227 +#define CLKID_CDAC_DIV 228 +#define CLKID_CDAC 229 +#define CLKID_DEMOD_CORE_SEL 230 +#define CLKID_DEMOD_CORE_DIV 231 +#define CLKID_DEMOD_CORE 232 +#define CLKID_ADC_EXTCLK_IN_SEL 233 +#define CLKID_ADC_EXTCLK_IN_DIV 234 +#define CLKID_ADC_EXTCLK_IN 235 #endif /* _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H */ From c78c9dbe2bb950939b3a1fe171c40cfba4f8c520 Mon Sep 17 00:00:00 2001 From: Chuan Liu Date: Fri, 19 Sep 2025 13:59:00 +0800 Subject: [PATCH 007/165] clk: amlogic: add video-related clocks for S4 SoC Add video encoder, demodulator and CVBS clocks. Signed-off-by: Chuan Liu Link: https://lore.kernel.org/r/20250919-add_video_clk-v6-2-fe223161fb3f@amlogic.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/s4-peripherals.c | 202 +++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) diff --git a/drivers/clk/meson/s4-peripherals.c b/drivers/clk/meson/s4-peripherals.c index 6d69b132d1e1..aa500ea8ef9c 100644 --- a/drivers/clk/meson/s4-peripherals.c +++ b/drivers/clk/meson/s4-peripherals.c @@ -44,6 +44,7 @@ #define CLKCTRL_VDIN_MEAS_CLK_CTRL 0x0f8 #define CLKCTRL_VAPBCLK_CTRL 0x0fc #define CLKCTRL_HDCP22_CTRL 0x100 +#define CLKCTRL_CDAC_CLK_CTRL 0x108 #define CLKCTRL_VDEC_CLK_CTRL 0x140 #define CLKCTRL_VDEC2_CLK_CTRL 0x144 #define CLKCTRL_VDEC3_CLK_CTRL 0x148 @@ -1126,6 +1127,21 @@ static struct clk_regmap s4_cts_encp_sel = { }, }; +static struct clk_regmap s4_cts_encl_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VIID_CLK_DIV, + .mask = 0xf, + .shift = 12, + .table = s4_cts_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_encl_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = s4_cts_parents, + .num_parents = ARRAY_SIZE(s4_cts_parents), + }, +}; + static struct clk_regmap s4_cts_vdac_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VIID_CLK_DIV, @@ -1205,6 +1221,22 @@ static struct clk_regmap s4_cts_encp = { }, }; +static struct clk_regmap s4_cts_encl = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL2, + .bit_idx = 3, + }, + .hw.init = &(struct clk_init_data) { + .name = "cts_encl", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cts_encl_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static struct clk_regmap s4_cts_vdac = { .data = &(struct clk_regmap_gate_data){ .offset = CLKCTRL_VID_CLK_CTRL2, @@ -2735,6 +2767,165 @@ static struct clk_regmap s4_gen_clk = { }, }; +/* CVBS DAC */ +static struct clk_regmap s4_cdac_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_CDAC_CLK_CTRL, + .mask = 0x3, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "cdac_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .fw_name = "fclk_div5" }, + }, + .num_parents = 2, + }, +}; + +static struct clk_regmap s4_cdac_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_CDAC_CLK_CTRL, + .shift = 0, + .width = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "cdac_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cdac_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_cdac = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_CDAC_CLK_CTRL, + .bit_idx = 20, + }, + .hw.init = &(struct clk_init_data){ + .name = "cdac", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cdac_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_demod_core_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "demod_core_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal" }, + { .fw_name = "fclk_div7" }, + { .fw_name = "fclk_div4" } + }, + .num_parents = 3, + }, +}; + +static struct clk_regmap s4_demod_core_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "demod_core_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_demod_core_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_demod_core = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .bit_idx = 8 + }, + .hw.init = &(struct clk_init_data){ + .name = "demod_core", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_demod_core_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* CVBS ADC */ +static struct clk_regmap s4_adc_extclk_in_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .mask = 0x7, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "adc_extclk_in_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal" }, + { .fw_name = "fclk_div4" }, + { .fw_name = "fclk_div3" }, + { .fw_name = "fclk_div5" }, + { .fw_name = "fclk_div7" }, + { .fw_name = "mpll2" }, + { .fw_name = "gp0_pll" }, + { .fw_name = "hifi_pll" } + }, + .num_parents = 8, + }, +}; + +static struct clk_regmap s4_adc_extclk_in_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "adc_extclk_in_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_adc_extclk_in_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_adc_extclk_in = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .bit_idx = 24 + }, + .hw.init = &(struct clk_init_data){ + .name = "adc_extclk_in", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_adc_extclk_in_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static const struct clk_parent_data s4_pclk_parents = { .hw = &s4_sys_clk.hw }; #define S4_PCLK(_name, _reg, _bit, _flags) \ @@ -3028,6 +3219,17 @@ static struct clk_hw *s4_peripherals_hw_clks[] = { [CLKID_HDCP22_SKPCLK_SEL] = &s4_hdcp22_skpclk_sel.hw, [CLKID_HDCP22_SKPCLK_DIV] = &s4_hdcp22_skpclk_div.hw, [CLKID_HDCP22_SKPCLK] = &s4_hdcp22_skpclk.hw, + [CLKID_CTS_ENCL_SEL] = &s4_cts_encl_sel.hw, + [CLKID_CTS_ENCL] = &s4_cts_encl.hw, + [CLKID_CDAC_SEL] = &s4_cdac_sel.hw, + [CLKID_CDAC_DIV] = &s4_cdac_div.hw, + [CLKID_CDAC] = &s4_cdac.hw, + [CLKID_DEMOD_CORE_SEL] = &s4_demod_core_sel.hw, + [CLKID_DEMOD_CORE_DIV] = &s4_demod_core_div.hw, + [CLKID_DEMOD_CORE] = &s4_demod_core.hw, + [CLKID_ADC_EXTCLK_IN_SEL] = &s4_adc_extclk_in_sel.hw, + [CLKID_ADC_EXTCLK_IN_DIV] = &s4_adc_extclk_in_div.hw, + [CLKID_ADC_EXTCLK_IN] = &s4_adc_extclk_in.hw, }; static const struct meson_clkc_data s4_peripherals_clkc_data = { From 4aca7e92023cac5018b4053bae324450f884c937 Mon Sep 17 00:00:00 2001 From: Chuan Liu Date: Fri, 19 Sep 2025 13:59:01 +0800 Subject: [PATCH 008/165] clk: amlogic: remove potentially unsafe flags from S4 video clocks The video clocks enci, encp, vdac and hdmitx share the same clock source. Adding CLK_SET_RATE_PARENT to the mux may unintentionally change the shared parent clock, which could affect other video clocks. Signed-off-by: Chuan Liu Link: https://lore.kernel.org/r/20250919-add_video_clk-v6-3-fe223161fb3f@amlogic.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/s4-peripherals.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/clk/meson/s4-peripherals.c b/drivers/clk/meson/s4-peripherals.c index aa500ea8ef9c..ba41fcd90588 100644 --- a/drivers/clk/meson/s4-peripherals.c +++ b/drivers/clk/meson/s4-peripherals.c @@ -1107,7 +1107,6 @@ static struct clk_regmap s4_cts_enci_sel = { .ops = &clk_regmap_mux_ops, .parent_hws = s4_cts_parents, .num_parents = ARRAY_SIZE(s4_cts_parents), - .flags = CLK_SET_RATE_PARENT, }, }; @@ -1123,7 +1122,6 @@ static struct clk_regmap s4_cts_encp_sel = { .ops = &clk_regmap_mux_ops, .parent_hws = s4_cts_parents, .num_parents = ARRAY_SIZE(s4_cts_parents), - .flags = CLK_SET_RATE_PARENT, }, }; @@ -1154,7 +1152,6 @@ static struct clk_regmap s4_cts_vdac_sel = { .ops = &clk_regmap_mux_ops, .parent_hws = s4_cts_parents, .num_parents = ARRAY_SIZE(s4_cts_parents), - .flags = CLK_SET_RATE_PARENT, }, }; @@ -1185,7 +1182,6 @@ static struct clk_regmap s4_hdmi_tx_sel = { .ops = &clk_regmap_mux_ops, .parent_hws = s4_hdmi_tx_parents, .num_parents = ARRAY_SIZE(s4_hdmi_tx_parents), - .flags = CLK_SET_RATE_PARENT, }, }; From a00655d98cd885472c311f01dff3e668d1288d0a Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Fri, 14 Nov 2025 14:37:11 -0500 Subject: [PATCH 009/165] clk: renesas: rzg2l: Fix intin variable size INTIN is a 12-bit register value, so u8 is too small. Fixes: 1561380ee72f ("clk: renesas: rzg2l: Add FOUTPOSTDIV clk support") Cc: stable@vger.kernel.org Reported-by: Hugo Villeneuve Closes: https://lore.kernel.org/20251107113058.f334957151d1a8dd94dd740b@hugovil.com Signed-off-by: Chris Brandt Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251114193711.3277912-1-chris.brandt@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rzg2l-cpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 64d1ef6e4c94..dfe0f5e87d8c 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -122,8 +122,8 @@ struct div_hw_data { struct rzg2l_pll5_param { u32 pl5_fracin; + u16 pl5_intin; u8 pl5_refdiv; - u8 pl5_intin; u8 pl5_postdiv1; u8 pl5_postdiv2; u8 pl5_spread; From f9451374dcfdfe669ee55b58ee6c11e8638980e4 Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Fri, 14 Nov 2025 14:45:29 -0500 Subject: [PATCH 010/165] clk: renesas: rzg2l: Select correct div round macro Variable foutvco_rate is an unsigned long, not an unsigned long long. Cc: stable@kernel.org Reported-by: Geert Uytterhoeven Closes: https://lore.kernel.org/CAMuHMdVf7dSeqAhtyxDCFuCheQRzwS-8996Rr2Ntui21uiBgdA@mail.gmail.com Fixes: dabf72b85f29 ("clk: renesas: rzg2l: Fix FOUTPOSTDIV clk") Signed-off-by: Chris Brandt Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251114194529.3304361-1-chris.brandt@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rzg2l-cpg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index dfe0f5e87d8c..0bcf64b152e0 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -572,8 +572,8 @@ rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params, foutvco_rate = div_u64(mul_u32_u32(EXTAL_FREQ_IN_MEGA_HZ * MEGA, (params->pl5_intin << 24) + params->pl5_fracin), params->pl5_refdiv) >> 24; - foutpostdiv_rate = DIV_ROUND_CLOSEST_ULL(foutvco_rate, - params->pl5_postdiv1 * params->pl5_postdiv2); + foutpostdiv_rate = DIV_ROUND_CLOSEST(foutvco_rate, + params->pl5_postdiv1 * params->pl5_postdiv2); return foutpostdiv_rate; } From ec74d201e697503d8460597e2c3cc5ade222c4fb Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 17 Nov 2025 20:56:27 +0000 Subject: [PATCH 011/165] clk: renesas: r9a09g077: Add xSPI core and module clocks Add core clocks and module clock definitions required by the xSPI (Expanded SPI) IP on the R9A09G077 SoC. Define the new SCKCR fields FSELXSPI0/FSELXSPI1 and DIVSEL_XSPI0/1 and add two new core clocks XSPI_CLK0 and XSPI_CLK1. The xSPI block uses PCLKH as its bus clock (use as module clock parent) while the operation clock (XSPI_CLKn) is derived from PLL4. To support this arrangement provide mux/div selectors and divider tables for the supported XSPI operating rates. Add CLK_TYPE_RZT2H_FSELXSPI to implement a custom divider/mux clock where the determine_rate() callback enforces the hardware constraint: when the parent output is 600MHz only dividers 8 and 16 are valid, whereas for 800MHz operation the full divider set (6,8,16,32,64) may be used. The custom determine_rate() picks the best parent/divider pair to match the requested rate and programs the appropriate SCKCR fields. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251117205627.39376-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g077-cpg.c | 193 +++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 3 deletions(-) diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index fb6cc94d08a1..07d6cc57b3d9 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include @@ -41,6 +43,12 @@ #define GET_WIDTH(val) FIELD_GET(WIDTH_MASK, val) #define GET_REG_OFFSET(val) FIELD_GET(OFFSET_MASK, val) +#define FSELXSPI0 CONF_PACK(SCKCR, 0, 3) +#define FSELXSPI1 CONF_PACK(SCKCR, 8, 3) +#define DIVSEL_XSPI0 CONF_PACK(SCKCR, 6, 1) +#define DIVSEL_XSPI1 CONF_PACK(SCKCR, 14, 1) +#define SEL_PLL CONF_PACK(SCKCR, 22, 1) + #define DIVCA55C0 CONF_PACK(SCKCR2, 8, 1) #define DIVCA55C1 CONF_PACK(SCKCR2, 9, 1) #define DIVCA55C2 CONF_PACK(SCKCR2, 10, 1) @@ -58,11 +66,10 @@ #define DIVSCI3ASYNC CONF_PACK(SCKCR3, 12, 2) #define DIVSCI4ASYNC CONF_PACK(SCKCR3, 14, 2) -#define SEL_PLL CONF_PACK(SCKCR, 22, 1) - enum rzt2h_clk_types { CLK_TYPE_RZT2H_DIV = CLK_TYPE_CUSTOM, /* Clock with divider */ CLK_TYPE_RZT2H_MUX, /* Clock with clock source selector */ + CLK_TYPE_RZT2H_FSELXSPI, /* Clock with FSELXSPIn source selector */ }; #define DEF_DIV(_name, _id, _parent, _conf, _dtable) \ @@ -72,10 +79,13 @@ enum rzt2h_clk_types { DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_MUX, .conf = _conf, \ .parent_names = _parent_names, .num_parents = _num_parents, \ .flag = 0, .mux_flags = _mux_flags) +#define DEF_DIV_FSELXSPI(_name, _id, _parent, _conf, _dtable) \ + DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_FSELXSPI, .conf = _conf, \ + .parent = _parent, .dtable = _dtable, .flag = 0) enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G077_ETCLKE, + LAST_DT_CORE_CLK = R9A09G077_XSPI_CLK1, /* External Input Clocks */ CLK_EXTAL, @@ -91,6 +101,8 @@ enum clk_ids { CLK_SEL_CLK_PLL2, CLK_SEL_CLK_PLL4, CLK_PLL4D1, + CLK_PLL4D1_DIV3, + CLK_PLL4D1_DIV4, CLK_SCI0ASYNC, CLK_SCI1ASYNC, CLK_SCI2ASYNC, @@ -101,6 +113,8 @@ enum clk_ids { CLK_SPI1ASYNC, CLK_SPI2ASYNC, CLK_SPI3ASYNC, + CLK_DIVSELXSPI0_SCKCR, + CLK_DIVSELXSPI1_SCKCR, /* Module Clocks */ MOD_CLK_BASE, @@ -112,6 +126,15 @@ static const struct clk_div_table dtable_1_2[] = { {0, 0}, }; +static const struct clk_div_table dtable_6_8_16_32_64[] = { + {6, 64}, + {5, 32}, + {4, 16}, + {3, 8}, + {2, 6}, + {0, 0}, +}; + static const struct clk_div_table dtable_24_25_30_32[] = { {0, 32}, {1, 30}, @@ -126,6 +149,7 @@ static const char * const sel_clk_pll0[] = { ".loco", ".pll0" }; static const char * const sel_clk_pll1[] = { ".loco", ".pll1" }; static const char * const sel_clk_pll2[] = { ".loco", ".pll2" }; static const char * const sel_clk_pll4[] = { ".loco", ".pll4" }; +static const char * const sel_clk_pll4d1_div3_div4[] = { ".pll4d1_div3", ".pll4d1_div4" }; static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { /* External Clock Inputs */ @@ -148,6 +172,9 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { sel_clk_pll4, ARRAY_SIZE(sel_clk_pll4), CLK_MUX_READ_ONLY), DEF_FIXED(".pll4d1", CLK_PLL4D1, CLK_SEL_CLK_PLL4, 1, 1), + DEF_FIXED(".pll4d1_div3", CLK_PLL4D1_DIV3, CLK_PLL4D1, 3, 1), + DEF_FIXED(".pll4d1_div4", CLK_PLL4D1_DIV4, CLK_PLL4D1, 4, 1), + DEF_DIV(".sci0async", CLK_SCI0ASYNC, CLK_PLL4D1, DIVSCI0ASYNC, dtable_24_25_30_32), DEF_DIV(".sci1async", CLK_SCI1ASYNC, CLK_PLL4D1, DIVSCI1ASYNC, @@ -170,6 +197,13 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { DEF_DIV(".spi3async", CLK_SPI3ASYNC, CLK_PLL4D1, DIVSPI3ASYNC, dtable_24_25_30_32), + DEF_MUX(".divselxspi0", CLK_DIVSELXSPI0_SCKCR, DIVSEL_XSPI0, + sel_clk_pll4d1_div3_div4, + ARRAY_SIZE(sel_clk_pll4d1_div3_div4), 0), + DEF_MUX(".divselxspi1", CLK_DIVSELXSPI1_SCKCR, DIVSEL_XSPI1, + sel_clk_pll4d1_div3_div4, + ARRAY_SIZE(sel_clk_pll4d1_div3_div4), 0), + /* Core output clk */ DEF_DIV("CA55C0", R9A09G077_CLK_CA55C0, CLK_SEL_CLK_PLL0, DIVCA55C0, dtable_1_2), @@ -194,9 +228,15 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { DEF_FIXED("ETCLKC", R9A09G077_ETCLKC, CLK_SEL_CLK_PLL1, 10, 1), DEF_FIXED("ETCLKD", R9A09G077_ETCLKD, CLK_SEL_CLK_PLL1, 20, 1), DEF_FIXED("ETCLKE", R9A09G077_ETCLKE, CLK_SEL_CLK_PLL1, 40, 1), + DEF_DIV_FSELXSPI("XSPI_CLK0", R9A09G077_XSPI_CLK0, CLK_DIVSELXSPI0_SCKCR, + FSELXSPI0, dtable_6_8_16_32_64), + DEF_DIV_FSELXSPI("XSPI_CLK1", R9A09G077_XSPI_CLK1, CLK_DIVSELXSPI1_SCKCR, + FSELXSPI1, dtable_6_8_16_32_64), }; static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { + DEF_MOD("xspi0", 4, R9A09G077_CLK_PCLKH), + DEF_MOD("xspi1", 5, R9A09G077_CLK_PCLKH), DEF_MOD("sci0fck", 8, CLK_SCI0ASYNC), DEF_MOD("sci1fck", 9, CLK_SCI1ASYNC), DEF_MOD("sci2fck", 10, CLK_SCI2ASYNC), @@ -284,6 +324,151 @@ r9a09g077_cpg_mux_clk_register(struct device *dev, return clk_hw->clk; } +static unsigned int r9a09g077_cpg_fselxspi_get_divider(struct clk_hw *hw, unsigned long rate, + unsigned int num_parents) +{ + struct clk_fixed_factor *ff; + struct clk_hw *parent_hw; + unsigned long best_rate; + unsigned int i; + + for (i = 0; i < num_parents; i++) { + parent_hw = clk_hw_get_parent_by_index(hw, i); + best_rate = clk_hw_round_rate(parent_hw, rate); + + if (best_rate == rate) { + ff = to_clk_fixed_factor(parent_hw); + return ff->div; + } + } + + /* No parent could provide the exact rate - this should not happen */ + return 0; +} + +static int r9a09g077_cpg_fselxspi_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_divider *divider = to_clk_divider(hw); + unsigned long parent_rate, best = 0, now; + const struct clk_div_table *clkt; + unsigned long rate = req->rate; + unsigned int num_parents; + unsigned int divselxspi; + unsigned int div = 0; + + if (!rate) + rate = 1; + + /* Get the number of parents for FSELXSPIn */ + num_parents = clk_hw_get_num_parents(req->best_parent_hw); + + for (clkt = divider->table; clkt->div; clkt++) { + parent_rate = clk_hw_round_rate(req->best_parent_hw, rate * clkt->div); + /* Skip if parent can't provide any valid rate */ + if (!parent_rate) + continue; + + /* Determine which DIVSELXSPIn divider (3 or 4) provides this parent_rate */ + divselxspi = r9a09g077_cpg_fselxspi_get_divider(req->best_parent_hw, parent_rate, + num_parents); + if (!divselxspi) + continue; + + /* + * DIVSELXSPIx supports 800MHz and 600MHz operation. + * When divselxspi is 4 (600MHz operation), only FSELXSPIn dividers of 8 and 16 + * are supported. Otherwise, when divselxspi is 3 (800MHz operation), + * dividers of 6, 8, 16, 32, and 64 are supported. This check ensures that + * FSELXSPIx is set correctly based on hardware limitations. + */ + if (divselxspi == 4 && (clkt->div != 8 && clkt->div != 16)) + continue; + + now = DIV_ROUND_UP_ULL(parent_rate, clkt->div); + if (abs(rate - now) < abs(rate - best)) { + div = clkt->div; + best = now; + req->best_parent_rate = parent_rate; + } + } + + if (!div) { + req->best_parent_rate = clk_hw_round_rate(req->best_parent_hw, 1); + divselxspi = r9a09g077_cpg_fselxspi_get_divider(req->best_parent_hw, + req->best_parent_rate, + num_parents); + /* default to divider 3 which will result DIVSELXSPIn = 800 MHz */ + if (!divselxspi) + divselxspi = 3; + + /* + * Use the maximum divider based on the parent clock rate: + * - 64 when DIVSELXSPIx is 800 MHz (divider = 3) + * - 16 when DIVSELXSPIx is 600 MHz (divider = 4) + */ + div = divselxspi == 3 ? 64 : 16; + } + + req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, div); + + return 0; +} + +static struct clk * __init +r9a09g077_cpg_fselxspi_div_clk_register(struct device *dev, + const struct cpg_core_clk *core, + void __iomem *addr, + struct cpg_mssr_pub *pub) +{ + static struct clk_ops *xspi_div_ops; + struct clk_init_data init = {}; + const struct clk *parent; + const char *parent_name; + struct clk_divider *div; + struct clk_hw *hw; + int ret; + + parent = pub->clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); + if (!div) + return ERR_PTR(-ENOMEM); + + if (!xspi_div_ops) { + xspi_div_ops = devm_kzalloc(dev, sizeof(*xspi_div_ops), GFP_KERNEL); + if (!xspi_div_ops) + return ERR_PTR(-ENOMEM); + memcpy(xspi_div_ops, &clk_divider_ops, + sizeof(const struct clk_ops)); + xspi_div_ops->determine_rate = r9a09g077_cpg_fselxspi_determine_rate; + } + + parent_name = __clk_get_name(parent); + init.name = core->name; + init.ops = xspi_div_ops; + init.flags = CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; + + div->reg = addr; + div->shift = GET_SHIFT(core->conf); + div->width = GET_WIDTH(core->conf); + div->flags = core->flag; + div->lock = &pub->rmw_lock; + div->hw.init = &init; + div->table = core->dtable; + + hw = &div->hw; + ret = devm_clk_hw_register(dev, hw); + if (ret) + return ERR_PTR(ret); + + return hw->clk; +} + static struct clk * __init r9a09g077_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, @@ -298,6 +483,8 @@ r9a09g077_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, return r9a09g077_cpg_div_clk_register(dev, core, addr, pub); case CLK_TYPE_RZT2H_MUX: return r9a09g077_cpg_mux_clk_register(dev, core, addr, pub); + case CLK_TYPE_RZT2H_FSELXSPI: + return r9a09g077_cpg_fselxspi_div_clk_register(dev, core, addr, pub); default: return ERR_PTR(-EINVAL); } From e68100006bedc361197e6cb9da1cced87ee3e5b0 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Fri, 21 Nov 2025 09:08:53 +0000 Subject: [PATCH 012/165] clk: renesas: r9a09g077: Propagate rate changes through mux parents Enable CLK_SET_RATE_PARENT for mux clocks so that rate changes can properly propagate to their parent clocks. Several clocks in the R9A09G077 CPG tree depend on upstream PLL or divider outputs being recalculated when a child requests a new frequency. Without this flag, rate adjustments stop at the mux layer, leaving parent rates unchanged and preventing the clock tree from converging on the intended values. Set the flag in DEF_MUX to ensure that parent clocks participate in rate negotiation, which is required for correct operation of the display and peripheral related clocks being added for RZ/T2H support. Fixes: 065fe720eec6e ("clk: renesas: Add support for R9A09G077 SoC") Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251121090853.5220-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g077-cpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index 07d6cc57b3d9..dee25cdadf1d 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -78,7 +78,7 @@ enum rzt2h_clk_types { #define DEF_MUX(_name, _id, _conf, _parent_names, _num_parents, _mux_flags) \ DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_MUX, .conf = _conf, \ .parent_names = _parent_names, .num_parents = _num_parents, \ - .flag = 0, .mux_flags = _mux_flags) + .flag = CLK_SET_RATE_PARENT, .mux_flags = _mux_flags) #define DEF_DIV_FSELXSPI(_name, _id, _parent, _conf, _dtable) \ DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_FSELXSPI, .conf = _conf, \ .parent = _parent, .dtable = _dtable, .flag = 0) From 75faf216112a69cdbf415fa057abbe7ed2ae6da6 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 25 Nov 2025 22:14:18 +0000 Subject: [PATCH 013/165] clk: renesas: r9a09g056: Add entries for the DMACs Add clock and reset entries for the DMAC IPs. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251125221420.288809-2-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g056-cpg.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index f48a082e65d7..19b712685a31 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -51,6 +51,8 @@ enum clk_ids { CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_DIV8, CLK_PLLDTY_DIV16, + CLK_PLLDTY_RCPU, + CLK_PLLDTY_RCPU_DIV4, CLK_PLLVDO_CRU0, CLK_PLLVDO_CRU1, CLK_PLLVDO_ISP, @@ -184,6 +186,8 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_FIXED(".plldty_acpu_div4", CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_ACPU, 1, 4), DEF_FIXED(".plldty_div8", CLK_PLLDTY_DIV8, CLK_PLLDTY, 1, 8), DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16), + DEF_DDIV(".plldty_rcpu", CLK_PLLDTY_RCPU, CLK_PLLDTY, CDDIV3_DIVCTL2, dtable_2_64), + DEF_FIXED(".plldty_rcpu_div4", CLK_PLLDTY_RCPU_DIV4, CLK_PLLDTY_RCPU, 1, 4), DEF_DDIV(".pllvdo_cru0", CLK_PLLVDO_CRU0, CLK_PLLVDO, CDDIV3_DIVCTL3, dtable_2_4), DEF_DDIV(".pllvdo_cru1", CLK_PLLVDO_CRU1, CLK_PLLVDO, CDDIV4_DIVCTL0, dtable_2_4), @@ -231,6 +235,16 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { }; static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { + DEF_MOD("dmac_0_aclk", CLK_PLLCM33_GEAR, 0, 0, 0, 0, + BUS_MSTOP(5, BIT(9))), + DEF_MOD("dmac_1_aclk", CLK_PLLDTY_ACPU_DIV2, 0, 1, 0, 1, + BUS_MSTOP(3, BIT(2))), + DEF_MOD("dmac_2_aclk", CLK_PLLDTY_ACPU_DIV2, 0, 2, 0, 2, + BUS_MSTOP(3, BIT(3))), + DEF_MOD("dmac_3_aclk", CLK_PLLDTY_RCPU_DIV4, 0, 3, 0, 3, + BUS_MSTOP(10, BIT(11))), + DEF_MOD("dmac_4_aclk", CLK_PLLDTY_RCPU_DIV4, 0, 4, 0, 4, + BUS_MSTOP(10, BIT(12))), DEF_MOD_CRITICAL("gic_0_gicclk", CLK_PLLDTY_ACPU_DIV4, 1, 3, 0, 19, BUS_MSTOP(3, BIT(5))), DEF_MOD("gtm_0_pclk", CLK_PLLCM33_DIV16, 4, 3, 2, 3, @@ -401,6 +415,11 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(3, 0, 1, 1), /* SYS_0_PRESETN */ + DEF_RST(3, 1, 1, 2), /* DMAC_0_ARESETN */ + DEF_RST(3, 2, 1, 3), /* DMAC_1_ARESETN */ + DEF_RST(3, 3, 1, 4), /* DMAC_2_ARESETN */ + DEF_RST(3, 4, 1, 5), /* DMAC_3_ARESETN */ + DEF_RST(3, 5, 1, 6), /* DMAC_4_ARESETN */ DEF_RST(3, 8, 1, 9), /* GIC_0_GICRESET_N */ DEF_RST(3, 9, 1, 10), /* GIC_0_DBG_GICRESET_N */ DEF_RST(6, 13, 2, 30), /* GTM_0_PRESETZ */ From 94cdeca6a17a3e2ba617c8a03e17d989de005a20 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 25 Nov 2025 22:14:19 +0000 Subject: [PATCH 014/165] clk: renesas: r9a09g056: Add entries for ICU Add clock and reset entries for the ICU IP block. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251125221420.288809-3-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g056-cpg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index 19b712685a31..1c6228b0544e 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -245,6 +245,8 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(10, BIT(11))), DEF_MOD("dmac_4_aclk", CLK_PLLDTY_RCPU_DIV4, 0, 4, 0, 4, BUS_MSTOP(10, BIT(12))), + DEF_MOD_CRITICAL("icu_0_pclk_i", CLK_PLLCM33_DIV16, 0, 5, 0, 5, + BUS_MSTOP_NONE), DEF_MOD_CRITICAL("gic_0_gicclk", CLK_PLLDTY_ACPU_DIV4, 1, 3, 0, 19, BUS_MSTOP(3, BIT(5))), DEF_MOD("gtm_0_pclk", CLK_PLLCM33_DIV16, 4, 3, 2, 3, @@ -420,6 +422,7 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(3, 3, 1, 4), /* DMAC_2_ARESETN */ DEF_RST(3, 4, 1, 5), /* DMAC_3_ARESETN */ DEF_RST(3, 5, 1, 6), /* DMAC_4_ARESETN */ + DEF_RST(3, 6, 1, 7), /* ICU_0_PRESETN_I */ DEF_RST(3, 8, 1, 9), /* GIC_0_GICRESET_N */ DEF_RST(3, 9, 1, 10), /* GIC_0_DBG_GICRESET_N */ DEF_RST(6, 13, 2, 30), /* GTM_0_PRESETZ */ From d8921e42a1983024227c0e64253ea96b25a1ae9a Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 25 Nov 2025 22:14:20 +0000 Subject: [PATCH 015/165] clk: renesas: r9a09g056: Add entries for the RSPIs Add clock and reset entries for the RSPI IPs. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251125221420.288809-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g056-cpg.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index 1c6228b0544e..4b068199edde 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -281,6 +281,24 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(5, BIT(13))), DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18, BUS_MSTOP(5, BIT(13))), + DEF_MOD("rspi_0_pclk", CLK_PLLCLN_DIV8, 5, 4, 2, 20, + BUS_MSTOP(11, BIT(0))), + DEF_MOD("rspi_0_pclk_sfr", CLK_PLLCLN_DIV8, 5, 5, 2, 21, + BUS_MSTOP(11, BIT(0))), + DEF_MOD("rspi_0_tclk", CLK_PLLCLN_DIV8, 5, 6, 2, 22, + BUS_MSTOP(11, BIT(0))), + DEF_MOD("rspi_1_pclk", CLK_PLLCLN_DIV8, 5, 7, 2, 23, + BUS_MSTOP(11, BIT(1))), + DEF_MOD("rspi_1_pclk_sfr", CLK_PLLCLN_DIV8, 5, 8, 2, 24, + BUS_MSTOP(11, BIT(1))), + DEF_MOD("rspi_1_tclk", CLK_PLLCLN_DIV8, 5, 9, 2, 25, + BUS_MSTOP(11, BIT(1))), + DEF_MOD("rspi_2_pclk", CLK_PLLCLN_DIV8, 5, 10, 2, 26, + BUS_MSTOP(11, BIT(2))), + DEF_MOD("rspi_2_pclk_sfr", CLK_PLLCLN_DIV8, 5, 11, 2, 27, + BUS_MSTOP(11, BIT(2))), + DEF_MOD("rspi_2_tclk", CLK_PLLCLN_DIV8, 5, 12, 2, 28, + BUS_MSTOP(11, BIT(2))), DEF_MOD("scif_0_clk_pck", CLK_PLLCM33_DIV16, 8, 15, 4, 15, BUS_MSTOP(3, BIT(14))), DEF_MOD("i3c_0_pclkrw", CLK_PLLCLN_DIV16, 9, 0, 4, 16, @@ -437,6 +455,12 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */ DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */ DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */ + DEF_RST(7, 11, 3, 12), /* RSPI_0_PRESETN */ + DEF_RST(7, 12, 3, 13), /* RSPI_0_TRESETN */ + DEF_RST(7, 13, 3, 14), /* RSPI_1_PRESETN */ + DEF_RST(7, 14, 3, 15), /* RSPI_1_TRESETN */ + DEF_RST(7, 15, 3, 16), /* RSPI_2_PRESETN */ + DEF_RST(8, 0, 3, 17), /* RSPI_2_TRESETN */ DEF_RST(9, 5, 4, 6), /* SCIF_0_RST_SYSTEM_N */ DEF_RST(9, 6, 4, 7), /* I3C_0_PRESETN */ DEF_RST(9, 7, 4, 8), /* I3C_0_TRESETN */ From 3dadc1dc5e85cefc7a2f1c9d428b5622fda12d3d Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 9 Dec 2025 14:19:24 +0530 Subject: [PATCH 016/165] clk: qcom: rpmh: Update the clock suffix for Glymur The current RPMh VRM clock definitions do not accurately represent the hardware mapping of these clocks. While there is no functional impact, this update aligns the definitions with the hardware convention by adding the appropriate suffix to indicate the clock divider and the E0 variant for the C3A_E0, C4A_E0, C5A_E0, and C8A_E0 resources on Glymur. Reviewed-by: Konrad Dybcio Signed-off-by: Taniya Das Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251209-gcc_kaanapali-v3-v5-1-3af118262289@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rpmh.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 1a98b3a0c528..a2185a6f321f 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -390,10 +390,10 @@ DEFINE_CLK_RPMH_VRM(clk7, _a4, "clka7", 4); DEFINE_CLK_RPMH_VRM(div_clk1, _div2, "divclka1", 2); -DEFINE_CLK_RPMH_VRM(clk3, _a, "C3A_E0", 1); -DEFINE_CLK_RPMH_VRM(clk4, _a, "C4A_E0", 1); -DEFINE_CLK_RPMH_VRM(clk5, _a, "C5A_E0", 1); -DEFINE_CLK_RPMH_VRM(clk8, _a, "C8A_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(clk8, _a1_e0, "C8A_E0", 1); DEFINE_CLK_RPMH_BCM(ce, "CE0"); DEFINE_CLK_RPMH_BCM(hwkm, "HK0"); @@ -888,12 +888,12 @@ static const struct clk_rpmh_desc clk_rpmh_sm8750 = { static struct clk_hw *glymur_rpmh_clocks[] = { [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, - [RPMH_RF_CLK3] = &clk_rpmh_clk3_a.hw, - [RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a_ao.hw, - [RPMH_RF_CLK4] = &clk_rpmh_clk4_a.hw, - [RPMH_RF_CLK4_A] = &clk_rpmh_clk4_a_ao.hw, - [RPMH_RF_CLK5] = &clk_rpmh_clk5_a.hw, - [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a_ao.hw, + [RPMH_RF_CLK3] = &clk_rpmh_clk3_a1_e0.hw, + [RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a1_e0_ao.hw, + [RPMH_RF_CLK4] = &clk_rpmh_clk4_a1_e0.hw, + [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, }; static const struct clk_rpmh_desc clk_rpmh_glymur = { From acabfd13859dfa343aa5289f7c2d55fddbaf346f Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 9 Dec 2025 14:19:25 +0530 Subject: [PATCH 017/165] clk: qcom: rpmh: Add support for Kaanapali rpmh clocks Add the RPMH clocks present in Kaanapali SoC. Reviewed-by: Konrad Dybcio Signed-off-by: Taniya Das Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251209-gcc_kaanapali-v3-v5-2-3af118262289@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rpmh.c | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index a2185a6f321f..10e84ada48ee 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -390,11 +390,22 @@ DEFINE_CLK_RPMH_VRM(clk7, _a4, "clka7", 4); DEFINE_CLK_RPMH_VRM(div_clk1, _div2, "divclka1", 2); +DEFINE_CLK_RPMH_VRM(clk1, _a1_e0, "C1A_E0", 1); +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(clk8, _a1_e0, "C8A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk3, _a2_e0, "C3A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk4, _a2_e0, "C4A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk5, _a2_e0, "C5A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk6, _a2_e0, "C6A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk7, _a2_e0, "C7A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk8, _a2_e0, "C8A_E0", 2); + +DEFINE_CLK_RPMH_VRM(clk11, _a4_e0, "C11A_E0", 4); + DEFINE_CLK_RPMH_BCM(ce, "CE0"); DEFINE_CLK_RPMH_BCM(hwkm, "HK0"); DEFINE_CLK_RPMH_BCM(ipa, "IP0"); @@ -901,6 +912,34 @@ static const struct clk_rpmh_desc clk_rpmh_glymur = { .num_clks = ARRAY_SIZE(glymur_rpmh_clocks), }; +static struct clk_hw *kaanapali_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, + [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, + [RPMH_DIV_CLK1] = &clk_rpmh_clk11_a4_e0.hw, + [RPMH_LN_BB_CLK1] = &clk_rpmh_clk6_a2_e0.hw, + [RPMH_LN_BB_CLK1_A] = &clk_rpmh_clk6_a2_e0_ao.hw, + [RPMH_LN_BB_CLK2] = &clk_rpmh_clk7_a2_e0.hw, + [RPMH_LN_BB_CLK2_A] = &clk_rpmh_clk7_a2_e0_ao.hw, + [RPMH_LN_BB_CLK3] = &clk_rpmh_clk8_a2_e0.hw, + [RPMH_LN_BB_CLK3_A] = &clk_rpmh_clk8_a2_e0_ao.hw, + [RPMH_RF_CLK1] = &clk_rpmh_clk1_a1_e0.hw, + [RPMH_RF_CLK1_A] = &clk_rpmh_clk1_a1_e0_ao.hw, + [RPMH_RF_CLK2] = &clk_rpmh_clk2_a1_e0.hw, + [RPMH_RF_CLK2_A] = &clk_rpmh_clk2_a1_e0_ao.hw, + [RPMH_RF_CLK3] = &clk_rpmh_clk3_a2_e0.hw, + [RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a2_e0_ao.hw, + [RPMH_RF_CLK4] = &clk_rpmh_clk4_a2_e0.hw, + [RPMH_RF_CLK4] = &clk_rpmh_clk4_a2_e0_ao.hw, + [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a2_e0.hw, + [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a2_e0_ao.hw, + [RPMH_IPA_CLK] = &clk_rpmh_ipa.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_kaanapali = { + .clks = kaanapali_rpmh_clocks, + .num_clks = ARRAY_SIZE(kaanapali_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -991,6 +1030,7 @@ static int clk_rpmh_probe(struct platform_device *pdev) static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,glymur-rpmh-clk", .data = &clk_rpmh_glymur}, + { .compatible = "qcom,kaanapali-rpmh-clk", .data = &clk_rpmh_kaanapali}, { .compatible = "qcom,milos-rpmh-clk", .data = &clk_rpmh_milos}, { .compatible = "qcom,qcs615-rpmh-clk", .data = &clk_rpmh_qcs615}, { .compatible = "qcom,qdu1000-rpmh-clk", .data = &clk_rpmh_qdu1000}, From e5682c953f5a9fbaad060ea000beff80f11c4048 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 9 Dec 2025 14:19:26 +0530 Subject: [PATCH 018/165] clk: qcom: Add TCSR clock driver for Kaanapali Add the TCSR clock controller that provides the refclks on Kaanapali platform for PCIe, USB and UFS subsystems. Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Reviewed-by: Abel Vesa Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20251209-gcc_kaanapali-v3-v5-3-3af118262289@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 8 ++ drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/tcsrcc-kaanapali.c | 141 ++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 drivers/clk/qcom/tcsrcc-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index a284ba040b78..efaf32bb517e 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -46,6 +46,14 @@ config CLK_GLYMUR_TCSRCC Support for the TCSR clock controller on GLYMUR devices. Say Y if you want to use peripheral devices such as USB/PCIe/EDP. +config CLK_KAANAPALI_TCSRCC + tristate "Kaanapali TCSR Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the TCSR clock controller on Kaanapali devices. + Say Y if you want to use peripheral devices such as PCIe, USB, UFS. + config CLK_X1E80100_CAMCC tristate "X1E80100 Camera Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 0ac8a9055a43..6e45410d572b 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o obj-$(CONFIG_CLK_GLYMUR_DISPCC) += dispcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_GCC) += gcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-glymur.o +obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o diff --git a/drivers/clk/qcom/tcsrcc-kaanapali.c b/drivers/clk/qcom/tcsrcc-kaanapali.c new file mode 100644 index 000000000000..4da77367c9e0 --- /dev/null +++ b/drivers/clk/qcom/tcsrcc-kaanapali.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-branch.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" + +enum { + DT_BI_TCXO_PAD, +}; + +static struct clk_branch tcsr_pcie_0_clkref_en = { + .halt_reg = 0x15044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x15044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_pcie_0_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb3_clkref_en = { + .halt_reg = 0x1504c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1504c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb3_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_clkref_en = { + .halt_reg = 0x15054, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x15054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_ufs_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_clkref_en = { + .halt_reg = 0x1505c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1505c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb2_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_kaanapali_clocks[] = { + [TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr, + [TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr, + [TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr, + [TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr, +}; + +static const struct regmap_config tcsr_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x3d000, + .fast_io = true, +}; + +static const struct qcom_cc_desc tcsr_cc_kaanapali_desc = { + .config = &tcsr_cc_kaanapali_regmap_config, + .clks = tcsr_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(tcsr_cc_kaanapali_clocks), +}; + +static const struct of_device_id tcsr_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-tcsr" }, + { } +}; +MODULE_DEVICE_TABLE(of, tcsr_cc_kaanapali_match_table); + +static int tcsr_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &tcsr_cc_kaanapali_desc); +} + +static struct platform_driver tcsr_cc_kaanapali_driver = { + .probe = tcsr_cc_kaanapali_probe, + .driver = { + .name = "tcsr_cc-kaanapali", + .of_match_table = tcsr_cc_kaanapali_match_table, + }, +}; + +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); + +MODULE_DESCRIPTION("QTI TCSR_CC Kaanapali Driver"); +MODULE_LICENSE("GPL"); From d1919c375f211a2aeef898496b6f3efbefebf7f5 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 9 Dec 2025 14:19:27 +0530 Subject: [PATCH 019/165] clk: qcom: Add support for Global clock controller on Kaanapali Add support for Global clock controller for Kaanapali Qualcomm SoC. Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20251209-gcc_kaanapali-v3-v5-4-3af118262289@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-kaanapali.c | 3541 ++++++++++++++++++++++++++++++ 3 files changed, 3551 insertions(+) create mode 100644 drivers/clk/qcom/gcc-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index efaf32bb517e..960ef7b4890e 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -46,6 +46,15 @@ config CLK_GLYMUR_TCSRCC Support for the TCSR clock controller on GLYMUR devices. Say Y if you want to use peripheral devices such as USB/PCIe/EDP. +config CLK_KAANAPALI_GCC + tristate "Kaanapali Global Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the global clock controller on Kaanapali devices. + Say Y if you want to use peripheral devices such as UART, + SPI, I2C, USB, SD/UFS, PCIe etc. + config CLK_KAANAPALI_TCSRCC tristate "Kaanapali TCSR Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 6e45410d572b..159f03287edd 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o obj-$(CONFIG_CLK_GLYMUR_DISPCC) += dispcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_GCC) += gcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-glymur.o +obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o diff --git a/drivers/clk/qcom/gcc-kaanapali.c b/drivers/clk/qcom/gcc-kaanapali.c new file mode 100644 index 000000000000..182b152df14c --- /dev/null +++ b/drivers/clk/qcom/gcc-kaanapali.c @@ -0,0 +1,3541 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "clk-regmap-phy-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, + DT_PCIE_0_PIPE_CLK, + DT_UFS_PHY_RX_SYMBOL_0_CLK, + DT_UFS_PHY_RX_SYMBOL_1_CLK, + DT_UFS_PHY_TX_SYMBOL_0_CLK, + DT_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, +}; + +enum { + P_BI_TCXO, + P_GCC_GPLL0_OUT_EVEN, + P_GCC_GPLL0_OUT_MAIN, + P_GCC_GPLL1_OUT_MAIN, + P_GCC_GPLL4_OUT_MAIN, + P_GCC_GPLL7_OUT_MAIN, + P_GCC_GPLL9_OUT_MAIN, + P_PCIE_0_PIPE_CLK, + P_SLEEP_CLK, + P_UFS_PHY_RX_SYMBOL_0_CLK, + P_UFS_PHY_RX_SYMBOL_1_CLK, + P_UFS_PHY_TX_SYMBOL_0_CLK, + P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, +}; + +static struct clk_alpha_pll gcc_gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gcc_gpll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gcc_gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_gcc_gpll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gcc_gpll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static struct clk_alpha_pll gcc_gpll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll4 = { + .offset = 0x4000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll7 = { + .offset = 0x7000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll7", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll9 = { + .offset = 0x9000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll9", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL1_OUT_MAIN, 4 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll1.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .index = DT_SLEEP_CLK }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data gcc_parent_data_4[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL7_OUT_MAIN, 2 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll7.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL9_OUT_MAIN, 2 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll9.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_12[] = { + { P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_12[] = { + { .index = DT_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static struct clk_regmap_phy_mux gcc_pcie_0_pipe_clk_src = { + .reg = 0x6b090, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_pipe_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_PCIE_0_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_0_clk_src = { + .reg = 0x77068, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk_src", + .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_phy_mux gcc_ufs_phy_rx_symbol_1_clk_src = { + .reg = 0x770ec, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk_src", + .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_phy_mux gcc_ufs_phy_tx_symbol_0_clk_src = { + .reg = 0x77058, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_UFS_PHY_TX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = { + .reg = 0x39074, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_12, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk_src", + .parent_data = gcc_parent_data_12, + .num_parents = ARRAY_SIZE(gcc_parent_data_12), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x64004, + .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), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x65004, + .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), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x66004, + .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), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_0_aux_clk_src = { + .cmd_rcgr = 0x6b094, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_aux_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_0_phy_aux_clk_src = { + .cmd_rcgr = 0x6b0ac, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_aux_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_0_phy_rchng_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_0_phy_rchng_clk_src = { + .cmd_rcgr = 0x6b078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_rchng_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(60000000, P_GCC_GPLL0_OUT_MAIN, 10, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x33010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .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_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s0_clk_src = { + .cmd_rcgr = 0x17008, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s1_clk_src = { + .cmd_rcgr = 0x17024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s2_clk_src = { + .cmd_rcgr = 0x17040, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s3_clk_src = { + .cmd_rcgr = 0x1705c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s4_clk_src = { + .cmd_rcgr = 0x17078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap1_qspi_ref_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + F(150000000, P_GCC_GPLL0_OUT_EVEN, 2, 0, 0), + F(250000000, P_GCC_GPLL7_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap1_qspi_ref_clk_src_init = { + .name = "gcc_qupv3_wrap1_qspi_ref_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_qspi_ref_clk_src = { + .cmd_rcgr = 0x188c0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_qupv3_wrap1_qspi_ref_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_qspi_ref_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s0_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(60000000, P_GCC_GPLL0_OUT_EVEN, 5, 0, 0), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { + .cmd_rcgr = 0x18014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { + .cmd_rcgr = 0x18150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { + .cmd_rcgr = 0x182a0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s4_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(60000000, P_GCC_GPLL0_OUT_EVEN, 5, 0, 0), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { + .cmd_rcgr = 0x183dc, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { + .cmd_rcgr = 0x18518, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = { + .name = "gcc_qupv3_wrap1_s6_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { + .cmd_rcgr = 0x18654, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = { + .name = "gcc_qupv3_wrap1_s7_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { + .cmd_rcgr = 0x18790, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = { + .name = "gcc_qupv3_wrap2_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = { + .cmd_rcgr = 0x1e014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = { + .name = "gcc_qupv3_wrap2_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = { + .cmd_rcgr = 0x1e150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = { + .name = "gcc_qupv3_wrap2_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = { + .cmd_rcgr = 0x1e28c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = { + .name = "gcc_qupv3_wrap2_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = { + .cmd_rcgr = 0x1e3c8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = { + .name = "gcc_qupv3_wrap2_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = { + .cmd_rcgr = 0x1e504, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s4_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap3_ibi_ctrl_0_clk_src[] = { + F(37500000, P_GCC_GPLL0_OUT_EVEN, 8, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_ibi_ctrl_0_clk_src = { + .cmd_rcgr = 0xa877c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap3_ibi_ctrl_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_ibi_ctrl_0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s0_clk_src_init = { + .name = "gcc_qupv3_wrap3_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s0_clk_src = { + .cmd_rcgr = 0xa8014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s1_clk_src_init = { + .name = "gcc_qupv3_wrap3_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s1_clk_src = { + .cmd_rcgr = 0xa8150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s2_clk_src_init = { + .name = "gcc_qupv3_wrap3_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s2_clk_src = { + .cmd_rcgr = 0xa828c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s3_clk_src_init = { + .name = "gcc_qupv3_wrap3_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s3_clk_src = { + .cmd_rcgr = 0xa83c8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s4_clk_src_init = { + .name = "gcc_qupv3_wrap3_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s4_clk_src = { + .cmd_rcgr = 0xa8504, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s4_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap3_s5_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(60000000, P_GCC_GPLL0_OUT_EVEN, 5, 0, 0), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + F(128000000, P_GCC_GPLL0_OUT_MAIN, 1, 16, 75), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap3_s5_clk_src_init = { + .name = "gcc_qupv3_wrap3_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s5_clk_src = { + .cmd_rcgr = 0xa8640, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap3_s5_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s0_clk_src_init = { + .name = "gcc_qupv3_wrap4_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s0_clk_src = { + .cmd_rcgr = 0xa9014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s1_clk_src_init = { + .name = "gcc_qupv3_wrap4_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s1_clk_src = { + .cmd_rcgr = 0xa9150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s2_clk_src_init = { + .name = "gcc_qupv3_wrap4_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s2_clk_src = { + .cmd_rcgr = 0xa928c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s3_clk_src_init = { + .name = "gcc_qupv3_wrap4_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s3_clk_src = { + .cmd_rcgr = 0xa93c8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s4_clk_src_init = { + .name = "gcc_qupv3_wrap4_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s4_clk_src = { + .cmd_rcgr = 0xa9504, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s4_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(202000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1401c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { + .cmd_rcgr = 0x1601c, + .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), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_floor_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), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(201500000, P_GCC_GPLL4_OUT_MAIN, 4, 0, 0), + F(403000000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { + .cmd_rcgr = 0x77034, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_axi_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = { + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(201500000, P_GCC_GPLL4_OUT_MAIN, 4, 0, 0), + F(403000000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { + .cmd_rcgr = 0x7708c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ice_core_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x770c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_phy_aux_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { + .cmd_rcgr = 0x770a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_unipro_core_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { + F(66666667, P_GCC_GPLL0_OUT_EVEN, 4.5, 0, 0), + F(133333333, P_GCC_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GCC_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0x39034, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0x3904c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0x39078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap1_s2_clk_src = { + .reg = 0x1828c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_ref_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = { + .reg = 0x39064, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gcc_aggre_noc_pcie_axi_clk = { + .halt_reg = 0x10068, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x10068, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_noc_pcie_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { + .halt_reg = 0x770f0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x770f0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x770f0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_prim_axi_clk = { + .halt_reg = 0x39094, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x39094, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x39094, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x38004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_hf_axi_clk = { + .halt_reg = 0x26014, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x26014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camera_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_sf_axi_clk = { + .halt_reg = 0x26028, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x26028, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camera_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_pcie_anoc_ahb_clk = { + .halt_reg = 0x10050, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x10050, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_pcie_anoc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0x39090, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x39090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x39090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cnoc_pcie_sf_axi_clk = { + .halt_reg = 0x10058, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cnoc_pcie_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_pcie_sf_qtb_clk = { + .halt_reg = 0x1007c, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x1007c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ddrss_pcie_sf_qtb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0x2701c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2701c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_sf_axi_clk = { + .halt_reg = 0x27008, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x27008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x27008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_sf_axi_clk", + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gcc_eva_axi0_clk = { + .halt_reg = 0x9f008, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x9f008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9f008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_eva_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eva_axi0c_clk = { + .halt_reg = 0x9f01c, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x9f01c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9f01c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_eva_axi0c_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x64000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x64000, + .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 = 0x65000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x65000, + .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 = 0x66000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x66000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gemnoc_gfx_clk = { + .halt_reg = 0x71010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x71010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gemnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0_out_even.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_aux_clk = { + .halt_reg = 0x6b044, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { + .halt_reg = 0x6b040, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_mstr_axi_clk = { + .halt_reg = 0x6b030, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x6b030, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_phy_aux_clk = { + .halt_reg = 0x6b054, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_phy_rchng_clk = { + .halt_reg = 0x6b074, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_rchng_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_phy_rchng_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_pipe_clk = { + .halt_reg = 0x6b064, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_axi_clk = { + .halt_reg = 0x6b020, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_q2a_axi_clk = { + .halt_reg = 0x6b01c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3300c, + .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 = 0x33004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x33004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x33004, + .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 = 0x33008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33008, + .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_qmip_camera_cmd_ahb_clk = { + .halt_reg = 0x26010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x26010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_cmd_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = { + .halt_reg = 0x26008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x26008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_nrt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_rt_ahb_clk = { + .halt_reg = 0x2600c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2600c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x2600c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_rt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_disp_dcp_sf_ahb_clk = { + .halt_reg = 0x27030, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x27030, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x27030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_disp_dcp_sf_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_gpu_ahb_clk = { + .halt_reg = 0x71008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x71008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_gpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_pcie_ahb_clk = { + .halt_reg = 0x6b018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_pcie_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_cv_cpu_ahb_clk = { + .halt_reg = 0x32014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_cv_cpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_cvp_ahb_clk = { + .halt_reg = 0x32008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_cvp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_v_cpu_ahb_clk = { + .halt_reg = 0x32010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_v_cpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = { + .halt_reg = 0x3200c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x3200c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3200c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_vcodec_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_core_clk = { + .halt_reg = 0x23004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s0_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s1_clk = { + .halt_reg = 0x17020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s2_clk = { + .halt_reg = 0x1703c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s3_clk = { + .halt_reg = 0x17058, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s4_clk = { + .halt_reg = 0x17074, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s_ahb_clk = { + .halt_reg = 0x23000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = { + .halt_reg = 0x2315c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_clk = { + .halt_reg = 0x23148, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_qspi_ref_clk = { + .halt_reg = 0x188bc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_qspi_ref_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_ref_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s0_clk = { + .halt_reg = 0x18004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s1_clk = { + .halt_reg = 0x18140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s2_clk = { + .halt_reg = 0x1827c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s3_clk = { + .halt_reg = 0x18290, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s4_clk = { + .halt_reg = 0x183cc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s5_clk = { + .halt_reg = 0x18508, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s6_clk = { + .halt_reg = 0x18644, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s7_clk = { + .halt_reg = 0x18780, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s7_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_core_2x_clk = { + .halt_reg = 0x232b4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_core_clk = { + .halt_reg = 0x232a0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s0_clk = { + .halt_reg = 0x1e004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s1_clk = { + .halt_reg = 0x1e140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s2_clk = { + .halt_reg = 0x1e27c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s3_clk = { + .halt_reg = 0x1e3b8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s4_clk = { + .halt_reg = 0x1e4f4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_core_2x_clk = { + .halt_reg = 0x2340c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_core_clk = { + .halt_reg = 0x233f8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_ibi_ctrl_1_clk = { + .halt_reg = 0xa8774, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa8774, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_ibi_ctrl_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_ibi_ctrl_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_ibi_ctrl_2_clk = { + .halt_reg = 0xa8778, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa8778, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_ibi_ctrl_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_ibi_ctrl_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s0_clk = { + .halt_reg = 0xa8004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s1_clk = { + .halt_reg = 0xa8140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s2_clk = { + .halt_reg = 0xa827c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s3_clk = { + .halt_reg = 0xa83b8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s4_clk = { + .halt_reg = 0xa84f4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s5_clk = { + .halt_reg = 0xa8630, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_core_2x_clk = { + .halt_reg = 0x23564, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_core_clk = { + .halt_reg = 0x23550, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s0_clk = { + .halt_reg = 0xa9004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s1_clk = { + .halt_reg = 0xa9140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s2_clk = { + .halt_reg = 0xa927c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s3_clk = { + .halt_reg = 0xa93b8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s4_clk = { + .halt_reg = 0xa94f4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_m_axi_clk = { + .halt_reg = 0x23140, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23140, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_1_m_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { + .halt_reg = 0x23144, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23144, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_1_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_m_ahb_clk = { + .halt_reg = 0x23298, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23298, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_2_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_s_ahb_clk = { + .halt_reg = 0x2329c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2329c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_2_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_ibi_1_ahb_clk = { + .halt_reg = 0xa876c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa876c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_ibi_1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_ibi_2_ahb_clk = { + .halt_reg = 0xa8770, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa8770, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_ibi_2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_m_ahb_clk = { + .halt_reg = 0x233f0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x233f0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_s_ahb_clk = { + .halt_reg = 0x233f4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x233f4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_4_m_ahb_clk = { + .halt_reg = 0x23548, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23548, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_4_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_4_s_ahb_clk = { + .halt_reg = 0x2354c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2354c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_4_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x14014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x14004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_ahb_clk = { + .halt_reg = 0x16014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16014, + .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 = 0x16004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16004, + .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_ufs_phy_ahb_clk = { + .halt_reg = 0x77028, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77028, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_axi_clk = { + .halt_reg = 0x77018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ice_core_clk = { + .halt_reg = 0x7707c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x7707c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7707c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ice_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_phy_aux_clk = { + .halt_reg = 0x770bc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x770bc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x770bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { + .halt_reg = 0x77030, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x77030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { + .halt_reg = 0x770d8, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x770d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { + .halt_reg = 0x7702c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x7702c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_tx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_unipro_core_clk = { + .halt_reg = 0x7706c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x7706c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7706c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_unipro_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_unipro_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0x39018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { + .halt_reg = 0x3902c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3902c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_sleep_clk = { + .halt_reg = 0x39028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_aux_clk = { + .halt_reg = 0x39068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + .halt_reg = 0x3906c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3906c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_com_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0x39070, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x39070, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x39070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi0_clk = { + .halt_reg = 0x32018, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x32018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi1_clk = { + .halt_reg = 0x3202c, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x3202c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3202c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gcc_pcie_0_gdsc = { + .gdscr = 0x6b004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .collapse_ctrl = 0x5214c, + .collapse_mask = BIT(0), + .pd = { + .name = "gcc_pcie_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_0_phy_gdsc = { + .gdscr = 0x6c000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .collapse_ctrl = 0x5214c, + .collapse_mask = BIT(2), + .pd = { + .name = "gcc_pcie_0_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_ufs_mem_phy_gdsc = { + .gdscr = 0x9e000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_ufs_mem_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_ufs_phy_gdsc = { + .gdscr = 0x77004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_ufs_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb30_prim_gdsc = { + .gdscr = 0x39004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb3_phy_gdsc = { + .gdscr = 0x50018, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_usb3_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gcc_kaanapali_clocks[] = { + [GCC_AGGRE_NOC_PCIE_AXI_CLK] = &gcc_aggre_noc_pcie_axi_clk.clkr, + [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, + [GCC_CAMERA_SF_AXI_CLK] = &gcc_camera_sf_axi_clk.clkr, + [GCC_CFG_NOC_PCIE_ANOC_AHB_CLK] = &gcc_cfg_noc_pcie_anoc_ahb_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_CNOC_PCIE_SF_AXI_CLK] = &gcc_cnoc_pcie_sf_axi_clk.clkr, + [GCC_DDRSS_PCIE_SF_QTB_CLK] = &gcc_ddrss_pcie_sf_qtb_clk.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_DISP_SF_AXI_CLK] = &gcc_disp_sf_axi_clk.clkr, + [GCC_EVA_AXI0_CLK] = &gcc_eva_axi0_clk.clkr, + [GCC_EVA_AXI0C_CLK] = &gcc_eva_axi0c_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPLL0] = &gcc_gpll0.clkr, + [GCC_GPLL0_OUT_EVEN] = &gcc_gpll0_out_even.clkr, + [GCC_GPLL1] = &gcc_gpll1.clkr, + [GCC_GPLL4] = &gcc_gpll4.clkr, + [GCC_GPLL7] = &gcc_gpll7.clkr, + [GCC_GPLL9] = &gcc_gpll9.clkr, + [GCC_GPU_GEMNOC_GFX_CLK] = &gcc_gpu_gemnoc_gfx_clk.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, + [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr, + [GCC_PCIE_0_AUX_CLK_SRC] = &gcc_pcie_0_aux_clk_src.clkr, + [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr, + [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr, + [GCC_PCIE_0_PHY_AUX_CLK] = &gcc_pcie_0_phy_aux_clk.clkr, + [GCC_PCIE_0_PHY_AUX_CLK_SRC] = &gcc_pcie_0_phy_aux_clk_src.clkr, + [GCC_PCIE_0_PHY_RCHNG_CLK] = &gcc_pcie_0_phy_rchng_clk.clkr, + [GCC_PCIE_0_PHY_RCHNG_CLK_SRC] = &gcc_pcie_0_phy_rchng_clk_src.clkr, + [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr, + [GCC_PCIE_0_PIPE_CLK_SRC] = &gcc_pcie_0_pipe_clk_src.clkr, + [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr, + [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = &gcc_pcie_0_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_I2C_CORE_CLK] = &gcc_qupv3_i2c_core_clk.clkr, + [GCC_QUPV3_I2C_S0_CLK] = &gcc_qupv3_i2c_s0_clk.clkr, + [GCC_QUPV3_I2C_S0_CLK_SRC] = &gcc_qupv3_i2c_s0_clk_src.clkr, + [GCC_QUPV3_I2C_S1_CLK] = &gcc_qupv3_i2c_s1_clk.clkr, + [GCC_QUPV3_I2C_S1_CLK_SRC] = &gcc_qupv3_i2c_s1_clk_src.clkr, + [GCC_QUPV3_I2C_S2_CLK] = &gcc_qupv3_i2c_s2_clk.clkr, + [GCC_QUPV3_I2C_S2_CLK_SRC] = &gcc_qupv3_i2c_s2_clk_src.clkr, + [GCC_QUPV3_I2C_S3_CLK] = &gcc_qupv3_i2c_s3_clk.clkr, + [GCC_QUPV3_I2C_S3_CLK_SRC] = &gcc_qupv3_i2c_s3_clk_src.clkr, + [GCC_QUPV3_I2C_S4_CLK] = &gcc_qupv3_i2c_s4_clk.clkr, + [GCC_QUPV3_I2C_S4_CLK_SRC] = &gcc_qupv3_i2c_s4_clk_src.clkr, + [GCC_QUPV3_I2C_S_AHB_CLK] = &gcc_qupv3_i2c_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr, + [GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr, + [GCC_QUPV3_WRAP1_QSPI_REF_CLK] = &gcc_qupv3_wrap1_qspi_ref_clk.clkr, + [GCC_QUPV3_WRAP1_QSPI_REF_CLK_SRC] = &gcc_qupv3_wrap1_qspi_ref_clk_src.clkr, + [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr, + [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr, + [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr, + [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr, + [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr, + [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr, + [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr, + [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr, + [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr, + [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr, + [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr, + [GCC_QUPV3_WRAP1_S6_CLK] = &gcc_qupv3_wrap1_s6_clk.clkr, + [GCC_QUPV3_WRAP1_S6_CLK_SRC] = &gcc_qupv3_wrap1_s6_clk_src.clkr, + [GCC_QUPV3_WRAP1_S7_CLK] = &gcc_qupv3_wrap1_s7_clk.clkr, + [GCC_QUPV3_WRAP1_S7_CLK_SRC] = &gcc_qupv3_wrap1_s7_clk_src.clkr, + [GCC_QUPV3_WRAP2_CORE_2X_CLK] = &gcc_qupv3_wrap2_core_2x_clk.clkr, + [GCC_QUPV3_WRAP2_CORE_CLK] = &gcc_qupv3_wrap2_core_clk.clkr, + [GCC_QUPV3_WRAP2_S0_CLK] = &gcc_qupv3_wrap2_s0_clk.clkr, + [GCC_QUPV3_WRAP2_S0_CLK_SRC] = &gcc_qupv3_wrap2_s0_clk_src.clkr, + [GCC_QUPV3_WRAP2_S1_CLK] = &gcc_qupv3_wrap2_s1_clk.clkr, + [GCC_QUPV3_WRAP2_S1_CLK_SRC] = &gcc_qupv3_wrap2_s1_clk_src.clkr, + [GCC_QUPV3_WRAP2_S2_CLK] = &gcc_qupv3_wrap2_s2_clk.clkr, + [GCC_QUPV3_WRAP2_S2_CLK_SRC] = &gcc_qupv3_wrap2_s2_clk_src.clkr, + [GCC_QUPV3_WRAP2_S3_CLK] = &gcc_qupv3_wrap2_s3_clk.clkr, + [GCC_QUPV3_WRAP2_S3_CLK_SRC] = &gcc_qupv3_wrap2_s3_clk_src.clkr, + [GCC_QUPV3_WRAP2_S4_CLK] = &gcc_qupv3_wrap2_s4_clk.clkr, + [GCC_QUPV3_WRAP2_S4_CLK_SRC] = &gcc_qupv3_wrap2_s4_clk_src.clkr, + [GCC_QUPV3_WRAP3_CORE_2X_CLK] = &gcc_qupv3_wrap3_core_2x_clk.clkr, + [GCC_QUPV3_WRAP3_CORE_CLK] = &gcc_qupv3_wrap3_core_clk.clkr, + [GCC_QUPV3_WRAP3_IBI_CTRL_0_CLK_SRC] = &gcc_qupv3_wrap3_ibi_ctrl_0_clk_src.clkr, + [GCC_QUPV3_WRAP3_IBI_CTRL_1_CLK] = &gcc_qupv3_wrap3_ibi_ctrl_1_clk.clkr, + [GCC_QUPV3_WRAP3_IBI_CTRL_2_CLK] = &gcc_qupv3_wrap3_ibi_ctrl_2_clk.clkr, + [GCC_QUPV3_WRAP3_S0_CLK] = &gcc_qupv3_wrap3_s0_clk.clkr, + [GCC_QUPV3_WRAP3_S0_CLK_SRC] = &gcc_qupv3_wrap3_s0_clk_src.clkr, + [GCC_QUPV3_WRAP3_S1_CLK] = &gcc_qupv3_wrap3_s1_clk.clkr, + [GCC_QUPV3_WRAP3_S1_CLK_SRC] = &gcc_qupv3_wrap3_s1_clk_src.clkr, + [GCC_QUPV3_WRAP3_S2_CLK] = &gcc_qupv3_wrap3_s2_clk.clkr, + [GCC_QUPV3_WRAP3_S2_CLK_SRC] = &gcc_qupv3_wrap3_s2_clk_src.clkr, + [GCC_QUPV3_WRAP3_S3_CLK] = &gcc_qupv3_wrap3_s3_clk.clkr, + [GCC_QUPV3_WRAP3_S3_CLK_SRC] = &gcc_qupv3_wrap3_s3_clk_src.clkr, + [GCC_QUPV3_WRAP3_S4_CLK] = &gcc_qupv3_wrap3_s4_clk.clkr, + [GCC_QUPV3_WRAP3_S4_CLK_SRC] = &gcc_qupv3_wrap3_s4_clk_src.clkr, + [GCC_QUPV3_WRAP3_S5_CLK] = &gcc_qupv3_wrap3_s5_clk.clkr, + [GCC_QUPV3_WRAP3_S5_CLK_SRC] = &gcc_qupv3_wrap3_s5_clk_src.clkr, + [GCC_QUPV3_WRAP4_CORE_2X_CLK] = &gcc_qupv3_wrap4_core_2x_clk.clkr, + [GCC_QUPV3_WRAP4_CORE_CLK] = &gcc_qupv3_wrap4_core_clk.clkr, + [GCC_QUPV3_WRAP4_S0_CLK] = &gcc_qupv3_wrap4_s0_clk.clkr, + [GCC_QUPV3_WRAP4_S0_CLK_SRC] = &gcc_qupv3_wrap4_s0_clk_src.clkr, + [GCC_QUPV3_WRAP4_S1_CLK] = &gcc_qupv3_wrap4_s1_clk.clkr, + [GCC_QUPV3_WRAP4_S1_CLK_SRC] = &gcc_qupv3_wrap4_s1_clk_src.clkr, + [GCC_QUPV3_WRAP4_S2_CLK] = &gcc_qupv3_wrap4_s2_clk.clkr, + [GCC_QUPV3_WRAP4_S2_CLK_SRC] = &gcc_qupv3_wrap4_s2_clk_src.clkr, + [GCC_QUPV3_WRAP4_S3_CLK] = &gcc_qupv3_wrap4_s3_clk.clkr, + [GCC_QUPV3_WRAP4_S3_CLK_SRC] = &gcc_qupv3_wrap4_s3_clk_src.clkr, + [GCC_QUPV3_WRAP4_S4_CLK] = &gcc_qupv3_wrap4_s4_clk.clkr, + [GCC_QUPV3_WRAP4_S4_CLK_SRC] = &gcc_qupv3_wrap4_s4_clk_src.clkr, + [GCC_QUPV3_WRAP_1_M_AXI_CLK] = &gcc_qupv3_wrap_1_m_axi_clk.clkr, + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_M_AHB_CLK] = &gcc_qupv3_wrap_2_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_S_AHB_CLK] = &gcc_qupv3_wrap_2_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_IBI_1_AHB_CLK] = &gcc_qupv3_wrap_3_ibi_1_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_IBI_2_AHB_CLK] = &gcc_qupv3_wrap_3_ibi_2_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_M_AHB_CLK] = &gcc_qupv3_wrap_3_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_S_AHB_CLK] = &gcc_qupv3_wrap_3_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_4_M_AHB_CLK] = &gcc_qupv3_wrap_4_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_4_S_AHB_CLK] = &gcc_qupv3_wrap_4_s_ahb_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_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_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, + [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_rx_symbol_0_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC] = &gcc_ufs_phy_rx_symbol_1_clk_src.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_tx_symbol_0_clk_src.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_phy_unipro_core_clk_src.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb3_prim_phy_pipe_clk_src.clkr, + [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, + [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr, + [GCC_QMIP_CAMERA_CMD_AHB_CLK] = &gcc_qmip_camera_cmd_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, + [GCC_QMIP_GPU_AHB_CLK] = &gcc_qmip_gpu_ahb_clk.clkr, + [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr, + [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr, + [GCC_QMIP_DISP_DCP_SF_AHB_CLK] = &gcc_qmip_disp_dcp_sf_ahb_clk.clkr, + [GCC_QMIP_PCIE_AHB_CLK] = &gcc_qmip_pcie_ahb_clk.clkr, + [GCC_QMIP_VIDEO_CV_CPU_AHB_CLK] = &gcc_qmip_video_cv_cpu_ahb_clk.clkr, + [GCC_QMIP_VIDEO_CVP_AHB_CLK] = &gcc_qmip_video_cvp_ahb_clk.clkr, + [GCC_QMIP_VIDEO_V_CPU_AHB_CLK] = &gcc_qmip_video_v_cpu_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, +}; + +static struct gdsc *gcc_kaanapali_gdscs[] = { + [GCC_PCIE_0_GDSC] = &gcc_pcie_0_gdsc, + [GCC_PCIE_0_PHY_GDSC] = &gcc_pcie_0_phy_gdsc, + [GCC_UFS_MEM_PHY_GDSC] = &gcc_ufs_mem_phy_gdsc, + [GCC_UFS_PHY_GDSC] = &gcc_ufs_phy_gdsc, + [GCC_USB30_PRIM_GDSC] = &gcc_usb30_prim_gdsc, + [GCC_USB3_PHY_GDSC] = &gcc_usb3_phy_gdsc, +}; + +static const struct qcom_reset_map gcc_kaanapali_resets[] = { + [GCC_CAMERA_BCR] = { 0x26000 }, + [GCC_DISPLAY_BCR] = { 0x27000 }, + [GCC_EVA_AXI0_CLK_ARES] = { 0x9f008, 2 }, + [GCC_EVA_AXI0C_CLK_ARES] = { 0x9f01c, 2 }, + [GCC_EVA_BCR] = { 0x9f000 }, + [GCC_GPU_BCR] = { 0x71000 }, + [GCC_PCIE_0_BCR] = { 0x6b000 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x6c014 }, + [GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0x6c020 }, + [GCC_PCIE_0_PHY_BCR] = { 0x6c01c }, + [GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0x6c028 }, + [GCC_PCIE_PHY_BCR] = { 0x6f000 }, + [GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x6f00c }, + [GCC_PCIE_PHY_COM_BCR] = { 0x6f010 }, + [GCC_PCIE_RSCC_BCR] = { 0x11000 }, + [GCC_PDM_BCR] = { 0x33000 }, + [GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 }, + [GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 }, + [GCC_QUPV3_WRAPPER_3_BCR] = { 0xa8000 }, + [GCC_QUPV3_WRAPPER_4_BCR] = { 0xa9000 }, + [GCC_QUPV3_WRAPPER_I2C_BCR] = { 0x17000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 }, + [GCC_SDCC2_BCR] = { 0x14000 }, + [GCC_SDCC4_BCR] = { 0x16000 }, + [GCC_UFS_PHY_BCR] = { 0x77000 }, + [GCC_USB30_PRIM_BCR] = { 0x39000 }, + [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 }, + [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 }, + [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 }, + [GCC_USB3_PHY_SEC_BCR] = { 0x5000c }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 }, + [GCC_VIDEO_AXI0_CLK_ARES] = { 0x32018, 2 }, + [GCC_VIDEO_AXI1_CLK_ARES] = { 0x3202c, 2 }, + [GCC_VIDEO_BCR] = { 0x32000 }, + [GCC_VIDEO_XO_CLK_ARES] = { 0x32040, 2 }, +}; + +static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap1_qspi_ref_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s4_clk_src), +}; + +static u32 gcc_kaanapali_critical_cbcrs[] = { + 0xa0004, /* GCC_CAM_BIST_MCLK_AHB_CLK */ + 0x26004, /* GCC_CAMERA_AHB_CLK */ + 0x2603c, /* GCC_CAMERA_XO_CLK */ + 0x27004, /* GCC_DISP_AHB_CLK */ + 0x9f004, /* GCC_EVA_AHB_CLK */ + 0x9f024, /* GCC_EVA_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0x52010, /* GCC_PCIE_RSCC_CFG_AHB_CLK */ + 0x52010, /* GCC_PCIE_RSCC_XO_CLK */ + 0x32004, /* GCC_VIDEO_AHB_CLK */ + 0x32040, /* GCC_VIDEO_XO_CLK */ +}; + +static const struct regmap_config gcc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1f41f0, + .fast_io = true, +}; + +static void clk_kaanapali_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 struct qcom_cc_driver_data gcc_kaanapali_driver_data = { + .clk_cbcrs = gcc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_kaanapali_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = clk_kaanapali_regs_configure, +}; + +static const struct qcom_cc_desc gcc_kaanapali_desc = { + .config = &gcc_kaanapali_regmap_config, + .clks = gcc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(gcc_kaanapali_clocks), + .resets = gcc_kaanapali_resets, + .num_resets = ARRAY_SIZE(gcc_kaanapali_resets), + .gdscs = gcc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_kaanapali_gdscs), + .driver_data = &gcc_kaanapali_driver_data, +}; + +static const struct of_device_id gcc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-gcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_kaanapali_match_table); + +static int gcc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gcc_kaanapali_desc); +} + +static struct platform_driver gcc_kaanapali_driver = { + .probe = gcc_kaanapali_probe, + .driver = { + .name = "gcc-kaanapali", + .of_match_table = gcc_kaanapali_match_table, + }, +}; + +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); + +MODULE_DESCRIPTION("QTI GCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); From 5f352125f8a0bc906dff8419a2377903012d7f35 Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Thu, 20 Nov 2025 13:14:10 +0000 Subject: [PATCH 020/165] dt-bindings: clock: thead,th1520-clk-ap: Add ID for C910 bus clock Add binding ID for C910 bus clock, which takes CLK_C910 as parent and is essential for C910 cluster's operation. Acked-by: Conor Dooley Signed-off-by: Yao Zi Signed-off-by: Drew Fustini --- include/dt-bindings/clock/thead,th1520-clk-ap.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/clock/thead,th1520-clk-ap.h b/include/dt-bindings/clock/thead,th1520-clk-ap.h index 09a9aa7b3ab1..68b35cc61204 100644 --- a/include/dt-bindings/clock/thead,th1520-clk-ap.h +++ b/include/dt-bindings/clock/thead,th1520-clk-ap.h @@ -93,6 +93,7 @@ #define CLK_SRAM3 83 #define CLK_PLL_GMAC_100M 84 #define CLK_UART_SCLK 85 +#define CLK_C910_BUS 86 /* VO clocks */ #define CLK_AXI4_VO_ACLK 0 From 892abfbed71e8e0fc5d6ccee1e975904805c6327 Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Thu, 20 Nov 2025 13:14:11 +0000 Subject: [PATCH 021/165] clk: thead: th1520-ap: Poll for PLL lock and wait for stability All PLLs found on TH1520 SoC take 21250ns at maximum to lock, and their lock status is indicated by register PLL_STS (offset 0x80 inside AP clock controller). We should poll the register to ensure the PLL actually locks after enabling it. Furthermore, a 30us delay is added after enabling the PLL, after which the PLL could be considered stable as stated by vendor clock code. Fixes: 56a48c1833aa ("clk: thead: add support for enabling/disabling PLLs") Reviewed-by: Drew Fustini Signed-off-by: Yao Zi Signed-off-by: Drew Fustini --- drivers/clk/thead/clk-th1520-ap.c | 34 +++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c index 71ad03a998e8..d870f0c665f8 100644 --- a/drivers/clk/thead/clk-th1520-ap.c +++ b/drivers/clk/thead/clk-th1520-ap.c @@ -8,11 +8,14 @@ #include #include #include +#include #include #include #include #include +#define TH1520_PLL_STS 0x80 + #define TH1520_PLL_POSTDIV2 GENMASK(26, 24) #define TH1520_PLL_POSTDIV1 GENMASK(22, 20) #define TH1520_PLL_FBDIV GENMASK(19, 8) @@ -23,6 +26,13 @@ #define TH1520_PLL_FRAC GENMASK(23, 0) #define TH1520_PLL_FRAC_BITS 24 +/* + * All PLLs in TH1520 take 21250ns at maximum to lock, let's take its double + * for safety. + */ +#define TH1520_PLL_LOCK_TIMEOUT_US 44 +#define TH1520_PLL_STABLE_DELAY_US 30 + struct ccu_internal { u8 shift; u8 width; @@ -64,6 +74,7 @@ struct ccu_div { struct ccu_pll { struct ccu_common common; + u32 lock_sts_mask; }; #define TH_CCU_ARG(_shift, _width) \ @@ -299,9 +310,21 @@ static void ccu_pll_disable(struct clk_hw *hw) static int ccu_pll_enable(struct clk_hw *hw) { struct ccu_pll *pll = hw_to_ccu_pll(hw); + u32 reg; + int ret; - return regmap_clear_bits(pll->common.map, pll->common.cfg1, - TH1520_PLL_VCO_RST); + regmap_clear_bits(pll->common.map, pll->common.cfg1, + TH1520_PLL_VCO_RST); + + ret = regmap_read_poll_timeout_atomic(pll->common.map, TH1520_PLL_STS, + reg, reg & pll->lock_sts_mask, + 5, TH1520_PLL_LOCK_TIMEOUT_US); + if (ret) + return ret; + + udelay(TH1520_PLL_STABLE_DELAY_US); + + return 0; } static int ccu_pll_is_enabled(struct clk_hw *hw) @@ -389,6 +412,7 @@ static struct ccu_pll cpu_pll0_clk = { &clk_pll_ops, CLK_IS_CRITICAL), }, + .lock_sts_mask = BIT(1), }; static struct ccu_pll cpu_pll1_clk = { @@ -401,6 +425,7 @@ static struct ccu_pll cpu_pll1_clk = { &clk_pll_ops, CLK_IS_CRITICAL), }, + .lock_sts_mask = BIT(4), }; static struct ccu_pll gmac_pll_clk = { @@ -413,6 +438,7 @@ static struct ccu_pll gmac_pll_clk = { &clk_pll_ops, CLK_IS_CRITICAL), }, + .lock_sts_mask = BIT(3), }; static const struct clk_hw *gmac_pll_clk_parent[] = { @@ -433,6 +459,7 @@ static struct ccu_pll video_pll_clk = { &clk_pll_ops, CLK_IS_CRITICAL), }, + .lock_sts_mask = BIT(7), }; static const struct clk_hw *video_pll_clk_parent[] = { @@ -453,6 +480,7 @@ static struct ccu_pll dpu0_pll_clk = { &clk_pll_ops, 0), }, + .lock_sts_mask = BIT(8), }; static const struct clk_hw *dpu0_pll_clk_parent[] = { @@ -469,6 +497,7 @@ static struct ccu_pll dpu1_pll_clk = { &clk_pll_ops, 0), }, + .lock_sts_mask = BIT(9), }; static const struct clk_hw *dpu1_pll_clk_parent[] = { @@ -485,6 +514,7 @@ static struct ccu_pll tee_pll_clk = { &clk_pll_ops, CLK_IS_CRITICAL), }, + .lock_sts_mask = BIT(10), }; static const struct clk_parent_data c910_i0_parents[] = { From b436f8a82aaa3bd54cb79b1219d94a99f7351d33 Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Thu, 20 Nov 2025 13:14:12 +0000 Subject: [PATCH 022/165] clk: thead: th1520-ap: Add C910 bus clock This divider takes c910_clk as parent and is essential for the C910 cluster to operate, thus is marked as CLK_IS_CRITICAL. Reviewed-by: Drew Fustini Signed-off-by: Yao Zi Signed-off-by: Drew Fustini --- drivers/clk/thead/clk-th1520-ap.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c index d870f0c665f8..b820d47387bb 100644 --- a/drivers/clk/thead/clk-th1520-ap.c +++ b/drivers/clk/thead/clk-th1520-ap.c @@ -539,6 +539,20 @@ static struct ccu_mux c910_clk = { .mux = TH_CCU_MUX("c910", c910_parents, 0, 1), }; +static struct ccu_div c910_bus_clk = { + .enable = BIT(7), + .div_en = BIT(11), + .div = TH_CCU_DIV_FLAGS(8, 3, 0), + .common = { + .clkid = CLK_C910_BUS, + .cfg0 = 0x100, + .hw.init = CLK_HW_INIT_HW("c910-bus", + &c910_clk.mux.hw, + &ccu_div_ops, + CLK_IS_CRITICAL), + }, +}; + static const struct clk_parent_data ahb2_cpusys_parents[] = { { .hw = &gmac_pll_clk.common.hw }, { .index = 0 } @@ -1051,6 +1065,7 @@ static struct ccu_common *th1520_pll_clks[] = { }; static struct ccu_common *th1520_div_clks[] = { + &c910_bus_clk.common, &ahb2_cpusys_hclk.common, &apb3_cpusys_pclk.common, &axi4_cpusys2_aclk.common, @@ -1194,7 +1209,7 @@ static const struct th1520_plat_data th1520_ap_platdata = { .th1520_mux_clks = th1520_mux_clks, .th1520_gate_clks = th1520_gate_clks, - .nr_clks = CLK_UART_SCLK + 1, + .nr_clks = CLK_C910_BUS + 1, .nr_pll_clks = ARRAY_SIZE(th1520_pll_clks), .nr_div_clks = ARRAY_SIZE(th1520_div_clks), From 238cc6316a885765fd52a6dc65b9ca4e47647b1e Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Thu, 20 Nov 2025 13:14:13 +0000 Subject: [PATCH 023/165] clk: thead: th1520-ap: Support setting PLL rates TH1520 ships several PLLs that could operate in either integer or fractional mode. However, the TRM only lists a few configuration whose stability is considered guaranteed. Add a table-lookup rate determination logic to support PLL rate setting, and fill up frequency-configuration tables for AP-subsystem PLLs. Reviewed-by: Drew Fustini Signed-off-by: Yao Zi Signed-off-by: Drew Fustini --- drivers/clk/thead/clk-th1520-ap.c | 142 ++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c index b820d47387bb..bf8e80c39a9e 100644 --- a/drivers/clk/thead/clk-th1520-ap.c +++ b/drivers/clk/thead/clk-th1520-ap.c @@ -22,6 +22,7 @@ #define TH1520_PLL_REFDIV GENMASK(5, 0) #define TH1520_PLL_BYPASS BIT(30) #define TH1520_PLL_VCO_RST BIT(29) +#define TH1520_PLL_DACPD BIT(25) #define TH1520_PLL_DSMPD BIT(24) #define TH1520_PLL_FRAC GENMASK(23, 0) #define TH1520_PLL_FRAC_BITS 24 @@ -72,9 +73,19 @@ struct ccu_div { struct ccu_common common; }; +struct ccu_pll_cfg { + unsigned long freq; + u32 fbdiv; + u32 frac; + u32 postdiv1; + u32 postdiv2; +}; + struct ccu_pll { struct ccu_common common; u32 lock_sts_mask; + int cfgnum; + const struct ccu_pll_cfg *cfgs; }; #define TH_CCU_ARG(_shift, _width) \ @@ -391,17 +402,102 @@ static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw, return rate; } +static const struct ccu_pll_cfg *ccu_pll_lookup_best_cfg(struct ccu_pll *pll, + unsigned long rate) +{ + unsigned long best_delta = ULONG_MAX; + const struct ccu_pll_cfg *best_cfg; + int i; + + for (i = 0; i < pll->cfgnum; i++) { + const struct ccu_pll_cfg *cfg = &pll->cfgs[i]; + unsigned long delta; + + delta = abs_diff(cfg->freq, rate); + if (delta < best_delta) { + best_delta = delta; + best_cfg = cfg; + } + } + + return best_cfg; +} + +static int ccu_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + + req->rate = ccu_pll_lookup_best_cfg(pll, req->rate)->freq; + + return 0; +} + +static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + const struct ccu_pll_cfg *cfg; + + cfg = ccu_pll_lookup_best_cfg(pll, rate); + + ccu_pll_disable(hw); + + regmap_write(pll->common.map, pll->common.cfg0, + FIELD_PREP(TH1520_PLL_REFDIV, 1) | + FIELD_PREP(TH1520_PLL_FBDIV, cfg->fbdiv) | + FIELD_PREP(TH1520_PLL_POSTDIV1, cfg->postdiv1) | + FIELD_PREP(TH1520_PLL_POSTDIV2, cfg->postdiv2)); + + regmap_update_bits(pll->common.map, pll->common.cfg1, + TH1520_PLL_DACPD | TH1520_PLL_DSMPD | + TH1520_PLL_FRAC, + cfg->frac ? cfg->frac : + TH1520_PLL_DACPD | TH1520_PLL_DSMPD); + + return ccu_pll_enable(hw); +} + static const struct clk_ops clk_pll_ops = { .disable = ccu_pll_disable, .enable = ccu_pll_enable, .is_enabled = ccu_pll_is_enabled, .recalc_rate = ccu_pll_recalc_rate, + .determine_rate = ccu_pll_determine_rate, + .set_rate = ccu_pll_set_rate, }; static const struct clk_parent_data osc_24m_clk[] = { { .index = 0 } }; +static const struct ccu_pll_cfg cpu_pll_cfgs[] = { + { 125000000, 125, 0, 6, 4 }, + { 200000000, 125, 0, 5, 3 }, + { 300000000, 125, 0, 5, 2 }, + { 400000000, 100, 0, 3, 2 }, + { 500000000, 125, 0, 6, 1 }, + { 600000000, 125, 0, 5, 1 }, + { 702000000, 117, 0, 4, 1 }, + { 800000000, 100, 0, 3, 1 }, + { 900000000, 75, 0, 2, 1 }, + { 1000000000, 125, 0, 3, 1 }, + { 1104000000, 92, 0, 2, 1 }, + { 1200000000, 100, 0, 2, 1 }, + { 1296000000, 108, 0, 2, 1 }, + { 1404000000, 117, 0, 2, 1 }, + { 1500000000, 125, 0, 2, 1 }, + { 1608000000, 67, 0, 1, 1 }, + { 1704000000, 71, 0, 1, 1 }, + { 1800000000, 75, 0, 1, 1 }, + { 1896000000, 79, 0, 1, 1 }, + { 1992000000, 83, 0, 1, 1 }, + { 2112000000, 88, 0, 1, 1 }, + { 2208000000, 92, 0, 1, 1 }, + { 2304000000, 96, 0, 1, 1 }, + { 2400000000, 100, 0, 1, 1 }, +}; + static struct ccu_pll cpu_pll0_clk = { .common = { .clkid = CLK_CPU_PLL0, @@ -413,6 +509,8 @@ static struct ccu_pll cpu_pll0_clk = { CLK_IS_CRITICAL), }, .lock_sts_mask = BIT(1), + .cfgnum = ARRAY_SIZE(cpu_pll_cfgs), + .cfgs = cpu_pll_cfgs, }; static struct ccu_pll cpu_pll1_clk = { @@ -426,6 +524,16 @@ static struct ccu_pll cpu_pll1_clk = { CLK_IS_CRITICAL), }, .lock_sts_mask = BIT(4), + .cfgnum = ARRAY_SIZE(cpu_pll_cfgs), + .cfgs = cpu_pll_cfgs, +}; + +static const struct ccu_pll_cfg gmac_pll_cfg = { + .freq = 1000000000, + .fbdiv = 125, + .frac = 0, + .postdiv1 = 3, + .postdiv2 = 1, }; static struct ccu_pll gmac_pll_clk = { @@ -439,6 +547,8 @@ static struct ccu_pll gmac_pll_clk = { CLK_IS_CRITICAL), }, .lock_sts_mask = BIT(3), + .cfgnum = 1, + .cfgs = &gmac_pll_cfg, }; static const struct clk_hw *gmac_pll_clk_parent[] = { @@ -449,6 +559,14 @@ static const struct clk_parent_data gmac_pll_clk_pd[] = { { .hw = &gmac_pll_clk.common.hw } }; +static const struct ccu_pll_cfg video_pll_cfg = { + .freq = 792000000, + .fbdiv = 99, + .frac = 0, + .postdiv1 = 3, + .postdiv2 = 1, +}; + static struct ccu_pll video_pll_clk = { .common = { .clkid = CLK_VIDEO_PLL, @@ -460,6 +578,8 @@ static struct ccu_pll video_pll_clk = { CLK_IS_CRITICAL), }, .lock_sts_mask = BIT(7), + .cfgnum = 1, + .cfgs = &video_pll_cfg, }; static const struct clk_hw *video_pll_clk_parent[] = { @@ -470,6 +590,14 @@ static const struct clk_parent_data video_pll_clk_pd[] = { { .hw = &video_pll_clk.common.hw } }; +static const struct ccu_pll_cfg dpu_pll_cfg = { + .freq = 1188000000, + .fbdiv = 99, + .frac = 0, + .postdiv1 = 2, + .postdiv2 = 1, +}; + static struct ccu_pll dpu0_pll_clk = { .common = { .clkid = CLK_DPU0_PLL, @@ -481,6 +609,8 @@ static struct ccu_pll dpu0_pll_clk = { 0), }, .lock_sts_mask = BIT(8), + .cfgnum = 1, + .cfgs = &dpu_pll_cfg, }; static const struct clk_hw *dpu0_pll_clk_parent[] = { @@ -498,12 +628,22 @@ static struct ccu_pll dpu1_pll_clk = { 0), }, .lock_sts_mask = BIT(9), + .cfgnum = 1, + .cfgs = &dpu_pll_cfg, }; static const struct clk_hw *dpu1_pll_clk_parent[] = { &dpu1_pll_clk.common.hw }; +static const struct ccu_pll_cfg tee_pll_cfg = { + .freq = 792000000, + .fbdiv = 99, + .frac = 0, + .postdiv1 = 3, + .postdiv2 = 1, +}; + static struct ccu_pll tee_pll_clk = { .common = { .clkid = CLK_TEE_PLL, @@ -515,6 +655,8 @@ static struct ccu_pll tee_pll_clk = { CLK_IS_CRITICAL), }, .lock_sts_mask = BIT(10), + .cfgnum = 1, + .cfgs = &tee_pll_cfg, }; static const struct clk_parent_data c910_i0_parents[] = { From 5dbee3503771a36464e0b39a420475a727911c83 Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Thu, 20 Nov 2025 13:14:14 +0000 Subject: [PATCH 024/165] clk: thead: th1520-ap: Add macro to define multiplexers with flags The new macro, TH_CCU_MUX_FLAGS, extends TH_CCU_MUX macro by adding two parameters to specify clock flags and multiplexer flags. Reviewed-by: Drew Fustini Signed-off-by: Yao Zi Signed-off-by: Drew Fustini --- drivers/clk/thead/clk-th1520-ap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c index bf8e80c39a9e..79f001a047b2 100644 --- a/drivers/clk/thead/clk-th1520-ap.c +++ b/drivers/clk/thead/clk-th1520-ap.c @@ -101,17 +101,22 @@ struct ccu_pll { .flags = _flags, \ } -#define TH_CCU_MUX(_name, _parents, _shift, _width) \ +#define TH_CCU_MUX_FLAGS(_name, _parents, _shift, _width, _flags, \ + _mux_flags) \ { \ .mask = GENMASK(_width - 1, 0), \ .shift = _shift, \ + .flags = _mux_flags, \ .hw.init = CLK_HW_INIT_PARENTS_DATA( \ _name, \ _parents, \ &clk_mux_ops, \ - 0), \ + _flags), \ } +#define TH_CCU_MUX(_name, _parents, _shift, _width) \ + TH_CCU_MUX_FLAGS(_name, _parents, _shift, _width, 0, 0) + #define CCU_GATE(_clkid, _struct, _name, _parent, _reg, _bit, _flags) \ struct ccu_gate _struct = { \ .clkid = _clkid, \ From db1cc4902f2f51977e427f796ea8daf49ba93c69 Mon Sep 17 00:00:00 2001 From: Raghav Sharma Date: Wed, 19 Nov 2025 17:17:42 +0530 Subject: [PATCH 025/165] dt-bindings: clock: exynosautov920: add MFD clock definitions Add device tree clock binding definitions for CMU_MFD Signed-off-by: Raghav Sharma Reviewed-by: Alim Akhtar Acked-by: Rob Herring (Arm) Link: https://patch.msgid.link/20251119114744.1914416-2-raghav.s@samsung.com Signed-off-by: Krzysztof Kozlowski --- .../clock/samsung,exynosautov920-clock.yaml | 19 +++++++++++++++++++ .../clock/samsung,exynosautov920.h | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml index 5bf905f88a1a..1318720193b3 100644 --- a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml +++ b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml @@ -40,6 +40,7 @@ properties: - samsung,exynosautov920-cmu-hsi2 - samsung,exynosautov920-cmu-m2m - samsung,exynosautov920-cmu-mfc + - samsung,exynosautov920-cmu-mfd - samsung,exynosautov920-cmu-misc - samsung,exynosautov920-cmu-peric0 - samsung,exynosautov920-cmu-peric1 @@ -268,6 +269,24 @@ allOf: - const: mfc - const: wfd + - if: + properties: + compatible: + contains: + const: samsung,exynosautov920-cmu-mfd + + then: + properties: + clocks: + items: + - description: External reference clock (38.4 MHz) + - description: CMU_MFD NOC clock (from CMU_TOP) + + clock-names: + items: + - const: oscclk + - const: noc + required: - compatible - "#clock-cells" diff --git a/include/dt-bindings/clock/samsung,exynosautov920.h b/include/dt-bindings/clock/samsung,exynosautov920.h index 970d05167fc6..06dec27a8c77 100644 --- a/include/dt-bindings/clock/samsung,exynosautov920.h +++ b/include/dt-bindings/clock/samsung,exynosautov920.h @@ -305,4 +305,8 @@ #define CLK_MOUT_MFC_WFD_USER 2 #define CLK_DOUT_MFC_NOCP 3 +/* CMU_MFD */ +#define CLK_MOUT_MFD_NOC_USER 1 +#define CLK_DOUT_MFD_NOCP 2 + #endif /* _DT_BINDINGS_CLOCK_EXYNOSAUTOV920_H */ From efa45bcc73e1a30705eed28933e341d36a08bb84 Mon Sep 17 00:00:00 2001 From: Raghav Sharma Date: Wed, 19 Nov 2025 17:17:43 +0530 Subject: [PATCH 026/165] clk: samsung: exynosautov920: add clock support Add support for CMU_MFD which provides clocks to MFD block, and register the required compatible and cmu_info for the same. Signed-off-by: Raghav Sharma Reviewed-by: Alim Akhtar Link: https://patch.msgid.link/20251119114744.1914416-3-raghav.s@samsung.com Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-exynosautov920.c | 40 ++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/clk/samsung/clk-exynosautov920.c b/drivers/clk/samsung/clk-exynosautov920.c index b90b73c3518f..d0617c7fff3a 100644 --- a/drivers/clk/samsung/clk-exynosautov920.c +++ b/drivers/clk/samsung/clk-exynosautov920.c @@ -29,6 +29,7 @@ #define CLKS_NR_HSI2 (CLK_DOUT_HSI2_ETHERNET_PTP + 1) #define CLKS_NR_M2M (CLK_DOUT_M2M_NOCP + 1) #define CLKS_NR_MFC (CLK_DOUT_MFC_NOCP + 1) +#define CLKS_NR_MFD (CLK_DOUT_MFD_NOCP + 1) /* ---- CMU_TOP ------------------------------------------------------------ */ @@ -1905,6 +1906,42 @@ static const struct samsung_cmu_info mfc_cmu_info __initconst = { .clk_name = "noc", }; +/* ---- CMU_MFD --------------------------------------------------------- */ + +/* Register Offset definitions for CMU_MFD (0x19e00000) */ +#define PLL_CON0_MUX_CLKCMU_MFD_NOC_USER 0x600 +#define CLK_CON_DIV_DIV_CLK_MFD_NOCP 0x1800 + +static const unsigned long mfd_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_MFD_NOC_USER, + CLK_CON_DIV_DIV_CLK_MFD_NOCP, +}; + +/* List of parent clocks for Muxes in CMU_MFD */ +PNAME(mout_clkcmu_mfd_noc_user_p) = { "oscclk", "dout_clkcmu_mfd_noc" }; + +static const struct samsung_mux_clock mfd_mux_clks[] __initconst = { + MUX(CLK_MOUT_MFD_NOC_USER, "mout_clkcmu_mfd_noc_user", + mout_clkcmu_mfd_noc_user_p, PLL_CON0_MUX_CLKCMU_MFD_NOC_USER, 4, 1), +}; + +static const struct samsung_div_clock mfd_div_clks[] __initconst = { + DIV(CLK_DOUT_MFD_NOCP, "dout_mfd_nocp", + "mout_clkcmu_mfd_noc_user", CLK_CON_DIV_DIV_CLK_MFD_NOCP, + 0, 3), +}; + +static const struct samsung_cmu_info mfd_cmu_info __initconst = { + .mux_clks = mfd_mux_clks, + .nr_mux_clks = ARRAY_SIZE(mfd_mux_clks), + .div_clks = mfd_div_clks, + .nr_div_clks = ARRAY_SIZE(mfd_div_clks), + .nr_clk_ids = CLKS_NR_MFD, + .clk_regs = mfd_clk_regs, + .nr_clk_regs = ARRAY_SIZE(mfd_clk_regs), + .clk_name = "noc", +}; + static int __init exynosautov920_cmu_probe(struct platform_device *pdev) { const struct samsung_cmu_info *info; @@ -1941,6 +1978,9 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = { }, { .compatible = "samsung,exynosautov920-cmu-mfc", .data = &mfc_cmu_info, + }, { + .compatible = "samsung,exynosautov920-cmu-mfd", + .data = &mfd_cmu_info, }, { } }; From 2e8e9a2492edbbef54de6ab1c5bf1578ffef4c8c Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Mon, 22 Dec 2025 10:22:12 +0000 Subject: [PATCH 027/165] dt-bindings: clock: google,gs101-clock: add samsung,sysreg property as required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each CMU (with the exception of cmu_top) has a corresponding sysreg bank that contains the BUSCOMPONENT_DRCG_EN and optional MEMCLK registers. The BUSCOMPONENT_DRCG_EN register enables dynamic root clock gating of bus components and MEMCLK gates the sram clock. Now the clock driver supports automatic clock mode, to fully enable dynamic root clock gating it is required to configure these registers. Update the bindings documentation so that all CMUs (with the exception of gs101-cmu-top) have samsung,sysreg as a required property. Note this is NOT an ABI break, as if the property isn't specified the clock driver will fallback to the current behaviour of not initializing the registers. The system still boots, but bus components won't benefit from dynamic root clock gating and dynamic power will be higher (which has been the case until now anyway). Additionally update the DT example to included the correct CMU size as registers in that region are used for automatic clock mode. Acked-by: Rob Herring (Arm) Reviewed-by: André Draszik Reviewed-by: Rob Herring (Arm) Signed-off-by: Peter Griffin Link: https://patch.msgid.link/20251222-automatic-clocks-v7-1-fec86fa89874@linaro.org Signed-off-by: Krzysztof Kozlowski --- .../bindings/clock/google,gs101-clock.yaml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml b/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml index 31e106ef913d..09e679c1a9de 100644 --- a/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml +++ b/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml @@ -52,6 +52,11 @@ properties: reg: maxItems: 1 + samsung,sysreg: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to system registers interface. + required: - compatible - "#clock-cells" @@ -166,6 +171,18 @@ allOf: - const: bus - const: ip + - if: + properties: + compatible: + contains: + const: google,gs101-cmu-top + then: + properties: + samsung,sysreg: false + else: + required: + - samsung,sysreg + additionalProperties: false examples: @@ -175,7 +192,7 @@ examples: cmu_top: clock-controller@1e080000 { compatible = "google,gs101-cmu-top"; - reg = <0x1e080000 0x8000>; + reg = <0x1e080000 0x10000>; #clock-cells = <1>; clocks = <&ext_24_5m>; clock-names = "oscclk"; From 298fac4f4b96448ce7ef8da525a74fd3dba0035d Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Mon, 22 Dec 2025 10:22:14 +0000 Subject: [PATCH 028/165] clk: samsung: Implement automatic clock gating mode for CMUs Update exynos_arm64_init_clocks() so that it enables the automatic clock mode bits in the CMU option register if the auto_clock_gate flag and option_offset fields are set for the CMU. To ensure compatibility with older DTs (that specified an incorrect CMU reg size), detect this and fallback to manual clock gate mode as the auto clock mode feature depends on registers in this area. The CMU option register bits are global and effect every clock component in the CMU, as such clearing the GATE_ENABLE_HWACG bit and setting GATE_MANUAL bit on every gate register is only required if auto_clock_gate is false. Additionally if auto_clock_gate is enabled the dynamic root clock gating and memclk registers will be configured in the corresponding CMUs sysreg bank. These registers are exposed via syscon, so the register samsung_clk_save/restore paths are updated to also take a regmap. As many gates for various Samsung SoCs are already exposed in the Samsung clock drivers a new samsung_auto_clk_gate_ops is implemented. This uses some CMU debug registers to report whether clocks are enabled or disabled when operating in automatic mode. This allows /sys/kernel/debug/clk/clk_summary to still dump the entire clock tree and correctly report the status of each clock in the system. Signed-off-by: Peter Griffin Link: https://patch.msgid.link/20251222-automatic-clocks-v7-3-fec86fa89874@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-exynos-arm64.c | 62 ++++++- drivers/clk/samsung/clk-exynos4.c | 12 +- drivers/clk/samsung/clk-exynos4412-isp.c | 4 +- drivers/clk/samsung/clk-exynos5250.c | 2 +- drivers/clk/samsung/clk-exynos5420.c | 4 +- drivers/clk/samsung/clk-s3c64xx.c | 4 +- drivers/clk/samsung/clk-s5pv210.c | 2 +- drivers/clk/samsung/clk.c | 200 +++++++++++++++++++++-- drivers/clk/samsung/clk.h | 55 ++++++- 9 files changed, 302 insertions(+), 43 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos-arm64.c b/drivers/clk/samsung/clk-exynos-arm64.c index bf7de21f329e..11e4d49f2390 100644 --- a/drivers/clk/samsung/clk-exynos-arm64.c +++ b/drivers/clk/samsung/clk-exynos-arm64.c @@ -24,6 +24,16 @@ #define GATE_MANUAL BIT(20) #define GATE_ENABLE_HWACG BIT(28) +/* Option register bits */ +#define OPT_EN_MEM_PWR_GATING BIT(24) +#define OPT_EN_AUTO_GATING BIT(28) +#define OPT_EN_PWR_MANAGEMENT BIT(29) +#define OPT_EN_LAYER2_CTRL BIT(30) +#define OPT_EN_DBG BIT(31) + +#define CMU_OPT_GLOBAL_EN_AUTO_GATING (OPT_EN_DBG | OPT_EN_LAYER2_CTRL | \ + OPT_EN_PWR_MANAGEMENT | OPT_EN_AUTO_GATING | OPT_EN_MEM_PWR_GATING) + /* PLL_CONx_PLL register offsets range */ #define PLL_CON_OFF_START 0x100 #define PLL_CON_OFF_END 0x600 @@ -37,6 +47,8 @@ struct exynos_arm64_cmu_data { unsigned int nr_clk_save; const struct samsung_clk_reg_dump *clk_suspend; unsigned int nr_clk_suspend; + struct samsung_clk_reg_dump *clk_sysreg_save; + unsigned int nr_clk_sysreg; struct clk *clk; struct clk **pclks; @@ -76,19 +88,41 @@ static void __init exynos_arm64_init_clocks(struct device_node *np, const unsigned long *reg_offs = cmu->clk_regs; size_t reg_offs_len = cmu->nr_clk_regs; void __iomem *reg_base; + bool init_auto; size_t i; reg_base = of_iomap(np, 0); if (!reg_base) panic("%s: failed to map registers\n", __func__); + /* ensure compatibility with older DTs */ + if (cmu->auto_clock_gate && samsung_is_auto_capable(np)) + init_auto = true; + else + init_auto = false; + + if (cmu->option_offset && init_auto) { + /* + * Enable the global automatic mode for the entire CMU. + * This overrides the individual HWACG bits in each of the + * individual gate, mux and qch registers. + */ + writel(CMU_OPT_GLOBAL_EN_AUTO_GATING, + reg_base + cmu->option_offset); + } + for (i = 0; i < reg_offs_len; ++i) { void __iomem *reg = reg_base + reg_offs[i]; u32 val; if (cmu->manual_plls && is_pll_con1_reg(reg_offs[i])) { writel(PLL_CON1_MANUAL, reg); - } else if (is_gate_reg(reg_offs[i])) { + } else if (is_gate_reg(reg_offs[i]) && !init_auto) { + /* + * Setting GATE_MANUAL bit (which is described in TRM as + * reserved!) overrides the global CMU automatic mode + * option. + */ val = readl(reg); val |= GATE_MANUAL; val &= ~GATE_ENABLE_HWACG; @@ -210,8 +244,8 @@ void __init exynos_arm64_register_cmu(struct device *dev, /** * exynos_arm64_register_cmu_pm - Register Exynos CMU domain with PM support * - * @pdev: Platform device object - * @set_manual: If true, set gate clocks to manual mode + * @pdev: Platform device object + * @init_clk_regs: If true, initialize CMU registers * * It's a version of exynos_arm64_register_cmu() with PM support. Should be * called from probe function of platform driver. @@ -219,7 +253,7 @@ void __init exynos_arm64_register_cmu(struct device *dev, * Return: 0 on success, or negative error code on error. */ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev, - bool set_manual) + bool init_clk_regs) { const struct samsung_cmu_info *cmu; struct device *dev = &pdev->dev; @@ -249,7 +283,7 @@ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev, dev_err(dev, "%s: could not enable bus clock %s; err = %d\n", __func__, cmu->clk_name, ret); - if (set_manual) + if (init_clk_regs) exynos_arm64_init_clocks(np, cmu); reg_base = devm_platform_ioremap_resource(pdev, 0); @@ -268,8 +302,10 @@ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev, pm_runtime_set_active(dev); pm_runtime_enable(dev); - samsung_cmu_register_clocks(data->ctx, cmu); + samsung_cmu_register_clocks(data->ctx, cmu, np); samsung_clk_of_add_provider(dev->of_node, data->ctx); + /* sysreg DT nodes reference a clock in this CMU */ + samsung_en_dyn_root_clk_gating(np, data->ctx, cmu); pm_runtime_put_sync(dev); return 0; @@ -280,14 +316,17 @@ int exynos_arm64_cmu_suspend(struct device *dev) struct exynos_arm64_cmu_data *data = dev_get_drvdata(dev); int i; - samsung_clk_save(data->ctx->reg_base, data->clk_save, + samsung_clk_save(data->ctx->reg_base, NULL, data->clk_save, data->nr_clk_save); + samsung_clk_save(NULL, data->ctx->sysreg, data->clk_sysreg_save, + data->nr_clk_sysreg); + for (i = 0; i < data->nr_pclks; i++) clk_prepare_enable(data->pclks[i]); /* For suspend some registers have to be set to certain values */ - samsung_clk_restore(data->ctx->reg_base, data->clk_suspend, + samsung_clk_restore(data->ctx->reg_base, NULL, data->clk_suspend, data->nr_clk_suspend); for (i = 0; i < data->nr_pclks; i++) @@ -308,9 +347,14 @@ int exynos_arm64_cmu_resume(struct device *dev) for (i = 0; i < data->nr_pclks; i++) clk_prepare_enable(data->pclks[i]); - samsung_clk_restore(data->ctx->reg_base, data->clk_save, + samsung_clk_restore(data->ctx->reg_base, NULL, data->clk_save, data->nr_clk_save); + if (data->ctx->sysreg) + samsung_clk_restore(NULL, data->ctx->sysreg, + data->clk_sysreg_save, + data->nr_clk_sysreg); + for (i = 0; i < data->nr_pclks; i++) clk_disable_unprepare(data->pclks[i]); diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index cc5c1644c41c..246bd28bac2d 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -1361,12 +1361,12 @@ static void __init exynos4_clk_init(struct device_node *np, ARRAY_SIZE(exynos4x12_plls)); } - samsung_cmu_register_clocks(ctx, &cmu_info_exynos4); + samsung_cmu_register_clocks(ctx, &cmu_info_exynos4, np); if (exynos4_soc == EXYNOS4210) { - samsung_cmu_register_clocks(ctx, &cmu_info_exynos4210); + samsung_cmu_register_clocks(ctx, &cmu_info_exynos4210, np); } else { - samsung_cmu_register_clocks(ctx, &cmu_info_exynos4x12); + samsung_cmu_register_clocks(ctx, &cmu_info_exynos4x12, np); if (soc == EXYNOS4412) samsung_clk_register_cpu(ctx, exynos4412_cpu_clks, ARRAY_SIZE(exynos4412_cpu_clks)); @@ -1378,15 +1378,15 @@ static void __init exynos4_clk_init(struct device_node *np, if (soc == EXYNOS4212 || soc == EXYNOS4412) exynos4x12_core_down_clock(); - samsung_clk_extended_sleep_init(reg_base, + samsung_clk_extended_sleep_init(reg_base, NULL, exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), src_mask_suspend, ARRAY_SIZE(src_mask_suspend)); if (exynos4_soc == EXYNOS4210) - samsung_clk_extended_sleep_init(reg_base, + samsung_clk_extended_sleep_init(reg_base, NULL, exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save), src_mask_suspend_e4210, ARRAY_SIZE(src_mask_suspend_e4210)); else - samsung_clk_sleep_init(reg_base, exynos4x12_clk_save, + samsung_clk_sleep_init(reg_base, NULL, exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save)); samsung_clk_of_add_provider(np, ctx); diff --git a/drivers/clk/samsung/clk-exynos4412-isp.c b/drivers/clk/samsung/clk-exynos4412-isp.c index fa915057e109..772bc18a1e68 100644 --- a/drivers/clk/samsung/clk-exynos4412-isp.c +++ b/drivers/clk/samsung/clk-exynos4412-isp.c @@ -94,7 +94,7 @@ static int __maybe_unused exynos4x12_isp_clk_suspend(struct device *dev) { struct samsung_clk_provider *ctx = dev_get_drvdata(dev); - samsung_clk_save(ctx->reg_base, exynos4x12_save_isp, + samsung_clk_save(ctx->reg_base, NULL, exynos4x12_save_isp, ARRAY_SIZE(exynos4x12_clk_isp_save)); return 0; } @@ -103,7 +103,7 @@ static int __maybe_unused exynos4x12_isp_clk_resume(struct device *dev) { struct samsung_clk_provider *ctx = dev_get_drvdata(dev); - samsung_clk_restore(ctx->reg_base, exynos4x12_save_isp, + samsung_clk_restore(ctx->reg_base, NULL, exynos4x12_save_isp, ARRAY_SIZE(exynos4x12_clk_isp_save)); return 0; } diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index e90d3a0848cb..f97f30b29be7 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -854,7 +854,7 @@ static void __init exynos5250_clk_init(struct device_node *np) PWR_CTRL2_CORE2_UP_RATIO | PWR_CTRL2_CORE1_UP_RATIO); __raw_writel(tmp, reg_base + PWR_CTRL2); - samsung_clk_sleep_init(reg_base, exynos5250_clk_regs, + samsung_clk_sleep_init(reg_base, NULL, exynos5250_clk_regs, ARRAY_SIZE(exynos5250_clk_regs)); exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5250_subcmus), exynos5250_subcmus); diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index a9df4e6db82f..1982e0751cee 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -1649,12 +1649,12 @@ static void __init exynos5x_clk_init(struct device_node *np, ARRAY_SIZE(exynos5800_cpu_clks)); } - samsung_clk_extended_sleep_init(reg_base, + samsung_clk_extended_sleep_init(reg_base, NULL, exynos5x_clk_regs, ARRAY_SIZE(exynos5x_clk_regs), exynos5420_set_clksrc, ARRAY_SIZE(exynos5420_set_clksrc)); if (soc == EXYNOS5800) { - samsung_clk_sleep_init(reg_base, exynos5800_clk_regs, + samsung_clk_sleep_init(reg_base, NULL, exynos5800_clk_regs, ARRAY_SIZE(exynos5800_clk_regs)); exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5800_subcmus), diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index 397a057af5d1..5a2d5a5703ff 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -449,10 +449,10 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, samsung_clk_register_alias(ctx, s3c64xx_clock_aliases, ARRAY_SIZE(s3c64xx_clock_aliases)); - samsung_clk_sleep_init(reg_base, s3c64xx_clk_regs, + samsung_clk_sleep_init(reg_base, NULL, s3c64xx_clk_regs, ARRAY_SIZE(s3c64xx_clk_regs)); if (!is_s3c6400) - samsung_clk_sleep_init(reg_base, s3c6410_clk_regs, + samsung_clk_sleep_init(reg_base, NULL, s3c6410_clk_regs, ARRAY_SIZE(s3c6410_clk_regs)); samsung_clk_of_add_provider(np, ctx); diff --git a/drivers/clk/samsung/clk-s5pv210.c b/drivers/clk/samsung/clk-s5pv210.c index 9a4217cc1908..4ee4f2b5efbc 100644 --- a/drivers/clk/samsung/clk-s5pv210.c +++ b/drivers/clk/samsung/clk-s5pv210.c @@ -782,7 +782,7 @@ static void __init __s5pv210_clk_init(struct device_node *np, samsung_clk_register_alias(ctx, s5pv210_aliases, ARRAY_SIZE(s5pv210_aliases)); - samsung_clk_sleep_init(reg_base, s5pv210_clk_regs, + samsung_clk_sleep_init(reg_base, NULL, s5pv210_clk_regs, ARRAY_SIZE(s5pv210_clk_regs)); samsung_clk_of_add_provider(np, ctx); diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index c149ca6c2217..06ea5deef4ee 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -12,8 +12,10 @@ #include #include #include +#include #include #include +#include #include #include "clk.h" @@ -21,19 +23,29 @@ static LIST_HEAD(clock_reg_cache_list); void samsung_clk_save(void __iomem *base, + struct regmap *regmap, struct samsung_clk_reg_dump *rd, unsigned int num_regs) { - for (; num_regs > 0; --num_regs, ++rd) - rd->value = readl(base + rd->offset); + for (; num_regs > 0; --num_regs, ++rd) { + if (base) + rd->value = readl(base + rd->offset); + else if (regmap) + regmap_read(regmap, rd->offset, &rd->value); + } } void samsung_clk_restore(void __iomem *base, + struct regmap *regmap, const struct samsung_clk_reg_dump *rd, unsigned int num_regs) { - for (; num_regs > 0; --num_regs, ++rd) - writel(rd->value, base + rd->offset); + for (; num_regs > 0; --num_regs, ++rd) { + if (base) + writel(rd->value, base + rd->offset); + else if (regmap) + regmap_write(regmap, rd->offset, rd->value); + } } struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( @@ -227,6 +239,103 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, } } +/* + * Some older DT's have an incorrect CMU resource size which is incompatible + * with the auto clock mode feature. In such cases we switch back to manual + * clock gating mode. + */ +bool samsung_is_auto_capable(struct device_node *np) +{ + struct resource res; + resource_size_t size; + + if (of_address_to_resource(np, 0, &res)) + return false; + + size = resource_size(&res); + if (size != 0x10000) { + pr_warn("%pOF: incorrect res size for automatic clocks\n", np); + return false; + } + return true; +} + +#define ACG_MSK GENMASK(6, 4) +#define CLK_IDLE GENMASK(5, 4) +static int samsung_auto_clk_gate_is_en(struct clk_hw *hw) +{ + u32 reg; + struct clk_gate *gate = to_clk_gate(hw); + + reg = readl(gate->reg); + return ((reg & ACG_MSK) == CLK_IDLE) ? 0 : 1; +} + +/* enable and disable are nops in automatic clock mode */ +static int samsung_auto_clk_gate_en(struct clk_hw *hw) +{ + return 0; +} + +static void samsung_auto_clk_gate_dis(struct clk_hw *hw) +{ +} + +static const struct clk_ops samsung_auto_clk_gate_ops = { + .enable = samsung_auto_clk_gate_en, + .disable = samsung_auto_clk_gate_dis, + .is_enabled = samsung_auto_clk_gate_is_en, +}; + +struct clk_hw *samsung_register_auto_gate(struct device *dev, + struct device_node *np, const char *name, + const char *parent_name, const struct clk_hw *parent_hw, + const struct clk_parent_data *parent_data, + unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, spinlock_t *lock) +{ + struct clk_gate *gate; + struct clk_hw *hw; + struct clk_init_data init = {}; + int ret = -EINVAL; + + /* allocate the gate */ + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &samsung_auto_clk_gate_ops; + init.flags = flags; + init.parent_names = parent_name ? &parent_name : NULL; + init.parent_hws = parent_hw ? &parent_hw : NULL; + init.parent_data = parent_data; + if (parent_name || parent_hw || parent_data) + init.num_parents = 1; + else + init.num_parents = 0; + + /* struct clk_gate assignments */ + gate->reg = reg; + gate->bit_idx = bit_idx; + gate->flags = clk_gate_flags; + gate->lock = lock; + gate->hw.init = &init; + + hw = &gate->hw; + if (dev || !np) + ret = clk_hw_register(dev, hw); + else if (np) + ret = of_clk_hw_register(np, hw); + if (ret) { + kfree(gate); + hw = ERR_PTR(ret); + } + + return hw; +} + /* register a list of gate clocks */ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, const struct samsung_gate_clock *list, @@ -234,14 +343,24 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, { struct clk_hw *clk_hw; unsigned int idx; + void __iomem *reg_offs; for (idx = 0; idx < nr_clk; idx++, list++) { - clk_hw = clk_hw_register_gate(ctx->dev, list->name, list->parent_name, - list->flags, ctx->reg_base + list->offset, + reg_offs = ctx->reg_base + list->offset; + + if (ctx->auto_clock_gate && ctx->gate_dbg_offset) + clk_hw = samsung_register_auto_gate(ctx->dev, NULL, + list->name, list->parent_name, NULL, NULL, + list->flags, reg_offs + ctx->gate_dbg_offset, list->bit_idx, list->gate_flags, &ctx->lock); + else + clk_hw = clk_hw_register_gate(ctx->dev, list->name, + list->parent_name, list->flags, + ctx->reg_base + list->offset, list->bit_idx, + list->gate_flags, &ctx->lock); if (IS_ERR(clk_hw)) { - pr_err("%s: failed to register clock %s\n", __func__, - list->name); + pr_err("%s: failed to register clock %s: %ld\n", __func__, + list->name, PTR_ERR(clk_hw)); continue; } @@ -276,10 +395,11 @@ static int samsung_clk_suspend(void *data) struct samsung_clock_reg_cache *reg_cache; list_for_each_entry(reg_cache, &clock_reg_cache_list, node) { - samsung_clk_save(reg_cache->reg_base, reg_cache->rdump, - reg_cache->rd_num); - samsung_clk_restore(reg_cache->reg_base, reg_cache->rsuspend, - reg_cache->rsuspend_num); + samsung_clk_save(reg_cache->reg_base, reg_cache->sysreg, + reg_cache->rdump, reg_cache->rd_num); + samsung_clk_restore(reg_cache->reg_base, reg_cache->sysreg, + reg_cache->rsuspend, + reg_cache->rsuspend_num); } return 0; } @@ -289,8 +409,8 @@ static void samsung_clk_resume(void *data) struct samsung_clock_reg_cache *reg_cache; list_for_each_entry(reg_cache, &clock_reg_cache_list, node) - samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump, - reg_cache->rd_num); + samsung_clk_restore(reg_cache->reg_base, reg_cache->sysreg, + reg_cache->rdump, reg_cache->rd_num); } static const struct syscore_ops samsung_clk_syscore_ops = { @@ -303,6 +423,7 @@ static struct syscore samsung_clk_syscore = { }; void samsung_clk_extended_sleep_init(void __iomem *reg_base, + struct regmap *sysreg, const unsigned long *rdump, unsigned long nr_rdump, const struct samsung_clk_reg_dump *rsuspend, @@ -323,6 +444,7 @@ void samsung_clk_extended_sleep_init(void __iomem *reg_base, register_syscore(&samsung_clk_syscore); reg_cache->reg_base = reg_base; + reg_cache->sysreg = sysreg; reg_cache->rd_num = nr_rdump; reg_cache->rsuspend = rsuspend; reg_cache->rsuspend_num = nr_rsuspend; @@ -334,10 +456,20 @@ void samsung_clk_extended_sleep_init(void __iomem *reg_base, * samsung_cmu_register_clocks() - Register all clocks provided in CMU object * @ctx: Clock provider object * @cmu: CMU object with clocks to register + * @np: CMU device tree node */ void __init samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, - const struct samsung_cmu_info *cmu) + const struct samsung_cmu_info *cmu, + struct device_node *np) { + if (samsung_is_auto_capable(np) && cmu->auto_clock_gate) + ctx->auto_clock_gate = cmu->auto_clock_gate; + + ctx->gate_dbg_offset = cmu->gate_dbg_offset; + ctx->option_offset = cmu->option_offset; + ctx->drcg_offset = cmu->drcg_offset; + ctx->memclk_offset = cmu->memclk_offset; + if (cmu->pll_clks) samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks); if (cmu->mux_clks) @@ -357,6 +489,37 @@ void __init samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, samsung_clk_register_cpu(ctx, cmu->cpu_clks, cmu->nr_cpu_clks); } +/* Each bit enable/disables DRCG of a bus component */ +#define DRCG_EN_MSK GENMASK(31, 0) +#define MEMCLK_EN BIT(0) + +/* Enable Dynamic Root Clock Gating (DRCG) of bus components */ +void samsung_en_dyn_root_clk_gating(struct device_node *np, + struct samsung_clk_provider *ctx, + const struct samsung_cmu_info *cmu) +{ + if (!ctx->auto_clock_gate) + return; + + ctx->sysreg = syscon_regmap_lookup_by_phandle(np, "samsung,sysreg"); + if (IS_ERR(ctx->sysreg)) { + pr_warn("%pOF: Unable to get CMU sysreg\n", np); + ctx->sysreg = NULL; + } else { + /* Enable DRCG for all bus components */ + regmap_write(ctx->sysreg, ctx->drcg_offset, DRCG_EN_MSK); + /* Enable memclk gate (not present on all sysreg) */ + if (ctx->memclk_offset) + regmap_write_bits(ctx->sysreg, ctx->memclk_offset, + MEMCLK_EN, 0x0); + + samsung_clk_extended_sleep_init(NULL, ctx->sysreg, + cmu->sysreg_clk_regs, + cmu->nr_sysreg_clk_regs, + NULL, 0); + } +} + /* * Common function which registers plls, muxes, dividers and gates * for each CMU. It also add CMU register list to register cache. @@ -375,14 +538,17 @@ struct samsung_clk_provider * __init samsung_cmu_register_one( } ctx = samsung_clk_init(NULL, reg_base, cmu->nr_clk_ids); - samsung_cmu_register_clocks(ctx, cmu); + samsung_cmu_register_clocks(ctx, cmu, np); if (cmu->clk_regs) - samsung_clk_extended_sleep_init(reg_base, + samsung_clk_extended_sleep_init(reg_base, NULL, cmu->clk_regs, cmu->nr_clk_regs, cmu->suspend_regs, cmu->nr_suspend_regs); samsung_clk_of_add_provider(np, ctx); + /* sysreg DT nodes reference a clock in this CMU */ + samsung_en_dyn_root_clk_gating(np, ctx, cmu); + return ctx; } diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 18660c1ac6f0..a56aa3be54d8 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -12,6 +12,7 @@ #include #include +#include #include "clk-pll.h" #include "clk-cpu.h" @@ -19,13 +20,25 @@ * struct samsung_clk_provider - information about clock provider * @reg_base: virtual address for the register base * @dev: clock provider device needed for runtime PM + * @sysreg: syscon regmap for clock-provider sysreg controller * @lock: maintains exclusion between callbacks for a given clock-provider + * @auto_clock_gate: enable auto clk mode for all clocks in clock-provider + * @gate_dbg_offset: gate debug reg offset. Used for all gates in auto clk mode + * @option_offset: option reg offset. Enables auto mode for clock-provider + * @drcg_offset: dynamic root clk gate enable register offset in sysreg + * @memclk_offset: memclk enable register offset in sysreg * @clk_data: holds clock related data like clk_hw* and number of clocks */ struct samsung_clk_provider { void __iomem *reg_base; struct device *dev; + struct regmap *sysreg; spinlock_t lock; + bool auto_clock_gate; + u32 gate_dbg_offset; + u32 option_offset; + u32 drcg_offset; + u32 memclk_offset; /* clk_data must be the last entry due to variable length 'hws' array */ struct clk_hw_onecell_data clk_data; }; @@ -310,6 +323,7 @@ struct samsung_cpu_clock { struct samsung_clock_reg_cache { struct list_head node; void __iomem *reg_base; + struct regmap *sysreg; struct samsung_clk_reg_dump *rdump; unsigned int rd_num; const struct samsung_clk_reg_dump *rsuspend; @@ -338,7 +352,14 @@ struct samsung_clock_reg_cache { * @suspend_regs: list of clock registers to set before suspend * @nr_suspend_regs: count of clock registers in @suspend_regs * @clk_name: name of the parent clock needed for CMU register access + * @sysreg_clk_regs: list of sysreg clock registers + * @nr_sysreg_clk_regs: count of clock registers in @sysreg_clk_regs * @manual_plls: Enable manual control for PLL clocks + * @auto_clock_gate: enable auto clock mode for all components in CMU + * @gate_dbg_offset: gate debug reg offset. Used by all gates in auto clk mode + * @option_offset: option reg offset. Enables auto clk mode for entire CMU + * @drcg_offset: dynamic root clk gate enable register offset in sysreg + * @memclk_offset: memclk enable register offset in sysreg */ struct samsung_cmu_info { const struct samsung_pll_clock *pll_clks; @@ -364,8 +385,16 @@ struct samsung_cmu_info { unsigned int nr_suspend_regs; const char *clk_name; + const unsigned long *sysreg_clk_regs; + unsigned int nr_sysreg_clk_regs; + /* ARM64 Exynos CMUs */ bool manual_plls; + bool auto_clock_gate; + u32 gate_dbg_offset; + u32 option_offset; + u32 drcg_offset; + u32 memclk_offset; }; struct samsung_clk_provider *samsung_clk_init(struct device *dev, @@ -408,35 +437,55 @@ void samsung_clk_register_cpu(struct samsung_clk_provider *ctx, const struct samsung_cpu_clock *list, unsigned int nr_clk); void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, - const struct samsung_cmu_info *cmu); + const struct samsung_cmu_info *cmu, + struct device_node *np); struct samsung_clk_provider *samsung_cmu_register_one( struct device_node *, const struct samsung_cmu_info *); #ifdef CONFIG_PM_SLEEP void samsung_clk_extended_sleep_init(void __iomem *reg_base, + struct regmap *sysreg, const unsigned long *rdump, unsigned long nr_rdump, const struct samsung_clk_reg_dump *rsuspend, unsigned long nr_rsuspend); #else static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base, + struct regmap *sysreg, const unsigned long *rdump, unsigned long nr_rdump, const struct samsung_clk_reg_dump *rsuspend, unsigned long nr_rsuspend) {} #endif -#define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \ - samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0) +#define samsung_clk_sleep_init(reg_base, sysreg, rdump, nr_rdump) \ + samsung_clk_extended_sleep_init(reg_base, sysreg, rdump, nr_rdump, \ + NULL, 0) void samsung_clk_save(void __iomem *base, + struct regmap *regmap, struct samsung_clk_reg_dump *rd, unsigned int num_regs); void samsung_clk_restore(void __iomem *base, + struct regmap *regmap, const struct samsung_clk_reg_dump *rd, unsigned int num_regs); struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( const unsigned long *rdump, unsigned long nr_rdump); +void samsung_en_dyn_root_clk_gating(struct device_node *np, + struct samsung_clk_provider *ctx, + const struct samsung_cmu_info *cmu); + +struct clk_hw *samsung_register_auto_gate(struct device *dev, + struct device_node *np, const char *name, + const char *parent_name, const struct clk_hw *parent_hw, + const struct clk_parent_data *parent_data, + unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, spinlock_t *lock); + +bool samsung_is_auto_capable(struct device_node *np); + #endif /* __SAMSUNG_CLK_H */ From eaf9206bf3d68f792ecd5e6f488eab1fb5afe900 Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Mon, 22 Dec 2025 10:22:15 +0000 Subject: [PATCH 029/165] clk: samsung: gs101: Enable auto_clock_gate mode for each gs101 CMU Enable auto clock mode, and define the additional fields which are used when this mode is enabled. /sys/kernel/debug/clk/clk_summary now reports approximately 308 running clocks and 298 disabled clocks. Prior to this commit 586 clocks were running and 17 disabled. Signed-off-by: Peter Griffin Link: https://patch.msgid.link/20251222-automatic-clocks-v7-4-fec86fa89874@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-gs101.c | 55 +++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/clk/samsung/clk-gs101.c b/drivers/clk/samsung/clk-gs101.c index 70b26db9b95a..8551289b46eb 100644 --- a/drivers/clk/samsung/clk-gs101.c +++ b/drivers/clk/samsung/clk-gs101.c @@ -26,6 +26,10 @@ #define CLKS_NR_PERIC0 (CLK_GOUT_PERIC0_SYSREG_PERIC0_PCLK + 1) #define CLKS_NR_PERIC1 (CLK_GOUT_PERIC1_SYSREG_PERIC1_PCLK + 1) +#define GS101_GATE_DBG_OFFSET 0x4000 +#define GS101_DRCG_EN_OFFSET 0x104 +#define GS101_MEMCLK_OFFSET 0x108 + /* ---- CMU_TOP ------------------------------------------------------------- */ /* Register Offset definitions for CMU_TOP (0x1e080000) */ @@ -1433,6 +1437,9 @@ static const struct samsung_cmu_info top_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_TOP, .clk_regs = cmu_top_clk_regs, .nr_clk_regs = ARRAY_SIZE(cmu_top_clk_regs), + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = CMU_CMU_TOP_CONTROLLER_OPTION, }; static void __init gs101_cmu_top_init(struct device_node *np) @@ -1900,6 +1907,11 @@ static const struct samsung_gate_clock apm_gate_clks[] __initconst = { CLK_CON_GAT_GOUT_BLK_APM_UID_XIU_DP_APM_IPCLKPORT_ACLK, 21, CLK_IS_CRITICAL, 0), }; +static const unsigned long dcrg_memclk_sysreg[] __initconst = { + GS101_DRCG_EN_OFFSET, + GS101_MEMCLK_OFFSET, +}; + static const struct samsung_cmu_info apm_cmu_info __initconst = { .mux_clks = apm_mux_clks, .nr_mux_clks = ARRAY_SIZE(apm_mux_clks), @@ -1912,6 +1924,12 @@ static const struct samsung_cmu_info apm_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_APM, .clk_regs = apm_clk_regs, .nr_clk_regs = ARRAY_SIZE(apm_clk_regs), + .sysreg_clk_regs = dcrg_memclk_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg), + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .drcg_offset = GS101_DRCG_EN_OFFSET, + .memclk_offset = GS101_MEMCLK_OFFSET, }; /* ---- CMU_HSI0 ------------------------------------------------------------ */ @@ -2375,7 +2393,14 @@ static const struct samsung_cmu_info hsi0_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_HSI0, .clk_regs = hsi0_clk_regs, .nr_clk_regs = ARRAY_SIZE(hsi0_clk_regs), + .sysreg_clk_regs = dcrg_memclk_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg), .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = HSI0_CMU_HSI0_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, + .memclk_offset = GS101_MEMCLK_OFFSET, }; /* ---- CMU_HSI2 ------------------------------------------------------------ */ @@ -2863,7 +2888,14 @@ static const struct samsung_cmu_info hsi2_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_HSI2, .clk_regs = cmu_hsi2_clk_regs, .nr_clk_regs = ARRAY_SIZE(cmu_hsi2_clk_regs), + .sysreg_clk_regs = dcrg_memclk_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg), .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = HSI2_CMU_HSI2_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, + .memclk_offset = GS101_MEMCLK_OFFSET, }; /* ---- CMU_MISC ------------------------------------------------------------ */ @@ -3423,7 +3455,14 @@ static const struct samsung_cmu_info misc_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_MISC, .clk_regs = misc_clk_regs, .nr_clk_regs = ARRAY_SIZE(misc_clk_regs), + .sysreg_clk_regs = dcrg_memclk_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg), .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = MISC_CMU_MISC_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, + .memclk_offset = GS101_MEMCLK_OFFSET, }; static void __init gs101_cmu_misc_init(struct device_node *np) @@ -4010,6 +4049,10 @@ static const struct samsung_gate_clock peric0_gate_clks[] __initconst = { 21, 0, 0), }; +static const unsigned long dcrg_sysreg[] __initconst = { + GS101_DRCG_EN_OFFSET, +}; + static const struct samsung_cmu_info peric0_cmu_info __initconst = { .mux_clks = peric0_mux_clks, .nr_mux_clks = ARRAY_SIZE(peric0_mux_clks), @@ -4020,7 +4063,13 @@ static const struct samsung_cmu_info peric0_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_PERIC0, .clk_regs = peric0_clk_regs, .nr_clk_regs = ARRAY_SIZE(peric0_clk_regs), + .sysreg_clk_regs = dcrg_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_sysreg), .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = PERIC0_CMU_PERIC0_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, }; /* ---- CMU_PERIC1 ---------------------------------------------------------- */ @@ -4368,7 +4417,13 @@ static const struct samsung_cmu_info peric1_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_PERIC1, .clk_regs = peric1_clk_regs, .nr_clk_regs = ARRAY_SIZE(peric1_clk_regs), + .sysreg_clk_regs = dcrg_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_sysreg), .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = PERIC1_CMU_PERIC1_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, }; /* ---- platform_driver ----------------------------------------------------- */ From 5ec8cbbc54c82c0bdae4dbf0e5aecf9817bde2b9 Mon Sep 17 00:00:00 2001 From: Inochi Amaoto Date: Fri, 19 Dec 2025 09:28:17 +0800 Subject: [PATCH 030/165] clk: spacemit: Respect Kconfig setting when building modules Currently, the SPACEMIT_CCU entry is only a switch for enabling entry SPACEMIT_K1_CCU. It does not guide the build for common clock codes even if it is a tristate entry. This makes this entry useless. Change the Makefile to add a separate build for common clock logic, so the SPACEMIT_CCU entry takes effect, also add necessary MODULE_LICENSE()/MODULE_DESCRIPTION()/EXPORT_SYMBOL() for the module build. Fixes: 1b72c59db0ad ("clk: spacemit: Add clock support for SpacemiT K1 SoC") Signed-off-by: Inochi Amaoto Reviewed-by: Yixun Lan Link: https://lore.kernel.org/r/20251219012819.440972-2-inochiama@gmail.com Signed-off-by: Yixun Lan --- drivers/clk/spacemit/Makefile | 9 +++++++-- drivers/clk/spacemit/ccu-k1.c | 1 + drivers/clk/spacemit/ccu_common.c | 6 ++++++ drivers/clk/spacemit/ccu_ddn.c | 1 + drivers/clk/spacemit/ccu_mix.c | 9 +++++++++ drivers/clk/spacemit/ccu_pll.c | 1 + 6 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 drivers/clk/spacemit/ccu_common.c diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile index 5ec6da61db98..ad2bf315109b 100644 --- a/drivers/clk/spacemit/Makefile +++ b/drivers/clk/spacemit/Makefile @@ -1,5 +1,10 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_SPACEMIT_K1_CCU) = spacemit-ccu-k1.o -spacemit-ccu-k1-y = ccu_pll.o ccu_mix.o ccu_ddn.o +obj-$(CONFIG_SPACEMIT_CCU) += spacemit-ccu.o +spacemit-ccu-y += ccu_common.o +spacemit-ccu-y += ccu_pll.o +spacemit-ccu-y += ccu_mix.o +spacemit-ccu-y += ccu_ddn.o + +obj-$(CONFIG_SPACEMIT_K1_CCU) += spacemit-ccu-k1.o spacemit-ccu-k1-y += ccu-k1.o diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c index 4761bc1e3b6e..01d9485b615d 100644 --- a/drivers/clk/spacemit/ccu-k1.c +++ b/drivers/clk/spacemit/ccu-k1.c @@ -1204,6 +1204,7 @@ static struct platform_driver k1_ccu_driver = { }; module_platform_driver(k1_ccu_driver); +MODULE_IMPORT_NS("CLK_SPACEMIT"); MODULE_DESCRIPTION("SpacemiT K1 CCU driver"); MODULE_AUTHOR("Haylen Chu "); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/spacemit/ccu_common.c b/drivers/clk/spacemit/ccu_common.c new file mode 100644 index 000000000000..4412c4104dab --- /dev/null +++ b/drivers/clk/spacemit/ccu_common.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +MODULE_DESCRIPTION("SpacemiT CCU common clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/spacemit/ccu_ddn.c b/drivers/clk/spacemit/ccu_ddn.c index 5b16e273bee5..b5540e0781ff 100644 --- a/drivers/clk/spacemit/ccu_ddn.c +++ b/drivers/clk/spacemit/ccu_ddn.c @@ -84,3 +84,4 @@ const struct clk_ops spacemit_ccu_ddn_ops = { .determine_rate = ccu_ddn_determine_rate, .set_rate = ccu_ddn_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_ddn_ops, "CLK_SPACEMIT"); diff --git a/drivers/clk/spacemit/ccu_mix.c b/drivers/clk/spacemit/ccu_mix.c index 7b7990875372..67f8b12b4f5b 100644 --- a/drivers/clk/spacemit/ccu_mix.c +++ b/drivers/clk/spacemit/ccu_mix.c @@ -198,24 +198,28 @@ const struct clk_ops spacemit_ccu_gate_ops = { .enable = ccu_gate_enable, .is_enabled = ccu_gate_is_enabled, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_gate_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_factor_ops = { .determine_rate = ccu_factor_determine_rate, .recalc_rate = ccu_factor_recalc_rate, .set_rate = ccu_factor_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_factor_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_mux_ops = { .determine_rate = ccu_mix_determine_rate, .get_parent = ccu_mux_get_parent, .set_parent = ccu_mux_set_parent, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_mux_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_div_ops = { .determine_rate = ccu_mix_determine_rate, .recalc_rate = ccu_div_recalc_rate, .set_rate = ccu_mix_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_div_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_factor_gate_ops = { .disable = ccu_gate_disable, @@ -226,6 +230,7 @@ const struct clk_ops spacemit_ccu_factor_gate_ops = { .recalc_rate = ccu_factor_recalc_rate, .set_rate = ccu_factor_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_factor_gate_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_mux_gate_ops = { .disable = ccu_gate_disable, @@ -236,6 +241,7 @@ const struct clk_ops spacemit_ccu_mux_gate_ops = { .get_parent = ccu_mux_get_parent, .set_parent = ccu_mux_set_parent, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_mux_gate_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_div_gate_ops = { .disable = ccu_gate_disable, @@ -246,6 +252,7 @@ const struct clk_ops spacemit_ccu_div_gate_ops = { .recalc_rate = ccu_div_recalc_rate, .set_rate = ccu_mix_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_div_gate_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_mux_div_gate_ops = { .disable = ccu_gate_disable, @@ -259,6 +266,7 @@ const struct clk_ops spacemit_ccu_mux_div_gate_ops = { .recalc_rate = ccu_div_recalc_rate, .set_rate = ccu_mix_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_mux_div_gate_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_mux_div_ops = { .get_parent = ccu_mux_get_parent, @@ -268,3 +276,4 @@ const struct clk_ops spacemit_ccu_mux_div_ops = { .recalc_rate = ccu_div_recalc_rate, .set_rate = ccu_mix_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_mux_div_ops, "CLK_SPACEMIT"); diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c index d92f0dae65a4..76d0244873d8 100644 --- a/drivers/clk/spacemit/ccu_pll.c +++ b/drivers/clk/spacemit/ccu_pll.c @@ -157,3 +157,4 @@ const struct clk_ops spacemit_ccu_pll_ops = { .determine_rate = ccu_pll_determine_rate, .is_enabled = ccu_pll_is_enabled, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_pll_ops, "CLK_SPACEMIT"); From 99735a742f7e9a3e7f4cb6c58edf1b38101e7657 Mon Sep 17 00:00:00 2001 From: Inochi Amaoto Date: Fri, 19 Dec 2025 09:28:18 +0800 Subject: [PATCH 031/165] clk: spacemit: Hide common clock driver from user controller Since the common clock driver is only a dependency for other spacemit clock driver, it should not be enabled individually, so hide this in the Kconfig UI and let other spacemit clock driver select it. Signed-off-by: Inochi Amaoto Reviewed-by: Yixun Lan Link: https://lore.kernel.org/r/20251219012819.440972-3-inochiama@gmail.com Signed-off-by: Yixun Lan --- drivers/clk/spacemit/Kconfig | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig index 3854f6ae6d0e..3351e8bc801d 100644 --- a/drivers/clk/spacemit/Kconfig +++ b/drivers/clk/spacemit/Kconfig @@ -1,19 +1,17 @@ # SPDX-License-Identifier: GPL-2.0-only -config SPACEMIT_CCU - tristate "Clock support for SpacemiT SoCs" +menu "Clock support for SpacemiT platforms" depends on ARCH_SPACEMIT || COMPILE_TEST + +config SPACEMIT_CCU + tristate select AUXILIARY_BUS select MFD_SYSCON - help - Say Y to enable clock controller unit support for SpacemiT SoCs. - -if SPACEMIT_CCU config SPACEMIT_K1_CCU tristate "Support for SpacemiT K1 SoC" - depends on ARCH_SPACEMIT || COMPILE_TEST + select SPACEMIT_CCU help Support for clock controller unit in SpacemiT K1 SoC. -endif +endmenu From 1f76689d171512e1fd99999faa76040e48420b7b Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 3 Dec 2025 09:41:46 +0000 Subject: [PATCH 032/165] clk: renesas: r9a09g056: Add entries for RSCIs Add clock and reset entries for the RSCI IPs. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251203094147.6429-2-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g056-cpg.c | 126 ++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index 4b068199edde..741df446e24e 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -46,6 +46,9 @@ enum clk_ids { CLK_PLLCLN_DIV2, CLK_PLLCLN_DIV8, CLK_PLLCLN_DIV16, + CLK_PLLCLN_DIV64, + CLK_PLLCLN_DIV256, + CLK_PLLCLN_DIV1024, CLK_PLLDTY_ACPU, CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU_DIV4, @@ -180,6 +183,9 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_FIXED(".pllcln_div2", CLK_PLLCLN_DIV2, CLK_PLLCLN, 1, 2), DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8), DEF_FIXED(".pllcln_div16", CLK_PLLCLN_DIV16, CLK_PLLCLN, 1, 16), + DEF_FIXED(".pllcln_div64", CLK_PLLCLN_DIV64, CLK_PLLCLN, 1, 64), + DEF_FIXED(".pllcln_div256", CLK_PLLCLN_DIV256, CLK_PLLCLN, 1, 256), + DEF_FIXED(".pllcln_div1024", CLK_PLLCLN_DIV1024, CLK_PLLCLN, 1, 1024), DEF_DDIV(".plldty_acpu", CLK_PLLDTY_ACPU, CLK_PLLDTY, CDDIV0_DIVCTL2, dtable_2_64), DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2), @@ -281,6 +287,106 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(5, BIT(13))), DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18, BUS_MSTOP(5, BIT(13))), + DEF_MOD("rsci0_pclk", CLK_PLLCLN_DIV16, 5, 13, 2, 29, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_tclk", CLK_PLLCLN_DIV16, 5, 14, 2, 30, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps3_n", CLK_PLLCLN_DIV1024, 5, 15, 2, 31, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 0, 3, 0, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 1, 3, 1, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci1_pclk", CLK_PLLCLN_DIV16, 6, 2, 3, 2, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_tclk", CLK_PLLCLN_DIV16, 6, 3, 3, 3, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 4, 3, 4, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 5, 3, 5, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 6, 3, 6, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci2_pclk", CLK_PLLCLN_DIV16, 6, 7, 3, 7, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_tclk", CLK_PLLCLN_DIV16, 6, 8, 3, 8, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 9, 3, 9, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 10, 3, 10, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 11, 3, 11, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci3_pclk", CLK_PLLCLN_DIV16, 6, 12, 3, 12, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_tclk", CLK_PLLCLN_DIV16, 6, 13, 3, 13, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 14, 3, 14, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 15, 3, 15, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 0, 3, 16, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci4_pclk", CLK_PLLCLN_DIV16, 7, 1, 3, 17, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_tclk", CLK_PLLCLN_DIV16, 7, 2, 3, 18, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 3, 3, 19, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 4, 3, 20, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 5, 3, 21, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci5_pclk", CLK_PLLCLN_DIV16, 7, 6, 3, 22, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_tclk", CLK_PLLCLN_DIV16, 7, 7, 3, 23, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 8, 3, 24, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 9, 3, 25, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 10, 3, 26, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci6_pclk", CLK_PLLCLN_DIV16, 7, 11, 3, 27, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_tclk", CLK_PLLCLN_DIV16, 7, 12, 3, 28, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 13, 3, 29, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 14, 3, 30, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 15, 3, 31, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci7_pclk", CLK_PLLCLN_DIV16, 8, 0, 4, 0, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_tclk", CLK_PLLCLN_DIV16, 8, 1, 4, 1, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 2, 4, 2, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 3, 4, 3, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 4, 4, 4, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci8_pclk", CLK_PLLCLN_DIV16, 8, 5, 4, 5, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_tclk", CLK_PLLCLN_DIV16, 8, 6, 4, 6, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 7, 4, 7, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 8, 4, 8, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 9, 4, 9, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci9_pclk", CLK_PLLCLN_DIV16, 8, 10, 4, 10, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_tclk", CLK_PLLCLN_DIV16, 8, 11, 4, 11, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 12, 4, 12, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 13, 4, 13, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 14, 4, 14, + BUS_MSTOP(11, BIT(12))), DEF_MOD("rspi_0_pclk", CLK_PLLCLN_DIV8, 5, 4, 2, 20, BUS_MSTOP(11, BIT(0))), DEF_MOD("rspi_0_pclk_sfr", CLK_PLLCLN_DIV8, 5, 5, 2, 21, @@ -455,6 +561,26 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */ DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */ DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */ + DEF_RST(8, 1, 3, 18), /* RSCI0_PRESETN */ + DEF_RST(8, 2, 3, 19), /* RSCI0_TRESETN */ + DEF_RST(8, 3, 3, 20), /* RSCI1_PRESETN */ + DEF_RST(8, 4, 3, 21), /* RSCI1_TRESETN */ + DEF_RST(8, 5, 3, 22), /* RSCI2_PRESETN */ + DEF_RST(8, 6, 3, 23), /* RSCI2_TRESETN */ + DEF_RST(8, 7, 3, 24), /* RSCI3_PRESETN */ + DEF_RST(8, 8, 3, 25), /* RSCI3_TRESETN */ + DEF_RST(8, 9, 3, 26), /* RSCI4_PRESETN */ + DEF_RST(8, 10, 3, 27), /* RSCI4_TRESETN */ + DEF_RST(8, 11, 3, 28), /* RSCI5_PRESETN */ + DEF_RST(8, 12, 3, 29), /* RSCI5_TRESETN */ + DEF_RST(8, 13, 3, 30), /* RSCI6_PRESETN */ + DEF_RST(8, 14, 3, 31), /* RSCI6_TRESETN */ + DEF_RST(8, 15, 4, 0), /* RSCI7_PRESETN */ + DEF_RST(9, 0, 4, 1), /* RSCI7_TRESETN */ + DEF_RST(9, 1, 4, 2), /* RSCI8_PRESETN */ + DEF_RST(9, 2, 4, 3), /* RSCI8_TRESETN */ + DEF_RST(9, 3, 4, 4), /* RSCI9_PRESETN */ + DEF_RST(9, 4, 4, 5), /* RSCI9_TRESETN */ DEF_RST(7, 11, 3, 12), /* RSPI_0_PRESETN */ DEF_RST(7, 12, 3, 13), /* RSPI_0_TRESETN */ DEF_RST(7, 13, 3, 14), /* RSPI_1_PRESETN */ From 2efea3b35cc916f04f06b89f2e2557dbd9c48109 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 3 Dec 2025 09:41:47 +0000 Subject: [PATCH 033/165] clk: renesas: r9a09g057: Add entries for RSCIs Add clock and reset entries for the RSCI IPs. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251203094147.6429-3-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g057-cpg.c | 126 ++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c index 400d9e94f2e9..991f9a2ec12e 100644 --- a/drivers/clk/renesas/r9a09g057-cpg.c +++ b/drivers/clk/renesas/r9a09g057-cpg.c @@ -46,6 +46,9 @@ enum clk_ids { CLK_PLLCLN_DIV2, CLK_PLLCLN_DIV8, CLK_PLLCLN_DIV16, + CLK_PLLCLN_DIV64, + CLK_PLLCLN_DIV256, + CLK_PLLCLN_DIV1024, CLK_PLLDTY_ACPU, CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU_DIV4, @@ -182,6 +185,9 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { DEF_FIXED(".pllcln_div2", CLK_PLLCLN_DIV2, CLK_PLLCLN, 1, 2), DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8), DEF_FIXED(".pllcln_div16", CLK_PLLCLN_DIV16, CLK_PLLCLN, 1, 16), + DEF_FIXED(".pllcln_div64", CLK_PLLCLN_DIV64, CLK_PLLCLN, 1, 64), + DEF_FIXED(".pllcln_div256", CLK_PLLCLN_DIV256, CLK_PLLCLN, 1, 256), + DEF_FIXED(".pllcln_div1024", CLK_PLLCLN_DIV1024, CLK_PLLCLN, 1, 1024), DEF_DDIV(".plldty_acpu", CLK_PLLDTY_ACPU, CLK_PLLDTY, CDDIV0_DIVCTL2, dtable_2_64), DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2), @@ -288,6 +294,106 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(5, BIT(13))), DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18, BUS_MSTOP(5, BIT(13))), + DEF_MOD("rsci0_pclk", CLK_PLLCLN_DIV16, 5, 13, 2, 29, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_tclk", CLK_PLLCLN_DIV16, 5, 14, 2, 30, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps3_n", CLK_PLLCLN_DIV1024, 5, 15, 2, 31, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 0, 3, 0, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 1, 3, 1, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci1_pclk", CLK_PLLCLN_DIV16, 6, 2, 3, 2, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_tclk", CLK_PLLCLN_DIV16, 6, 3, 3, 3, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 4, 3, 4, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 5, 3, 5, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 6, 3, 6, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci2_pclk", CLK_PLLCLN_DIV16, 6, 7, 3, 7, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_tclk", CLK_PLLCLN_DIV16, 6, 8, 3, 8, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 9, 3, 9, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 10, 3, 10, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 11, 3, 11, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci3_pclk", CLK_PLLCLN_DIV16, 6, 12, 3, 12, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_tclk", CLK_PLLCLN_DIV16, 6, 13, 3, 13, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 14, 3, 14, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 15, 3, 15, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 0, 3, 16, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci4_pclk", CLK_PLLCLN_DIV16, 7, 1, 3, 17, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_tclk", CLK_PLLCLN_DIV16, 7, 2, 3, 18, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 3, 3, 19, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 4, 3, 20, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 5, 3, 21, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci5_pclk", CLK_PLLCLN_DIV16, 7, 6, 3, 22, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_tclk", CLK_PLLCLN_DIV16, 7, 7, 3, 23, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 8, 3, 24, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 9, 3, 25, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 10, 3, 26, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci6_pclk", CLK_PLLCLN_DIV16, 7, 11, 3, 27, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_tclk", CLK_PLLCLN_DIV16, 7, 12, 3, 28, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 13, 3, 29, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 14, 3, 30, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 15, 3, 31, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci7_pclk", CLK_PLLCLN_DIV16, 8, 0, 4, 0, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_tclk", CLK_PLLCLN_DIV16, 8, 1, 4, 1, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 2, 4, 2, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 3, 4, 3, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 4, 4, 4, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci8_pclk", CLK_PLLCLN_DIV16, 8, 5, 4, 5, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_tclk", CLK_PLLCLN_DIV16, 8, 6, 4, 6, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 7, 4, 7, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 8, 4, 8, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 9, 4, 9, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci9_pclk", CLK_PLLCLN_DIV16, 8, 10, 4, 10, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_tclk", CLK_PLLCLN_DIV16, 8, 11, 4, 11, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 12, 4, 12, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 13, 4, 13, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 14, 4, 14, + BUS_MSTOP(11, BIT(12))), DEF_MOD("rtc_0_clk_rtc", CLK_PLLCM33_DIV16, 5, 3, 2, 19, BUS_MSTOP(3, BIT(11) | BIT(12))), DEF_MOD("rspi_0_pclk", CLK_PLLCLN_DIV8, 5, 4, 2, 20, @@ -488,6 +594,26 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */ DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */ DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */ + DEF_RST(8, 1, 3, 18), /* RSCI0_PRESETN */ + DEF_RST(8, 2, 3, 19), /* RSCI0_TRESETN */ + DEF_RST(8, 3, 3, 20), /* RSCI1_PRESETN */ + DEF_RST(8, 4, 3, 21), /* RSCI1_TRESETN */ + DEF_RST(8, 5, 3, 22), /* RSCI2_PRESETN */ + DEF_RST(8, 6, 3, 23), /* RSCI2_TRESETN */ + DEF_RST(8, 7, 3, 24), /* RSCI3_PRESETN */ + DEF_RST(8, 8, 3, 25), /* RSCI3_TRESETN */ + DEF_RST(8, 9, 3, 26), /* RSCI4_PRESETN */ + DEF_RST(8, 10, 3, 27), /* RSCI4_TRESETN */ + DEF_RST(8, 11, 3, 28), /* RSCI5_PRESETN */ + DEF_RST(8, 12, 3, 29), /* RSCI5_TRESETN */ + DEF_RST(8, 13, 3, 30), /* RSCI6_PRESETN */ + DEF_RST(8, 14, 3, 31), /* RSCI6_TRESETN */ + DEF_RST(8, 15, 4, 0), /* RSCI7_PRESETN */ + DEF_RST(9, 0, 4, 1), /* RSCI7_TRESETN */ + DEF_RST(9, 1, 4, 2), /* RSCI8_PRESETN */ + DEF_RST(9, 2, 4, 3), /* RSCI8_TRESETN */ + DEF_RST(9, 3, 4, 4), /* RSCI9_PRESETN */ + DEF_RST(9, 4, 4, 5), /* RSCI9_TRESETN */ DEF_RST(7, 9, 3, 10), /* RTC_0_RST_RTC */ DEF_RST(7, 10, 3, 11), /* RTC_0_RST_RTC_V */ DEF_RST(7, 11, 3, 12), /* RSPI_0_PRESETN */ From ab5c13d98848d7f61680559f9eae659fbd32b029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20Cz=C3=A9m=C3=A1n?= Date: Mon, 17 Nov 2025 18:17:53 +0100 Subject: [PATCH 034/165] clk: qcom: gcc-msm8917: Add missing MDSS reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing MDSS reset can be found on MSM8917 and MSM8937. Reviewed-by: Taniya Das Signed-off-by: Barnabás Czémán Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251117-mdss-resets-msm8917-msm8937-v2-2-a7e9bbdaac96@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-msm8917.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/gcc-msm8917.c b/drivers/clk/qcom/gcc-msm8917.c index 0a1aa623cd49..248fa0fd86f5 100644 --- a/drivers/clk/qcom/gcc-msm8917.c +++ b/drivers/clk/qcom/gcc-msm8917.c @@ -3770,6 +3770,7 @@ static const struct qcom_reset_map gcc_msm8917_resets[] = { [GCC_QUSB2_PHY_BCR] = { 0x4103c }, [GCC_USB_HS_BCR] = { 0x41000 }, [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, + [GCC_MDSS_BCR] = { 0x4d074 }, }; static const struct regmap_config gcc_msm8917_regmap_config = { From ebb3acf4d7c95b52265084168b59a565bf972883 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Tue, 9 Dec 2025 09:11:14 +0000 Subject: [PATCH 035/165] clk: renesas: r9a09g056: Add clock and reset entries for TSU Add module clock and reset entries for the TSU0 and TSU1 blocks on the Renesas RZ/V2N (R9A09G056) SoC. Signed-off-by: Ovidiu Panait Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251209091115.8541-3-ovidiu.panait.rb@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g056-cpg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index 741df446e24e..d831246ff55d 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -537,6 +537,10 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(3, BIT(4))), DEF_MOD("gpu_0_ace_clk", CLK_PLLDTY_ACPU_DIV2, 15, 2, 7, 18, BUS_MSTOP(3, BIT(4))), + DEF_MOD("tsu_0_pclk", CLK_QEXTAL, 16, 9, 8, 9, + BUS_MSTOP(5, BIT(2))), + DEF_MOD("tsu_1_pclk", CLK_QEXTAL, 16, 10, 8, 10, + BUS_MSTOP(2, BIT(15))), }; static const struct rzv2h_reset r9a09g056_resets[] __initconst = { @@ -626,6 +630,8 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(13, 13, 6, 14), /* GPU_0_RESETN */ DEF_RST(13, 14, 6, 15), /* GPU_0_AXI_RESETN */ DEF_RST(13, 15, 6, 16), /* GPU_0_ACE_RESETN */ + DEF_RST(15, 7, 7, 8), /* TSU_0_PRESETN */ + DEF_RST(15, 8, 7, 9), /* TSU_1_PRESETN */ }; const struct rzv2h_cpg_info r9a09g056_cpg_info __initconst = { From e77ff7d32b2029851a3567f1ccf7ab9db5cfa137 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 24 Dec 2025 12:22:58 +0100 Subject: [PATCH 036/165] clk: qcom: gcc-kaanapali: Fix double array initializer [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] element in clk_regmap array is already initialized, as reported by W=1 clang warning: gcc-kaanapali.c:3383:36: error: initializer overrides prior initialization of this subobject [-Werror,-Winitializer-overrides] Fixes: d1919c375f21 ("clk: qcom: Add support for Global clock controller on Kaanapali") Signed-off-by: Krzysztof Kozlowski Reviewed-by: Abel Vesa Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251224112257.83874-3-krzysztof.kozlowski@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-kaanapali.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/qcom/gcc-kaanapali.c b/drivers/clk/qcom/gcc-kaanapali.c index 182b152df14c..b9743284927d 100644 --- a/drivers/clk/qcom/gcc-kaanapali.c +++ b/drivers/clk/qcom/gcc-kaanapali.c @@ -3380,7 +3380,6 @@ static struct clk_regmap *gcc_kaanapali_clocks[] = { [GCC_QMIP_VIDEO_CV_CPU_AHB_CLK] = &gcc_qmip_video_cv_cpu_ahb_clk.clkr, [GCC_QMIP_VIDEO_CVP_AHB_CLK] = &gcc_qmip_video_cvp_ahb_clk.clkr, [GCC_QMIP_VIDEO_V_CPU_AHB_CLK] = &gcc_qmip_video_v_cpu_ahb_clk.clkr, - [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, }; static struct gdsc *gcc_kaanapali_gdscs[] = { From bb466f234f2cfeea1c65b2d777ed878ee783b3ba Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 24 Dec 2025 12:22:59 +0100 Subject: [PATCH 037/165] clk: qcom: rpmh: Fix double array initializer on Kaanapali [RPMH_RF_CLK4] and [RPMH_RF_CLK5_A] elements in clk_hw array are already initialized, as reported by W=1 clang warning: clk-rpmh.c:932:20: error: initializer overrides prior initialization of this subobject [-Werror,-Winitializer-overrides] clk-rpmh.c:934:21: error: initializer overrides prior initialization of this subobject [-Werror,-Winitializer-overrides] Fixes: acabfd13859d ("clk: qcom: rpmh: Add support for Kaanapali rpmh clocks") Signed-off-by: Krzysztof Kozlowski Reviewed-by: Abel Vesa Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251224112257.83874-4-krzysztof.kozlowski@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rpmh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 10e84ada48ee..547729b1a8ee 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -929,8 +929,8 @@ static struct clk_hw *kaanapali_rpmh_clocks[] = { [RPMH_RF_CLK3] = &clk_rpmh_clk3_a2_e0.hw, [RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a2_e0_ao.hw, [RPMH_RF_CLK4] = &clk_rpmh_clk4_a2_e0.hw, - [RPMH_RF_CLK4] = &clk_rpmh_clk4_a2_e0_ao.hw, - [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a2_e0.hw, + [RPMH_RF_CLK4_A] = &clk_rpmh_clk4_a2_e0_ao.hw, + [RPMH_RF_CLK5] = &clk_rpmh_clk5_a2_e0.hw, [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a2_e0_ao.hw, [RPMH_IPA_CLK] = &clk_rpmh_ipa.hw, }; From bf94404bc7bf9904bfa9334d3115e95b764db12b Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sat, 3 Jan 2026 11:27:06 +0530 Subject: [PATCH 038/165] clk: qcom: gcc-x1e80100: Add missing UFS symbol mux clocks The UFS symbol RX/TX mux clocks were not defined previously. Add these mux clocks so that clock rate propagation reaches the muxes correctly. Fixes: 161b7c401f4b ("clk: qcom: Add Global Clock controller (GCC) driver for X1E80100") Reviewed-by: Abel Vesa Signed-off-by: Taniya Das Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20260103-ufs_symbol_clk-v2-2-51828cc76236@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-x1e80100.c | 72 +++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index b63c8abdd2fc..ae9621aff858 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -59,6 +59,9 @@ enum { DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + DT_UFS_PHY_RX_SYMBOL_0_CLK, + DT_UFS_PHY_RX_SYMBOL_1_CLK, + DT_UFS_PHY_TX_SYMBOL_0_CLK, }; enum { @@ -103,6 +106,9 @@ enum { P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, P_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + P_UFS_PHY_RX_SYMBOL_0_CLK, + P_UFS_PHY_RX_SYMBOL_1_CLK, + P_UFS_PHY_TX_SYMBOL_0_CLK, }; static struct clk_alpha_pll gcc_gpll0 = { @@ -482,6 +488,48 @@ static const struct clk_parent_data gcc_parent_data_33[] = { { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, }; +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_0_clk_src = { + .reg = 0x77064, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk_src", + .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_phy_mux gcc_ufs_phy_rx_symbol_1_clk_src = { + .reg = 0x770e0, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk_src", + .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_phy_mux gcc_ufs_phy_tx_symbol_0_clk_src = { + .reg = 0x77054, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_UFS_PHY_TX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + static struct clk_regmap_phy_mux gcc_usb4_0_phy_dp0_clk_src = { .reg = 0x9f06c, .clkr = { @@ -5148,12 +5196,17 @@ static struct clk_branch gcc_ufs_phy_phy_aux_clk = { static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { .halt_reg = 0x7702c, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x7702c, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_rx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5161,12 +5214,17 @@ static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { .halt_reg = 0x770cc, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x770cc, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_rx_symbol_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5174,12 +5232,17 @@ static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { .halt_reg = 0x77028, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x77028, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_tx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_tx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -7180,6 +7243,9 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_USB4_2_TMU_CLK_SRC] = &gcc_usb4_2_tmu_clk_src.clkr, [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_rx_symbol_0_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC] = &gcc_ufs_phy_rx_symbol_1_clk_src.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_tx_symbol_0_clk_src.clkr, }; static struct gdsc *gcc_x1e80100_gdscs[] = { From 77d0ea71b30bcb9f06d36a804542851081d4da3c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 8 Dec 2025 03:06:22 +0100 Subject: [PATCH 039/165] clk: qcom: videocc-sm8750: Constify qcom_cc_desc Static 'struct qcom_cc_desc' is not modified by drivers and can be made const for code safety. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Taniya Das Reviewed-by: Imran Shaik Link: https://lore.kernel.org/r/20251208020621.4514-2-krzysztof.kozlowski@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/videocc-sm8750.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/videocc-sm8750.c b/drivers/clk/qcom/videocc-sm8750.c index 0acf3104d702..823aca2bdd34 100644 --- a/drivers/clk/qcom/videocc-sm8750.c +++ b/drivers/clk/qcom/videocc-sm8750.c @@ -416,7 +416,7 @@ static struct qcom_cc_driver_data video_cc_sm8750_driver_data = { .clk_regs_configure = clk_sm8750_regs_configure, }; -static struct qcom_cc_desc video_cc_sm8750_desc = { +static const struct qcom_cc_desc video_cc_sm8750_desc = { .config = &video_cc_sm8750_regmap_config, .clks = video_cc_sm8750_clocks, .num_clks = ARRAY_SIZE(video_cc_sm8750_clocks), From 1c06e3956054fb5a0930f07b02726b1774b6c700 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Mon, 24 Nov 2025 23:20:11 +0200 Subject: [PATCH 040/165] clk: qcom: gcc-sm8550: Use floor ops for SDCC RCGs In line with commit a27ac3806b0a ("clk: qcom: gcc-sm8450: Use floor ops for SDCC RCGs") done to fix issues with overclocked SD cards on SM8450 powered boards set floor clock operations for SDCC RCGs on SM8550. This change fixes initialization of some SD cards, where the problem is manifested by the SDHC driver: mmc0: Card appears overclocked; req 50000000 Hz, actual 100000000 Hz mmc0: error -110 whilst initialising SD card Fixes: 955f2ea3b9e9 ("clk: qcom: Add GCC driver for SM8550") Signed-off-by: Vladimir Zapolskiy Reviewed-by: Neil Armstrong Reviewed-by: Taniya Das Link: https://lore.kernel.org/r/20251124212012.3660189-2-vladimir.zapolskiy@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sm8550.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c index 862a9bf73bcb..36a5b7de5b55 100644 --- a/drivers/clk/qcom/gcc-sm8550.c +++ b/drivers/clk/qcom/gcc-sm8550.c @@ -1025,7 +1025,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_9, .num_parents = ARRAY_SIZE(gcc_parent_data_9), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1048,7 +1048,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; From 8c4415fd17cd5979c31a4bf303acc702e9726033 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Mon, 24 Nov 2025 23:20:12 +0200 Subject: [PATCH 041/165] clk: qcom: gcc-sm8650: Use floor ops for SDCC RCGs In line with commit a27ac3806b0a ("clk: qcom: gcc-sm8450: Use floor ops for SDCC RCGs") done to fix issues with overclocked SD cards on SM8450 powered boards set floor clock operations for SDCC RCGs on SM8650. This change fixes initialization of some SD cards, where the problem is manifested by the SDHC driver: mmc0: Card appears overclocked; req 50000000 Hz, actual 100000000 Hz mmc0: error -110 whilst initialising SD card Fixes: c58225b7e3d7 ("clk: qcom: add the SM8650 Global Clock Controller driver, part 1") Signed-off-by: Vladimir Zapolskiy Reviewed-by: Neil Armstrong Reviewed-by: Taniya Das Link: https://lore.kernel.org/r/20251124212012.3660189-3-vladimir.zapolskiy@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sm8650.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-sm8650.c b/drivers/clk/qcom/gcc-sm8650.c index 24f98062b9dd..2dd6444ce036 100644 --- a/drivers/clk/qcom/gcc-sm8650.c +++ b/drivers/clk/qcom/gcc-sm8650.c @@ -1257,7 +1257,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_11, .num_parents = ARRAY_SIZE(gcc_parent_data_11), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1279,7 +1279,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; From d6205a1878dd4cc9664c4b4829b68a29c0426efc Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Mon, 5 Jan 2026 16:09:50 +0530 Subject: [PATCH 042/165] clk: qcom: rcg2: compute 2d using duty fraction directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The duty-cycle calculation in clk_rcg2_set_duty_cycle() currently derives an intermediate percentage `duty_per = (num * 100) / den` and then computes: d = DIV_ROUND_CLOSEST(n * duty_per * 2, 100); This introduces integer truncation at the percentage step (division by `den`) and a redundant scaling by 100, which can reduce precision for large `den` and skew the final rounding. Compute `2d` directly from the duty fraction to preserve precision and avoid the unnecessary scaling: d = DIV_ROUND_CLOSEST(n * duty->num * 2, duty->den); This keeps the intended formula `d ≈ n * 2 * (num/den)` while performing a single, final rounded division, improving accuracy especially for small duty cycles or large denominators. It also removes the unused `duty_per` variable, simplifying the code. There is no functional changes beyond improved numerical accuracy. Fixes: 7f891faf596ed ("clk: qcom: clk-rcg2: Add support for duty-cycle for RCG") Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20260105-duty_cycle_precision-v2-1-d1d466a6330a@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rcg2.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index e18cb8807d73..2838d4cb2d58 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -755,7 +755,7 @@ static int clk_rcg2_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); - u32 notn_m, n, m, d, not2d, mask, duty_per, cfg; + u32 notn_m, n, m, d, not2d, mask, cfg; int ret; /* Duty-cycle cannot be modified for non-MND RCGs */ @@ -774,10 +774,8 @@ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) n = (~(notn_m) + m) & mask; - duty_per = (duty->num * 100) / duty->den; - /* Calculate 2d value */ - d = DIV_ROUND_CLOSEST(n * duty_per * 2, 100); + d = DIV_ROUND_CLOSEST(n * duty->num * 2, duty->den); /* * Check bit widths of 2d. If D is too big reduce duty cycle. From 5b1a43950fd3162af0ce52b13c14a2d29b179d4f Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Mon, 5 Jan 2026 21:47:08 +0100 Subject: [PATCH 043/165] clk: meson: gxbb: Limit the HDMI PLL OD to /4 on GXL/GXM SoCs GXBB has the HDMI PLL OD in the HHI_HDMI_PLL_CNTL2 register while for GXL/GXM the OD has moved to HHI_HDMI_PLL_CNTL3. At first glance the rest of the OD setup seems identical. However, looking at the downstream kernel sources as well as testing shows that GXL only supports three OD values: - register value 0 means: divide by 1 - register value 1 means: divide by 2 - register value 2 means: divide by 4 Using register value 3 (which on GXBB means: divide by 8) still divides by 4 as verified using meson-clk-measure. Downstream sources are also only using OD register values 0, 1 and 2 for GXL (while for GXBB the downstream kernel sources are also using value 3). Add clk_div_table and have it replace the CLK_DIVIDER_POWER_OF_TWO flag to make the kernel's view of this register match with how the hardware actually works. Fixes: 69d92293274b ("clk: meson: add the gxl hdmi pll") Signed-off-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20260105204710.447779-2-martin.blumenstingl@googlemail.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/gxbb.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 5a229c4ffae1..ec9a3414875a 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -349,12 +349,23 @@ static struct clk_regmap gxbb_hdmi_pll = { }, }; +/* + * GXL hdmi OD dividers are POWER_OF_TWO dividers but limited to /4. + * A divider value of 3 should map to /8 but instead map /4 so ignore it. + */ +static const struct clk_div_table gxl_hdmi_pll_od_div_table[] = { + { .val = 0, .div = 1 }, + { .val = 1, .div = 2 }, + { .val = 2, .div = 4 }, + { /* sentinel */ } +}; + static struct clk_regmap gxl_hdmi_pll_od = { .data = &(struct clk_regmap_div_data){ .offset = HHI_HDMI_PLL_CNTL + 8, .shift = 21, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = gxl_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od", @@ -372,7 +383,7 @@ static struct clk_regmap gxl_hdmi_pll_od2 = { .offset = HHI_HDMI_PLL_CNTL + 8, .shift = 23, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = gxl_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od2", @@ -390,7 +401,7 @@ static struct clk_regmap gxl_hdmi_pll = { .offset = HHI_HDMI_PLL_CNTL + 8, .shift = 19, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = gxl_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll", From 7aa6c24697ef5db1402dd38743914493cd5b356d Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Mon, 5 Jan 2026 21:47:09 +0100 Subject: [PATCH 044/165] clk: meson: g12a: Limit the HDMI PLL OD to /4 GXBB has the HDMI PLL OD in the HHI_HDMI_PLL_CNTL2 register while for G12A/G12B/SM1 the OD has moved to HHI_HDMI_PLL_CNTL0. At first glance the rest of the OD setup seems identical. However, looking at the downstream kernel sources as well as testing shows that G12A/G12B/SM1 only supports three OD values: - register value 0 means: divide by 1 - register value 1 means: divide by 2 - register value 2 means: divide by 4 Downstream sources are also only using OD register values 0, 1 and 2 for G12A/G12B/SM1 (while for GXBB the downstream kernel sources are also using value 3 which means: divide by 8). Add clk_div_table and have it replace the CLK_DIVIDER_POWER_OF_TWO flag to make the kernel's view of this register match with how the hardware actually works. Fixes: 085a4ea93d54 ("clk: meson: g12a: add peripheral clock controller") Signed-off-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20260105204710.447779-3-martin.blumenstingl@googlemail.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 185b6348251d..d0d4c7b6dc82 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -777,12 +777,23 @@ static struct clk_regmap g12a_hdmi_pll_dco = { }, }; +/* + * G12/SM1 hdmi OD dividers are POWER_OF_TWO dividers but limited to /4. + * A divider value of 3 should map to /8 but instead map /4 so ignore it. + */ +static const struct clk_div_table g12a_hdmi_pll_od_div_table[] = { + { .val = 0, .div = 1 }, + { .val = 1, .div = 2 }, + { .val = 2, .div = 4 }, + { /* sentinel */ } +}; + static struct clk_regmap g12a_hdmi_pll_od = { .data = &(struct clk_regmap_div_data){ .offset = HHI_HDMI_PLL_CNTL0, .shift = 16, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = g12a_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od", @@ -800,7 +811,7 @@ static struct clk_regmap g12a_hdmi_pll_od2 = { .offset = HHI_HDMI_PLL_CNTL0, .shift = 18, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = g12a_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od2", @@ -818,7 +829,7 @@ static struct clk_regmap g12a_hdmi_pll = { .offset = HHI_HDMI_PLL_CNTL0, .shift = 20, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = g12a_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll", From 2fe1ef40b58c2256f4682594f48bfbd584501ec5 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Mon, 5 Jan 2026 21:47:10 +0100 Subject: [PATCH 045/165] clk: meson: gxbb: use the existing HHI_HDMI_PLL_CNTL3 macro There's no need to calculate HHI_HDMI_PLL_CNTL + 8 when we have a HHI_HDMI_PLL_CNTL3 macro that has the correct offset already. No functional changes, this makes it easier to compare the driver with the datasheets. Signed-off-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20260105204710.447779-4-martin.blumenstingl@googlemail.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/gxbb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index ec9a3414875a..f9131d014ef4 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -362,7 +362,7 @@ static const struct clk_div_table gxl_hdmi_pll_od_div_table[] = { static struct clk_regmap gxl_hdmi_pll_od = { .data = &(struct clk_regmap_div_data){ - .offset = HHI_HDMI_PLL_CNTL + 8, + .offset = HHI_HDMI_PLL_CNTL3, .shift = 21, .width = 2, .table = gxl_hdmi_pll_od_div_table, @@ -380,7 +380,7 @@ static struct clk_regmap gxl_hdmi_pll_od = { static struct clk_regmap gxl_hdmi_pll_od2 = { .data = &(struct clk_regmap_div_data){ - .offset = HHI_HDMI_PLL_CNTL + 8, + .offset = HHI_HDMI_PLL_CNTL3, .shift = 23, .width = 2, .table = gxl_hdmi_pll_od_div_table, @@ -398,7 +398,7 @@ static struct clk_regmap gxl_hdmi_pll_od2 = { static struct clk_regmap gxl_hdmi_pll = { .data = &(struct clk_regmap_div_data){ - .offset = HHI_HDMI_PLL_CNTL + 8, + .offset = HHI_HDMI_PLL_CNTL3, .shift = 19, .width = 2, .table = gxl_hdmi_pll_od_div_table, From 89428516f99572a9c37ebbb7859595881e7025a0 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Thu, 27 Nov 2025 23:27:36 +0530 Subject: [PATCH 046/165] clk: qcom: gcc-sm8450: Update the SDCC RCGs to use shared_floor_ops Use shared_floor_ops for the SDCC RCGs so the RCG is safely parked during disable and the new parent configuration is programmed in hardware only when the new parent is enabled, avoiding cases where the RCG configuration fails to update. Fixes: a27ac3806b0a ("clk: qcom: gcc-sm8450: Use floor ops for SDCC RCGs") Reviewed-by: Taniya Das Reviewed-by: Imran Shaik Reviewed-by: Dmitry Baryshkov Reviewed-by: Vladimir Zapolskiy Signed-off-by: Jagadeesh Kona Link: https://lore.kernel.org/r/20251127-sdcc_shared_floor_ops-v2-1-473afc86589c@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sm8450.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-sm8450.c b/drivers/clk/qcom/gcc-sm8450.c index 65d7d52bce03..b18bb34889ab 100644 --- a/drivers/clk/qcom/gcc-sm8450.c +++ b/drivers/clk/qcom/gcc-sm8450.c @@ -1034,7 +1034,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_7, .num_parents = ARRAY_SIZE(gcc_parent_data_7), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1057,7 +1057,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; From a7231d4aa084e485394f9214ec9bcb2d1f65dde9 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Thu, 27 Nov 2025 23:27:37 +0530 Subject: [PATCH 047/165] clk: qcom: gcc-sm8750: Update the SDCC RCGs to use shared_floor_ops Use shared_floor_ops for the SDCC RCGs so the RCG is safely parked during disable and the new parent configuration is programmed in hardware only when the new parent is enabled, avoiding cases where the RCG configuration fails to update. Fixes: 3267c774f3ff ("clk: qcom: Add support for GCC on SM8750") Reviewed-by: Taniya Das Reviewed-by: Imran Shaik Reviewed-by: Dmitry Baryshkov Reviewed-by: Vladimir Zapolskiy Signed-off-by: Jagadeesh Kona Link: https://lore.kernel.org/r/20251127-sdcc_shared_floor_ops-v2-2-473afc86589c@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sm8750.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-sm8750.c b/drivers/clk/qcom/gcc-sm8750.c index def86b71a3da..db81569dd4b1 100644 --- a/drivers/clk/qcom/gcc-sm8750.c +++ b/drivers/clk/qcom/gcc-sm8750.c @@ -1030,7 +1030,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_8, .num_parents = ARRAY_SIZE(gcc_parent_data_8), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1052,7 +1052,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; From 458e8a082186335380a9ab83003a385aec9bb254 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Thu, 27 Nov 2025 23:27:38 +0530 Subject: [PATCH 048/165] clk: qcom: gcc-sm4450: Update the SDCC RCGs to use shared_floor_ops Use shared_floor_ops for the SDCC RCGs so the RCG is safely parked during disable and the new parent configuration is programmed in hardware only when the new parent is enabled, avoiding cases where the RCG configuration fails to update. Fixes: c32c4ef98bac ("clk: qcom: Add GCC driver support for SM4450") Reviewed-by: Taniya Das Reviewed-by: Imran Shaik Reviewed-by: Dmitry Baryshkov Reviewed-by: Vladimir Zapolskiy Signed-off-by: Jagadeesh Kona Link: https://lore.kernel.org/r/20251127-sdcc_shared_floor_ops-v2-3-473afc86589c@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sm4450.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/qcom/gcc-sm4450.c b/drivers/clk/qcom/gcc-sm4450.c index e2d9e4691c5b..023d840e9f4e 100644 --- a/drivers/clk/qcom/gcc-sm4450.c +++ b/drivers/clk/qcom/gcc-sm4450.c @@ -769,7 +769,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { .parent_data = gcc_parent_data_4, .num_parents = ARRAY_SIZE(gcc_parent_data_4), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -791,7 +791,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { .parent_data = gcc_parent_data_4, .num_parents = ARRAY_SIZE(gcc_parent_data_4), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -815,7 +815,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_6, .num_parents = ARRAY_SIZE(gcc_parent_data_6), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; From 4b057462bb61a6571608ba393e6e018c9da9c9c3 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Thu, 27 Nov 2025 23:27:39 +0530 Subject: [PATCH 049/165] clk: qcom: gcc-sdx75: Update the SDCC RCGs to use shared_floor_ops Use shared_floor_ops for the SDCC RCGs so the RCG is safely parked during disable and the new parent configuration is programmed in hardware only when the new parent is enabled, avoiding cases where the RCG configuration fails to update. Fixes: 108cdc09b2de ("clk: qcom: Add GCC driver support for SDX75") Reviewed-by: Taniya Das Reviewed-by: Imran Shaik Reviewed-by: Dmitry Baryshkov Reviewed-by: Vladimir Zapolskiy Signed-off-by: Jagadeesh Kona Link: https://lore.kernel.org/r/20251127-sdcc_shared_floor_ops-v2-4-473afc86589c@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sdx75.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-sdx75.c b/drivers/clk/qcom/gcc-sdx75.c index 453a6bf8e878..1f3cd58483a2 100644 --- a/drivers/clk/qcom/gcc-sdx75.c +++ b/drivers/clk/qcom/gcc-sdx75.c @@ -1033,7 +1033,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { .name = "gcc_sdcc1_apps_clk_src", .parent_data = gcc_parent_data_17, .num_parents = ARRAY_SIZE(gcc_parent_data_17), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1057,7 +1057,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_18, .num_parents = ARRAY_SIZE(gcc_parent_data_18), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; From 08da8d7dabb161cea14c6d3ad9b5037aaf6d4b7e Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Thu, 27 Nov 2025 23:27:40 +0530 Subject: [PATCH 050/165] clk: qcom: gcc-milos: Update the SDCC RCGs to use shared_floor_ops Use shared_floor_ops for the SDCC RCGs to avoid any overclocking issues in SDCC usecases. Fixes: 88174d5d9422 ("clk: qcom: Add Global Clock controller (GCC) driver for Milos") Reviewed-by: Taniya Das Reviewed-by: Imran Shaik Reviewed-by: Dmitry Baryshkov Reviewed-by: Vladimir Zapolskiy Signed-off-by: Jagadeesh Kona Link: https://lore.kernel.org/r/20251127-sdcc_shared_floor_ops-v2-5-473afc86589c@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-milos.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/qcom/gcc-milos.c b/drivers/clk/qcom/gcc-milos.c index c9d61b05bafa..81fa09ec55d7 100644 --- a/drivers/clk/qcom/gcc-milos.c +++ b/drivers/clk/qcom/gcc-milos.c @@ -917,7 +917,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { .name = "gcc_sdcc1_apps_clk_src", .parent_data = gcc_parent_data_9, .num_parents = ARRAY_SIZE(gcc_parent_data_9), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -938,7 +938,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { .name = "gcc_sdcc1_ice_core_clk_src", .parent_data = gcc_parent_data_10, .num_parents = ARRAY_SIZE(gcc_parent_data_10), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -962,7 +962,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_11, .num_parents = ARRAY_SIZE(gcc_parent_data_11), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; From a468047c4e1c56783204a3ac551b843b4277c8fc Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Thu, 27 Nov 2025 23:27:41 +0530 Subject: [PATCH 051/165] clk: qcom: gcc-x1e80100: Update the SDCC RCGs to use shared_floor_ops Use shared_floor_ops for the SDCC RCGs so the RCG is safely parked during disable and the new parent configuration is programmed in hardware only when the new parent is enabled, avoiding cases where the RCG configuration fails to update. Fixes: 161b7c401f4b ("clk: qcom: Add Global Clock controller (GCC) driver for X1E80100") Signed-off-by: Jagadeesh Kona Reviewed-by: Imran Shaik Reviewed-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20251127-sdcc_shared_floor_ops-v2-6-473afc86589c@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-x1e80100.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index ae9621aff858..74afd12c158c 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -1564,7 +1564,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_9, .num_parents = ARRAY_SIZE(gcc_parent_data_9), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1586,7 +1586,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; From 947c4b326c1f4dc64aed42170b39c2cf551ba8ca Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Thu, 27 Nov 2025 23:27:42 +0530 Subject: [PATCH 052/165] clk: qcom: gcc-qdu1000: Update the SDCC RCGs to use shared_floor_ops Use shared_floor_ops for the SDCC RCGs so the RCG is safely parked during disable and the new parent configuration is programmed in hardware only when the new parent is enabled, avoiding cases where the RCG configuration fails to update. Fixes: baa316580013 ("clk: qcom: gcc-qdu1000: Update the SDCC clock RCG ops") Signed-off-by: Jagadeesh Kona Reviewed-by: Imran Shaik Reviewed-by: Taniya Das Reviewed-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20251127-sdcc_shared_floor_ops-v2-7-473afc86589c@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-qdu1000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-qdu1000.c b/drivers/clk/qcom/gcc-qdu1000.c index dbe9e9437939..915bb9b4ff81 100644 --- a/drivers/clk/qcom/gcc-qdu1000.c +++ b/drivers/clk/qcom/gcc-qdu1000.c @@ -904,7 +904,7 @@ static struct clk_rcg2 gcc_sdcc5_apps_clk_src = { .name = "gcc_sdcc5_apps_clk_src", .parent_data = gcc_parent_data_8, .num_parents = ARRAY_SIZE(gcc_parent_data_8), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -923,7 +923,7 @@ static struct clk_rcg2 gcc_sdcc5_ice_core_clk_src = { .name = "gcc_sdcc5_ice_core_clk_src", .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; From d5639a6d72810023d257c935cb763aea1ada1abc Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Thu, 27 Nov 2025 23:27:43 +0530 Subject: [PATCH 053/165] clk: qcom: gcc-glymur: Update the SDCC RCGs to use shared_floor_ops Use shared_floor_ops for the SDCC RCGs so the RCG is safely parked during disable and the new parent configuration is programmed in hardware only when the new parent is enabled, avoiding cases where the RCG configuration fails to update. Fixes: efe504300a17 ("clk: qcom: gcc: Add support for Global Clock Controller") Signed-off-by: Jagadeesh Kona Reviewed-by: Imran Shaik Reviewed-by: Taniya Das Reviewed-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20251127-sdcc_shared_floor_ops-v2-8-473afc86589c@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-glymur.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-glymur.c b/drivers/clk/qcom/gcc-glymur.c index deab819576d0..238e205735ed 100644 --- a/drivers/clk/qcom/gcc-glymur.c +++ b/drivers/clk/qcom/gcc-glymur.c @@ -2317,7 +2317,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_17, .num_parents = ARRAY_SIZE(gcc_parent_data_17), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -2339,7 +2339,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_3, .num_parents = ARRAY_SIZE(gcc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; From d88d5bedb502eed6f439838b1e6148942a9232b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20Cz=C3=A9m=C3=A1n?= Date: Mon, 17 Nov 2025 17:57:06 +0100 Subject: [PATCH 054/165] dt-bindings: clock: qcom: Add MSM8940 Global Clock Controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add devicetree bindings for the global clock controller on Qualcomm MSM8940 platform. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Barnabás Czémán Link: https://lore.kernel.org/r/20251117-gcc-msm8940-sdm439-v2-1-4af57c8bc7eb@mainlining.org Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/clock/qcom,gcc-msm8953.yaml | 5 +++-- include/dt-bindings/clock/qcom,gcc-msm8917.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml index f2e37f439d28..68fcd0d6492f 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/clock/qcom,gcc-msm8953.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Qualcomm Global Clock & Reset Controller on MSM8953 +title: Qualcomm Global Clock & Reset Controller on MSM8937, MSM8940 and MSM8953 maintainers: - Adam Skladowski @@ -13,7 +13,7 @@ maintainers: description: | Qualcomm global clock control module provides the clocks, resets and power - domains on MSM8937 or MSM8953. + domains on MSM8937, MSM8940 or MSM8953. See also:: include/dt-bindings/clock/qcom,gcc-msm8917.h @@ -23,6 +23,7 @@ properties: compatible: enum: - qcom,gcc-msm8937 + - qcom,gcc-msm8940 - qcom,gcc-msm8953 clocks: diff --git a/include/dt-bindings/clock/qcom,gcc-msm8917.h b/include/dt-bindings/clock/qcom,gcc-msm8917.h index 4265460bfb30..c592682d5ba7 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8917.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8917.h @@ -187,6 +187,7 @@ #define MSM8937_GCC_MDSS_PCLK1_CLK 179 #define MSM8937_GCC_OXILI_AON_CLK 180 #define MSM8937_GCC_OXILI_TIMER_CLK 181 +#define MSM8940_GCC_IPA_TBU_CLK 182 /* GCC block resets */ #define GCC_CAMSS_MICRO_BCR 0 From b97a6150050c7274d72a349afe017fb1fed34799 Mon Sep 17 00:00:00 2001 From: Daniil Titov Date: Mon, 17 Nov 2025 17:57:07 +0100 Subject: [PATCH 055/165] clk: qcom: gcc: Add support for Global Clock controller found on MSM8940 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modify existing MSM8917 driver to support MSM8940 SoC. MSM8940 SoC has the same changes as MSM8937 SoC, but with additional IPA clk and different GFX3D clock frequency table. Signed-off-by: Daniil Titov Signed-off-by: Barnabás Czémán Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251117-gcc-msm8940-sdm439-v2-2-4af57c8bc7eb@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 6 +- drivers/clk/qcom/gcc-msm8917.c | 231 +++++++++++++++++++++++++++++++++ 2 files changed, 234 insertions(+), 3 deletions(-) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 960ef7b4890e..fdc8e07abbcc 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -387,12 +387,12 @@ config MSM_GCC_8916 SD/eMMC, display, graphics, camera etc. config MSM_GCC_8917 - tristate "MSM89(17/37)/QM215 Global Clock Controller" + tristate "MSM89(17/37/40)/QM215 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC help - Support for the global clock controller on msm8917, msm8937 - and qm215 devices. + Support for the global clock controller on msm8917, msm8937, + msm8940 and qm215 devices. Say Y if you want to use devices such as UART, SPI i2c, USB, SD/eMMC, display, graphics, camera etc. diff --git a/drivers/clk/qcom/gcc-msm8917.c b/drivers/clk/qcom/gcc-msm8917.c index 248fa0fd86f5..5d0512a1e6d7 100644 --- a/drivers/clk/qcom/gcc-msm8917.c +++ b/drivers/clk/qcom/gcc-msm8917.c @@ -957,6 +957,27 @@ static const struct freq_tbl ftbl_gfx3d_clk_src_msm8937[] = { { } }; +static const struct freq_tbl ftbl_gfx3d_clk_src_msm8940[] = { + 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(216000000, P_GPLL6, 5, 0, 0), + F(228570000, P_GPLL0, 3.5, 0, 0), + F(240000000, P_GPLL6, 4.5, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(300000000, P_GPLL3, 1, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + F(375000000, P_GPLL3, 1, 0, 0), + F(400000000, P_GPLL0, 2, 0, 0), + F(450000000, P_GPLL3, 1, 0, 0), + F(475000000, P_GPLL3, 1, 0, 0), + F(500000000, P_GPLL3, 1, 0, 0), + { } +}; + static struct clk_rcg2 gfx3d_clk_src = { .cmd_rcgr = 0x59000, .hid_width = 5, @@ -3307,6 +3328,19 @@ static struct clk_branch gcc_vfe_tbu_clk = { } }; +static struct clk_branch gcc_ipa_tbu_clk = { + .halt_reg = 0x120a0, + .halt_check = BRANCH_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 gdsc venus_gdsc = { .gdscr = 0x4c018, .cxcs = (unsigned int []){ 0x4c024, 0x4c01c }, @@ -3764,6 +3798,189 @@ static struct clk_regmap *gcc_msm8937_clocks[] = { [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr, }; +static struct clk_regmap *gcc_msm8940_clocks[] = { + [GPLL0] = &gpll0.clkr, + [GPLL0_EARLY] = &gpll0_early.clkr, + [GPLL0_SLEEP_CLK_SRC] = &gpll0_sleep_clk_src.clkr, + [GPLL3] = &gpll3.clkr, + [GPLL3_EARLY] = &gpll3_early.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL4_EARLY] = &gpll4_early.clkr, + [GPLL6] = &gpll6, + [GPLL6_EARLY] = &gpll6_early.clkr, + [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr, + [MSM8937_BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [MSM8937_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, + [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, + [MSM8937_BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr, + [MSM8937_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, + [BYTE0_CLK_SRC] = &byte0_clk_src.clkr, + [MSM8937_BYTE1_CLK_SRC] = &byte1_clk_src.clkr, + [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr, + [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr, + [CAMSS_TOP_AHB_CLK_SRC] = &camss_top_ahb_clk_src.clkr, + [CCI_CLK_SRC] = &cci_clk_src.clkr, + [CPP_CLK_SRC] = &cpp_clk_src.clkr, + [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr, + [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr, + [CSI0_CLK_SRC] = &csi0_clk_src.clkr, + [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr, + [CSI1_CLK_SRC] = &csi1_clk_src.clkr, + [CSI2_CLK_SRC] = &csi2_clk_src.clkr, + [ESC0_CLK_SRC] = &esc0_clk_src.clkr, + [MSM8937_ESC1_CLK_SRC] = &esc1_clk_src.clkr, + [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr, + [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr, + [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr, + [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr, + [MDP_CLK_SRC] = &mdp_clk_src.clkr, + [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr, + [MSM8937_PCLK1_CLK_SRC] = &pclk1_clk_src.clkr, + [PDM2_CLK_SRC] = &pdm2_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr, + [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr, + [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr, + [VCODEC0_CLK_SRC] = &vcodec0_clk_src.clkr, + [VFE0_CLK_SRC] = &vfe0_clk_src.clkr, + [VFE1_CLK_SRC] = &vfe1_clk_src.clkr, + [VSYNC_CLK_SRC] = &vsync_clk_src.clkr, + [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr, + [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, + [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [MSM8937_GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [MSM8937_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_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, + [MSM8937_GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr, + [MSM8937_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, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMSS_AHB_CLK] = &gcc_camss_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_CPP_AHB_CLK] = &gcc_camss_cpp_ahb_clk.clkr, + [GCC_CAMSS_CPP_CLK] = &gcc_camss_cpp_clk.clkr, + [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_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_CSI0_AHB_CLK] = &gcc_camss_csi0_ahb_clk.clkr, + [GCC_CAMSS_CSI0_CLK] = &gcc_camss_csi0_clk.clkr, + [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_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_CSI1_AHB_CLK] = &gcc_camss_csi1_ahb_clk.clkr, + [GCC_CAMSS_CSI1_CLK] = &gcc_camss_csi1_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_CSI2_AHB_CLK] = &gcc_camss_csi2_ahb_clk.clkr, + [GCC_CAMSS_CSI2_CLK] = &gcc_camss_csi2_clk.clkr, + [GCC_CAMSS_CSI_VFE0_CLK] = &gcc_camss_csi_vfe0_clk.clkr, + [GCC_CAMSS_CSI_VFE1_CLK] = &gcc_camss_csi_vfe1_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_MCLK2_CLK] = &gcc_camss_mclk2_clk.clkr, + [GCC_CAMSS_MICRO_AHB_CLK] = &gcc_camss_micro_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_VFE0_CLK] = &gcc_camss_vfe0_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_VFE1_CLK] = &gcc_camss_vfe1_clk.clkr, + [GCC_CPP_TBU_CLK] = &gcc_cpp_tbu_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_DCC_CLK] = &gcc_dcc_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_JPEG_TBU_CLK] = &gcc_jpeg_tbu_clk.clkr, + [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_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, + [MSM8937_GCC_MDSS_BYTE1_CLK] = &gcc_mdss_byte1_clk.clkr, + [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr, + [MSM8937_GCC_MDSS_ESC1_CLK] = &gcc_mdss_esc1_clk.clkr, + [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr, + [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr, + [MSM8937_GCC_MDSS_PCLK1_CLK] = &gcc_mdss_pclk1_clk.clkr, + [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [GCC_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr, + [MSM8937_GCC_OXILI_AON_CLK] = &gcc_oxili_aon_clk.clkr, + [GCC_OXILI_GFX3D_CLK] = &gcc_oxili_gfx3d_clk.clkr, + [MSM8937_GCC_OXILI_TIMER_CLK] = &gcc_oxili_timer_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_QDSS_DAP_CLK] = &gcc_qdss_dap_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_SMMU_CFG_CLK] = &gcc_smmu_cfg_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_PHY_CFG_AHB_CLK] = &gcc_usb_hs_phy_cfg_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_CORE0_VCODEC0_CLK] = &gcc_venus0_core0_vcodec0_clk.clkr, + [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr, + [GCC_VENUS_TBU_CLK] = &gcc_venus_tbu_clk.clkr, + [GCC_VFE1_TBU_CLK] = &gcc_vfe1_tbu_clk.clkr, + [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr, + [MSM8940_GCC_IPA_TBU_CLK] = &gcc_ipa_tbu_clk.clkr, +}; + static const struct qcom_reset_map gcc_msm8917_resets[] = { [GCC_CAMSS_MICRO_BCR] = { 0x56008 }, [GCC_MSS_BCR] = { 0x71000 }, @@ -3834,6 +4051,16 @@ static const struct qcom_cc_desc gcc_msm8937_desc = { .num_gdscs = ARRAY_SIZE(gcc_msm8937_gdscs), }; +static const struct qcom_cc_desc gcc_msm8940_desc = { + .config = &gcc_msm8917_regmap_config, + .clks = gcc_msm8940_clocks, + .num_clks = ARRAY_SIZE(gcc_msm8940_clocks), + .resets = gcc_msm8917_resets, + .num_resets = ARRAY_SIZE(gcc_msm8917_resets), + .gdscs = gcc_msm8937_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_msm8937_gdscs), +}; + static void msm8937_clock_override(void) { /* GPLL3 750MHz configuration */ @@ -3871,6 +4098,9 @@ static int gcc_msm8917_probe(struct platform_device *pdev) } else if (gcc_desc == &gcc_msm8937_desc) { msm8937_clock_override(); gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_msm8937; + } else if (gcc_desc == &gcc_msm8940_desc) { + msm8937_clock_override(); + gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_msm8940; } regmap = qcom_cc_map(pdev, gcc_desc); @@ -3886,6 +4116,7 @@ static const struct of_device_id gcc_msm8917_match_table[] = { { .compatible = "qcom,gcc-msm8917", .data = &gcc_msm8917_desc }, { .compatible = "qcom,gcc-qm215", .data = &gcc_qm215_desc }, { .compatible = "qcom,gcc-msm8937", .data = &gcc_msm8937_desc }, + { .compatible = "qcom,gcc-msm8940", .data = &gcc_msm8940_desc }, {}, }; MODULE_DEVICE_TABLE(of, gcc_msm8917_match_table); From 7a5a8a67c06ecba23d547a57d9fd317f628e1790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20Cz=C3=A9m=C3=A1n?= Date: Mon, 17 Nov 2025 17:57:08 +0100 Subject: [PATCH 056/165] dt-bindings: clock: qcom: Add SDM439 Global Clock Controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add devicetree bindings for the global clock controller on Qualcomm SDM439 platform. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Barnabás Czémán Link: https://lore.kernel.org/r/20251117-gcc-msm8940-sdm439-v2-3-4af57c8bc7eb@mainlining.org Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/clock/qcom,gcc-msm8953.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml index 68fcd0d6492f..ced3118c8580 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/clock/qcom,gcc-msm8953.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Qualcomm Global Clock & Reset Controller on MSM8937, MSM8940 and MSM8953 +title: Qualcomm Global Clock & Reset Controller on MSM8937, MSM8940, MSM8953 and SDM439 maintainers: - Adam Skladowski @@ -13,7 +13,7 @@ maintainers: description: | Qualcomm global clock control module provides the clocks, resets and power - domains on MSM8937, MSM8940 or MSM8953. + domains on MSM8937, MSM8940, MSM8953 or SDM439. See also:: include/dt-bindings/clock/qcom,gcc-msm8917.h @@ -25,6 +25,7 @@ properties: - qcom,gcc-msm8937 - qcom,gcc-msm8940 - qcom,gcc-msm8953 + - qcom,gcc-sdm439 clocks: items: From a6df111d55ffea7926fc7b136f96f16b314ad362 Mon Sep 17 00:00:00 2001 From: Daniil Titov Date: Mon, 17 Nov 2025 17:57:09 +0100 Subject: [PATCH 057/165] clk: qcom: gcc: Add support for Global Clock controller found on SDM439 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modify existing MSM8917 driver to support SDM439 SoC. SDM439 SoC has the same changes as MSM8937 SoC, but with different gpll3 vco rate and different GFX3D clock frequency table. Signed-off-by: Daniil Titov Signed-off-by: Barnabás Czémán Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251117-gcc-msm8940-sdm439-v2-4-4af57c8bc7eb@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 4 +-- drivers/clk/qcom/gcc-msm8917.c | 49 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index fdc8e07abbcc..4bbe942f0e96 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -387,12 +387,12 @@ config MSM_GCC_8916 SD/eMMC, display, graphics, camera etc. config MSM_GCC_8917 - tristate "MSM89(17/37/40)/QM215 Global Clock Controller" + tristate "MSM89(17/37/40)/QM215/SDM439 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC help Support for the global clock controller on msm8917, msm8937, - msm8940 and qm215 devices. + msm8940, qm215 and sdm439 devices. Say Y if you want to use devices such as UART, SPI i2c, USB, SD/eMMC, display, graphics, camera etc. diff --git a/drivers/clk/qcom/gcc-msm8917.c b/drivers/clk/qcom/gcc-msm8917.c index 5d0512a1e6d7..07a796f94911 100644 --- a/drivers/clk/qcom/gcc-msm8917.c +++ b/drivers/clk/qcom/gcc-msm8917.c @@ -978,6 +978,27 @@ static const struct freq_tbl ftbl_gfx3d_clk_src_msm8940[] = { { } }; +static const struct freq_tbl ftbl_gfx3d_clk_src_sdm439[] = { + 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(216000000, P_GPLL6, 5, 0, 0), + F(228570000, P_GPLL0, 3.5, 0, 0), + F(240000000, P_GPLL6, 4.5, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + F(355200000, P_GPLL3, 1, 0, 0), + F(400000000, P_GPLL0, 2, 0, 0), + F(450000000, P_GPLL3, 1, 0, 0), + F(510000000, P_GPLL3, 1, 0, 0), + F(560000000, P_GPLL3, 1, 0, 0), + F(650000000, P_GPLL3, 1, 0, 0), + { } +}; + static struct clk_rcg2 gfx3d_clk_src = { .cmd_rcgr = 0x59000, .hid_width = 5, @@ -4061,6 +4082,16 @@ static const struct qcom_cc_desc gcc_msm8940_desc = { .num_gdscs = ARRAY_SIZE(gcc_msm8937_gdscs), }; +static const struct qcom_cc_desc gcc_sdm439_desc = { + .config = &gcc_msm8917_regmap_config, + .clks = gcc_msm8937_clocks, + .num_clks = ARRAY_SIZE(gcc_msm8937_clocks), + .resets = gcc_msm8917_resets, + .num_resets = ARRAY_SIZE(gcc_msm8917_resets), + .gdscs = gcc_msm8937_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_msm8937_gdscs), +}; + static void msm8937_clock_override(void) { /* GPLL3 750MHz configuration */ @@ -4086,6 +4117,21 @@ static void msm8937_clock_override(void) usb_hs_system_clk_src.freq_tbl = ftbl_usb_hs_system_clk_src_msm8937; } +static void sdm439_clock_override(void) +{ + vcodec0_clk_src.parent_map = gcc_cpp_map; + vcodec0_clk_src.clkr.hw.init = &vcodec0_clk_src_init_msm8937; + + vfe0_clk_src.freq_tbl = ftbl_vfe_clk_src_msm8937; + vfe1_clk_src.freq_tbl = ftbl_vfe_clk_src_msm8937; + cpp_clk_src.freq_tbl = ftbl_cpp_clk_src_msm8937; + vcodec0_clk_src.freq_tbl = ftbl_vcodec0_clk_src_msm8937; + gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_sdm439; + csi0phytimer_clk_src.freq_tbl = ftbl_csi_phytimer_clk_src_msm8937; + csi1phytimer_clk_src.freq_tbl = ftbl_csi_phytimer_clk_src_msm8937; + usb_hs_system_clk_src.freq_tbl = ftbl_usb_hs_system_clk_src_msm8937; +} + static int gcc_msm8917_probe(struct platform_device *pdev) { struct regmap *regmap; @@ -4101,6 +4147,8 @@ static int gcc_msm8917_probe(struct platform_device *pdev) } else if (gcc_desc == &gcc_msm8940_desc) { msm8937_clock_override(); gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_msm8940; + } else if (gcc_desc == &gcc_sdm439_desc) { + sdm439_clock_override(); } regmap = qcom_cc_map(pdev, gcc_desc); @@ -4117,6 +4165,7 @@ static const struct of_device_id gcc_msm8917_match_table[] = { { .compatible = "qcom,gcc-qm215", .data = &gcc_qm215_desc }, { .compatible = "qcom,gcc-msm8937", .data = &gcc_msm8937_desc }, { .compatible = "qcom,gcc-msm8940", .data = &gcc_msm8940_desc }, + { .compatible = "qcom,gcc-sdm439", .data = &gcc_sdm439_desc }, {}, }; MODULE_DEVICE_TABLE(of, gcc_msm8917_match_table); From 5f613e7034187179a9d088ff5fd02b1089d0cf20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20Cz=C3=A9m=C3=A1n?= Date: Mon, 17 Nov 2025 18:58:47 +0100 Subject: [PATCH 058/165] clk: qcom: gcc-msm8953: Remove ALWAYS_ON flag from cpp_gdsc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cpp_gdsc should not be always on, ALWAYS_ON flag was set accidentally. Fixes: 9bb6cfc3c77e ("clk: qcom: Add Global Clock Controller driver for MSM8953") Signed-off-by: Barnabás Czémán Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251117-fix-gdsc-cpp-msm8917-msm8953-v1-1-db33adcff28a@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-msm8953.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/qcom/gcc-msm8953.c b/drivers/clk/qcom/gcc-msm8953.c index 8f29ecc74c50..8fe1d3e42144 100644 --- a/drivers/clk/qcom/gcc-msm8953.c +++ b/drivers/clk/qcom/gcc-msm8953.c @@ -3946,7 +3946,6 @@ static struct gdsc cpp_gdsc = { .pd = { .name = "cpp_gdsc", }, - .flags = ALWAYS_ON, .pwrsts = PWRSTS_OFF_ON, }; From e4eb42f290aecac0ba355b1f8d7243be6de11f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20Cz=C3=A9m=C3=A1n?= Date: Mon, 17 Nov 2025 18:58:48 +0100 Subject: [PATCH 059/165] clk: qcom: gcc-msm8917: Remove ALWAYS_ON flag from cpp_gdsc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cpp_gdsc should not be always on, ALWAYS_ON flag was set accidentally. Fixes: 33cc27a47d3a ("clk: qcom: Add global clock controller driver for MSM8917") Signed-off-by: Barnabás Czémán Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251117-fix-gdsc-cpp-msm8917-msm8953-v1-2-db33adcff28a@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-msm8917.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/qcom/gcc-msm8917.c b/drivers/clk/qcom/gcc-msm8917.c index 07a796f94911..2f561a950bc2 100644 --- a/drivers/clk/qcom/gcc-msm8917.c +++ b/drivers/clk/qcom/gcc-msm8917.c @@ -3464,7 +3464,6 @@ static struct gdsc cpp_gdsc = { .pd = { .name = "cpp_gdsc", }, - .flags = ALWAYS_ON, .pwrsts = PWRSTS_OFF_ON, }; From 04c4dc1f541135708d90a9b4632af51136f93ac3 Mon Sep 17 00:00:00 2001 From: George Moussalem Date: Fri, 28 Nov 2025 15:03:19 +0400 Subject: [PATCH 060/165] clk: qcom: gcc-ipq5018: flag sleep clock as critical The sleep clock never be disabled. To avoid the kernel trying to disable it and keep it always on, flag it as critical. Fixes: e3fdbef1bab8 ("clk: qcom: Add Global Clock controller (GCC) driver for IPQ5018") Signed-off-by: George Moussalem Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251128-ipq5018-sleep-clk-fix-v1-1-6f4b75ec336c@outlook.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-ipq5018.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/gcc-ipq5018.c b/drivers/clk/qcom/gcc-ipq5018.c index dcda2be8c1a5..64792cda0620 100644 --- a/drivers/clk/qcom/gcc-ipq5018.c +++ b/drivers/clk/qcom/gcc-ipq5018.c @@ -1340,6 +1340,7 @@ static struct clk_branch gcc_sleep_clk_src = { .name = "gcc_sleep_clk_src", .parent_data = gcc_sleep_clk_data, .num_parents = ARRAY_SIZE(gcc_sleep_clk_data), + .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, From 82efed175bfa238035664a3b0f1f53d75f695a6b Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 2 Dec 2025 15:56:26 +0530 Subject: [PATCH 061/165] dt-bindings: clock: qcom: Add camera clock controller for SM8750 SoC Add device tree bindings for the camera clock controller on Qualcomm SM8750 platform. The camera clock controller is split between camcc and cambist. The cambist controls the mclks of the camera clock controller. Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20251202-sm8750_camcc-v1-2-b3f7ef6723f1@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm8450-camcc.yaml | 5 + .../clock/qcom,sm8750-cambistmclkcc.h | 30 ++++ include/dt-bindings/clock/qcom,sm8750-camcc.h | 151 ++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h create mode 100644 include/dt-bindings/clock/qcom,sm8750-camcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml index c1e06f39431e..8e3baba5270b 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml @@ -9,6 +9,7 @@ title: Qualcomm Camera Clock & Reset Controller on SM8450 maintainers: - Vladimir Zapolskiy - Jagadeesh Kona + - Taniya Das description: | Qualcomm camera clock control module provides the clocks, resets and power @@ -18,6 +19,8 @@ description: | include/dt-bindings/clock/qcom,sm8450-camcc.h include/dt-bindings/clock/qcom,sm8550-camcc.h include/dt-bindings/clock/qcom,sm8650-camcc.h + include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h + include/dt-bindings/clock/qcom,sm8750-camcc.h properties: compatible: @@ -26,6 +29,8 @@ properties: - qcom,sm8475-camcc - qcom,sm8550-camcc - qcom,sm8650-camcc + - qcom,sm8750-cambistmclkcc + - qcom,sm8750-camcc clocks: items: diff --git a/include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h b/include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h new file mode 100644 index 000000000000..51615bee307f --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.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_CAM_BIST_MCLK_CC_SM8750_H +#define _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_SM8750_H + +/* CAM_BIST_MCLK_CC clocks */ +#define CAM_BIST_MCLK_CC_MCLK0_CLK 0 +#define CAM_BIST_MCLK_CC_MCLK0_CLK_SRC 1 +#define CAM_BIST_MCLK_CC_MCLK1_CLK 2 +#define CAM_BIST_MCLK_CC_MCLK1_CLK_SRC 3 +#define CAM_BIST_MCLK_CC_MCLK2_CLK 4 +#define CAM_BIST_MCLK_CC_MCLK2_CLK_SRC 5 +#define CAM_BIST_MCLK_CC_MCLK3_CLK 6 +#define CAM_BIST_MCLK_CC_MCLK3_CLK_SRC 7 +#define CAM_BIST_MCLK_CC_MCLK4_CLK 8 +#define CAM_BIST_MCLK_CC_MCLK4_CLK_SRC 9 +#define CAM_BIST_MCLK_CC_MCLK5_CLK 10 +#define CAM_BIST_MCLK_CC_MCLK5_CLK_SRC 11 +#define CAM_BIST_MCLK_CC_MCLK6_CLK 12 +#define CAM_BIST_MCLK_CC_MCLK6_CLK_SRC 13 +#define CAM_BIST_MCLK_CC_MCLK7_CLK 14 +#define CAM_BIST_MCLK_CC_MCLK7_CLK_SRC 15 +#define CAM_BIST_MCLK_CC_PLL0 16 +#define CAM_BIST_MCLK_CC_SLEEP_CLK 17 +#define CAM_BIST_MCLK_CC_SLEEP_CLK_SRC 18 + +#endif diff --git a/include/dt-bindings/clock/qcom,sm8750-camcc.h b/include/dt-bindings/clock/qcom,sm8750-camcc.h new file mode 100644 index 000000000000..dae788247afe --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8750-camcc.h @@ -0,0 +1,151 @@ +/* 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_CAM_CC_SM8750_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_SM8750_H + +/* CAM_CC clocks */ +#define CAM_CC_CAM_TOP_AHB_CLK 0 +#define CAM_CC_CAM_TOP_FAST_AHB_CLK 1 +#define CAM_CC_CAMNOC_DCD_XO_CLK 2 +#define CAM_CC_CAMNOC_NRT_AXI_CLK 3 +#define CAM_CC_CAMNOC_NRT_CRE_CLK 4 +#define CAM_CC_CAMNOC_NRT_IPE_NPS_CLK 5 +#define CAM_CC_CAMNOC_NRT_OFE_ANCHOR_CLK 6 +#define CAM_CC_CAMNOC_NRT_OFE_HDR_CLK 7 +#define CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK 8 +#define CAM_CC_CAMNOC_RT_AXI_CLK 9 +#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 10 +#define CAM_CC_CAMNOC_RT_IFE_LITE_CLK 11 +#define CAM_CC_CAMNOC_RT_TFE_0_BAYER_CLK 12 +#define CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK 13 +#define CAM_CC_CAMNOC_RT_TFE_1_BAYER_CLK 14 +#define CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK 15 +#define CAM_CC_CAMNOC_RT_TFE_2_BAYER_CLK 16 +#define CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK 17 +#define CAM_CC_CAMNOC_XO_CLK 18 +#define CAM_CC_CCI_0_CLK 19 +#define CAM_CC_CCI_0_CLK_SRC 20 +#define CAM_CC_CCI_1_CLK 21 +#define CAM_CC_CCI_1_CLK_SRC 22 +#define CAM_CC_CCI_2_CLK 23 +#define CAM_CC_CCI_2_CLK_SRC 24 +#define CAM_CC_CORE_AHB_CLK 25 +#define CAM_CC_CPHY_RX_CLK_SRC 26 +#define CAM_CC_CRE_AHB_CLK 27 +#define CAM_CC_CRE_CLK 28 +#define CAM_CC_CRE_CLK_SRC 29 +#define CAM_CC_CSI0PHYTIMER_CLK 30 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 31 +#define CAM_CC_CSI1PHYTIMER_CLK 32 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 33 +#define CAM_CC_CSI2PHYTIMER_CLK 34 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 35 +#define CAM_CC_CSI3PHYTIMER_CLK 36 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 37 +#define CAM_CC_CSI4PHYTIMER_CLK 38 +#define CAM_CC_CSI4PHYTIMER_CLK_SRC 39 +#define CAM_CC_CSI5PHYTIMER_CLK 40 +#define CAM_CC_CSI5PHYTIMER_CLK_SRC 41 +#define CAM_CC_CSID_CLK 42 +#define CAM_CC_CSID_CLK_SRC 43 +#define CAM_CC_CSID_CSIPHY_RX_CLK 44 +#define CAM_CC_CSIPHY0_CLK 45 +#define CAM_CC_CSIPHY1_CLK 46 +#define CAM_CC_CSIPHY2_CLK 47 +#define CAM_CC_CSIPHY3_CLK 48 +#define CAM_CC_CSIPHY4_CLK 49 +#define CAM_CC_CSIPHY5_CLK 50 +#define CAM_CC_DRV_AHB_CLK 51 +#define CAM_CC_DRV_XO_CLK 52 +#define CAM_CC_FAST_AHB_CLK_SRC 53 +#define CAM_CC_GDSC_CLK 54 +#define CAM_CC_ICP_0_AHB_CLK 55 +#define CAM_CC_ICP_0_CLK 56 +#define CAM_CC_ICP_0_CLK_SRC 57 +#define CAM_CC_ICP_1_AHB_CLK 58 +#define CAM_CC_ICP_1_CLK 59 +#define CAM_CC_ICP_1_CLK_SRC 60 +#define CAM_CC_IFE_LITE_AHB_CLK 61 +#define CAM_CC_IFE_LITE_CLK 62 +#define CAM_CC_IFE_LITE_CLK_SRC 63 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 64 +#define CAM_CC_IFE_LITE_CSID_CLK 65 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 66 +#define CAM_CC_IPE_NPS_AHB_CLK 67 +#define CAM_CC_IPE_NPS_CLK 68 +#define CAM_CC_IPE_NPS_CLK_SRC 69 +#define CAM_CC_IPE_NPS_FAST_AHB_CLK 70 +#define CAM_CC_IPE_PPS_CLK 71 +#define CAM_CC_IPE_PPS_FAST_AHB_CLK 72 +#define CAM_CC_JPEG_0_CLK 73 +#define CAM_CC_JPEG_1_CLK 74 +#define CAM_CC_JPEG_CLK_SRC 75 +#define CAM_CC_OFE_AHB_CLK 76 +#define CAM_CC_OFE_ANCHOR_CLK 77 +#define CAM_CC_OFE_ANCHOR_FAST_AHB_CLK 78 +#define CAM_CC_OFE_CLK_SRC 79 +#define CAM_CC_OFE_HDR_CLK 80 +#define CAM_CC_OFE_HDR_FAST_AHB_CLK 81 +#define CAM_CC_OFE_MAIN_CLK 82 +#define CAM_CC_OFE_MAIN_FAST_AHB_CLK 83 +#define CAM_CC_PLL0 84 +#define CAM_CC_PLL0_OUT_EVEN 85 +#define CAM_CC_PLL0_OUT_ODD 86 +#define CAM_CC_PLL1 87 +#define CAM_CC_PLL1_OUT_EVEN 88 +#define CAM_CC_PLL2 89 +#define CAM_CC_PLL2_OUT_EVEN 90 +#define CAM_CC_PLL3 91 +#define CAM_CC_PLL3_OUT_EVEN 92 +#define CAM_CC_PLL4 93 +#define CAM_CC_PLL4_OUT_EVEN 94 +#define CAM_CC_PLL5 95 +#define CAM_CC_PLL5_OUT_EVEN 96 +#define CAM_CC_PLL6 97 +#define CAM_CC_PLL6_OUT_EVEN 98 +#define CAM_CC_PLL6_OUT_ODD 99 +#define CAM_CC_QDSS_DEBUG_CLK 100 +#define CAM_CC_QDSS_DEBUG_CLK_SRC 101 +#define CAM_CC_QDSS_DEBUG_XO_CLK 102 +#define CAM_CC_SLEEP_CLK 103 +#define CAM_CC_SLEEP_CLK_SRC 104 +#define CAM_CC_SLOW_AHB_CLK_SRC 105 +#define CAM_CC_TFE_0_BAYER_CLK 106 +#define CAM_CC_TFE_0_BAYER_FAST_AHB_CLK 107 +#define CAM_CC_TFE_0_CLK_SRC 108 +#define CAM_CC_TFE_0_MAIN_CLK 109 +#define CAM_CC_TFE_0_MAIN_FAST_AHB_CLK 110 +#define CAM_CC_TFE_1_BAYER_CLK 111 +#define CAM_CC_TFE_1_BAYER_FAST_AHB_CLK 112 +#define CAM_CC_TFE_1_CLK_SRC 113 +#define CAM_CC_TFE_1_MAIN_CLK 114 +#define CAM_CC_TFE_1_MAIN_FAST_AHB_CLK 115 +#define CAM_CC_TFE_2_BAYER_CLK 116 +#define CAM_CC_TFE_2_BAYER_FAST_AHB_CLK 117 +#define CAM_CC_TFE_2_CLK_SRC 118 +#define CAM_CC_TFE_2_MAIN_CLK 119 +#define CAM_CC_TFE_2_MAIN_FAST_AHB_CLK 120 +#define CAM_CC_XO_CLK_SRC 121 + +/* CAM_CC power domains */ +#define CAM_CC_TITAN_TOP_GDSC 0 +#define CAM_CC_IPE_0_GDSC 1 +#define CAM_CC_OFE_GDSC 2 +#define CAM_CC_TFE_0_GDSC 3 +#define CAM_CC_TFE_1_GDSC 4 +#define CAM_CC_TFE_2_GDSC 5 + +/* CAM_CC resets */ +#define CAM_CC_DRV_BCR 0 +#define CAM_CC_ICP_BCR 1 +#define CAM_CC_IPE_0_BCR 2 +#define CAM_CC_OFE_BCR 3 +#define CAM_CC_QDSS_DEBUG_BCR 4 +#define CAM_CC_TFE_0_BCR 5 +#define CAM_CC_TFE_1_BCR 6 +#define CAM_CC_TFE_2_BCR 7 + +#endif From 322aad122ce3eebd70e5c07f62cf9081919a30ca Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:07 +0530 Subject: [PATCH 062/165] dt-bindings: clock: qcom: document Kaanapali DISPCC clock controller Document device tree bindings for display clock controller for Qualcomm Kaanapali SoC. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Reviewed-by: Bryan O'Donoghue Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-4-8e10adc236a8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm8550-dispcc.yaml | 2 + .../dt-bindings/clock/qcom,kaanapali-dispcc.h | 109 ++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,kaanapali-dispcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml index 30e4b4631575..591ce91b8d54 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml @@ -15,6 +15,7 @@ description: | domains on SM8550, SM8650, SM8750 and few other platforms. See also: + - include/dt-bindings/clock/qcom,kaanapali-dispcc.h - include/dt-bindings/clock/qcom,sm8550-dispcc.h - include/dt-bindings/clock/qcom,sm8650-dispcc.h - include/dt-bindings/clock/qcom,sm8750-dispcc.h @@ -23,6 +24,7 @@ description: | properties: compatible: enum: + - qcom,kaanapali-dispcc - qcom,sar2130p-dispcc - qcom,sm8550-dispcc - qcom,sm8650-dispcc diff --git a/include/dt-bindings/clock/qcom,kaanapali-dispcc.h b/include/dt-bindings/clock/qcom,kaanapali-dispcc.h new file mode 100644 index 000000000000..05146f9dfe07 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-dispcc.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_DISP_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_DISP_CC_KAANAPALI_H + +/* DISP_CC clocks */ +#define DISP_CC_ESYNC0_CLK 0 +#define DISP_CC_ESYNC0_CLK_SRC 1 +#define DISP_CC_ESYNC1_CLK 2 +#define DISP_CC_ESYNC1_CLK_SRC 3 +#define DISP_CC_MDSS_ACCU_SHIFT_CLK 4 +#define DISP_CC_MDSS_AHB1_CLK 5 +#define DISP_CC_MDSS_AHB_CLK 6 +#define DISP_CC_MDSS_AHB_CLK_SRC 7 +#define DISP_CC_MDSS_AHB_SWI_CLK 8 +#define DISP_CC_MDSS_AHB_SWI_DIV_CLK_SRC 9 +#define DISP_CC_MDSS_BYTE0_CLK 10 +#define DISP_CC_MDSS_BYTE0_CLK_SRC 11 +#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 12 +#define DISP_CC_MDSS_BYTE0_INTF_CLK 13 +#define DISP_CC_MDSS_BYTE1_CLK 14 +#define DISP_CC_MDSS_BYTE1_CLK_SRC 15 +#define DISP_CC_MDSS_BYTE1_DIV_CLK_SRC 16 +#define DISP_CC_MDSS_BYTE1_INTF_CLK 17 +#define DISP_CC_MDSS_DPTX0_AUX_CLK 18 +#define DISP_CC_MDSS_DPTX0_AUX_CLK_SRC 19 +#define DISP_CC_MDSS_DPTX0_CRYPTO_CLK 20 +#define DISP_CC_MDSS_DPTX0_LINK_CLK 21 +#define DISP_CC_MDSS_DPTX0_LINK_CLK_SRC 22 +#define DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC 23 +#define DISP_CC_MDSS_DPTX0_LINK_INTF_CLK 24 +#define DISP_CC_MDSS_DPTX0_PIXEL0_CLK 25 +#define DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC 26 +#define DISP_CC_MDSS_DPTX0_PIXEL1_CLK 27 +#define DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC 28 +#define DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK 29 +#define DISP_CC_MDSS_DPTX1_AUX_CLK 30 +#define DISP_CC_MDSS_DPTX1_AUX_CLK_SRC 31 +#define DISP_CC_MDSS_DPTX1_CRYPTO_CLK 32 +#define DISP_CC_MDSS_DPTX1_LINK_CLK 33 +#define DISP_CC_MDSS_DPTX1_LINK_CLK_SRC 34 +#define DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC 35 +#define DISP_CC_MDSS_DPTX1_LINK_INTF_CLK 36 +#define DISP_CC_MDSS_DPTX1_PIXEL0_CLK 37 +#define DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC 38 +#define DISP_CC_MDSS_DPTX1_PIXEL1_CLK 39 +#define DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC 40 +#define DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK 41 +#define DISP_CC_MDSS_DPTX2_AUX_CLK 42 +#define DISP_CC_MDSS_DPTX2_AUX_CLK_SRC 43 +#define DISP_CC_MDSS_DPTX2_CRYPTO_CLK 44 +#define DISP_CC_MDSS_DPTX2_LINK_CLK 45 +#define DISP_CC_MDSS_DPTX2_LINK_CLK_SRC 46 +#define DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC 47 +#define DISP_CC_MDSS_DPTX2_LINK_INTF_CLK 48 +#define DISP_CC_MDSS_DPTX2_PIXEL0_CLK 49 +#define DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC 50 +#define DISP_CC_MDSS_DPTX2_PIXEL1_CLK 51 +#define DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC 52 +#define DISP_CC_MDSS_DPTX3_AUX_CLK 53 +#define DISP_CC_MDSS_DPTX3_AUX_CLK_SRC 54 +#define DISP_CC_MDSS_DPTX3_CRYPTO_CLK 55 +#define DISP_CC_MDSS_DPTX3_LINK_CLK 56 +#define DISP_CC_MDSS_DPTX3_LINK_CLK_SRC 57 +#define DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC 58 +#define DISP_CC_MDSS_DPTX3_LINK_INTF_CLK 59 +#define DISP_CC_MDSS_DPTX3_PIXEL0_CLK 60 +#define DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC 61 +#define DISP_CC_MDSS_ESC0_CLK 62 +#define DISP_CC_MDSS_ESC0_CLK_SRC 63 +#define DISP_CC_MDSS_ESC1_CLK 64 +#define DISP_CC_MDSS_ESC1_CLK_SRC 65 +#define DISP_CC_MDSS_MDP1_CLK 66 +#define DISP_CC_MDSS_MDP_CLK 67 +#define DISP_CC_MDSS_MDP_CLK_SRC 68 +#define DISP_CC_MDSS_MDP_LUT1_CLK 69 +#define DISP_CC_MDSS_MDP_LUT_CLK 70 +#define DISP_CC_MDSS_MDP_SS_IP_CLK 71 +#define DISP_CC_MDSS_NON_GDSC_AHB_CLK 72 +#define DISP_CC_MDSS_PCLK0_CLK 73 +#define DISP_CC_MDSS_PCLK0_CLK_SRC 74 +#define DISP_CC_MDSS_PCLK1_CLK 75 +#define DISP_CC_MDSS_PCLK1_CLK_SRC 76 +#define DISP_CC_MDSS_PCLK2_CLK 77 +#define DISP_CC_MDSS_PCLK2_CLK_SRC 78 +#define DISP_CC_MDSS_VSYNC1_CLK 79 +#define DISP_CC_MDSS_VSYNC_CLK 80 +#define DISP_CC_MDSS_VSYNC_CLK_SRC 81 +#define DISP_CC_OSC_CLK 82 +#define DISP_CC_OSC_CLK_SRC 83 +#define DISP_CC_PLL0 84 +#define DISP_CC_PLL1 85 +#define DISP_CC_PLL2 86 +#define DISP_CC_SLEEP_CLK 87 +#define DISP_CC_XO_CLK 88 + +/* DISP_CC power domains */ +#define DISP_CC_MDSS_CORE_GDSC 0 +#define DISP_CC_MDSS_CORE_INT2_GDSC 1 + +/* DISP_CC resets */ +#define DISP_CC_MDSS_CORE_BCR 0 +#define DISP_CC_MDSS_CORE_INT2_BCR 1 +#define DISP_CC_MDSS_RSCC_BCR 2 + +#endif From 9d566b0431d3d5b9c588eb000dbee5138e6a31cd Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:08 +0530 Subject: [PATCH 063/165] dt-bindings: clock: qcom: Add support for CAMCC for Kaanapali Update the compatible and the bindings for CAMCC support on Kaanapali SoC. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-5-8e10adc236a8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm8450-camcc.yaml | 6 + .../clock/qcom,kaanapali-cambistmclkcc.h | 33 ++++ .../dt-bindings/clock/qcom,kaanapali-camcc.h | 147 ++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h create mode 100644 include/dt-bindings/clock/qcom,kaanapali-camcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml index c1e06f39431e..3ec9bf4d82ad 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml @@ -15,6 +15,8 @@ description: | domains on SM8450. See also: + include/dt-bindings/clock/qcom,kaanapali-camcc.h + include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h include/dt-bindings/clock/qcom,sm8450-camcc.h include/dt-bindings/clock/qcom,sm8550-camcc.h include/dt-bindings/clock/qcom,sm8650-camcc.h @@ -22,6 +24,8 @@ description: | properties: compatible: enum: + - qcom,kaanapali-cambistmclkcc + - qcom,kaanapali-camcc - qcom,sm8450-camcc - qcom,sm8475-camcc - qcom,sm8550-camcc @@ -63,6 +67,8 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-cambistmclkcc + - qcom,kaanapali-camcc - qcom,sc8280xp-camcc - qcom,sm8450-camcc - qcom,sm8550-camcc diff --git a/include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h b/include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h new file mode 100644 index 000000000000..ddb083b5289e --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h @@ -0,0 +1,33 @@ +/* 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_CAM_BIST_MCLK_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_KAANAPALI_H + +/* CAM_BIST_MCLK_CC clocks */ +#define CAM_BIST_MCLK_CC_DEBUG_CLK 0 +#define CAM_BIST_MCLK_CC_DEBUG_DIV_CLK_SRC 1 +#define CAM_BIST_MCLK_CC_MCLK0_CLK 2 +#define CAM_BIST_MCLK_CC_MCLK0_CLK_SRC 3 +#define CAM_BIST_MCLK_CC_MCLK1_CLK 4 +#define CAM_BIST_MCLK_CC_MCLK1_CLK_SRC 5 +#define CAM_BIST_MCLK_CC_MCLK2_CLK 6 +#define CAM_BIST_MCLK_CC_MCLK2_CLK_SRC 7 +#define CAM_BIST_MCLK_CC_MCLK3_CLK 8 +#define CAM_BIST_MCLK_CC_MCLK3_CLK_SRC 9 +#define CAM_BIST_MCLK_CC_MCLK4_CLK 10 +#define CAM_BIST_MCLK_CC_MCLK4_CLK_SRC 11 +#define CAM_BIST_MCLK_CC_MCLK5_CLK 12 +#define CAM_BIST_MCLK_CC_MCLK5_CLK_SRC 13 +#define CAM_BIST_MCLK_CC_MCLK6_CLK 14 +#define CAM_BIST_MCLK_CC_MCLK6_CLK_SRC 15 +#define CAM_BIST_MCLK_CC_MCLK7_CLK 16 +#define CAM_BIST_MCLK_CC_MCLK7_CLK_SRC 17 +#define CAM_BIST_MCLK_CC_PLL0 18 +#define CAM_BIST_MCLK_CC_PLL_TEST_CLK 19 +#define CAM_BIST_MCLK_CC_PLL_TEST_DIV_CLK_SRC 20 +#define CAM_BIST_MCLK_CC_SLEEP_CLK 21 + +#endif diff --git a/include/dt-bindings/clock/qcom,kaanapali-camcc.h b/include/dt-bindings/clock/qcom,kaanapali-camcc.h new file mode 100644 index 000000000000..58835136b356 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-camcc.h @@ -0,0 +1,147 @@ +/* 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_CAM_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_KAANAPALI_H + +/* CAM_CC clocks */ +#define CAM_CC_CAM_TOP_AHB_CLK 0 +#define CAM_CC_CAM_TOP_FAST_AHB_CLK 1 +#define CAM_CC_CAMNOC_DCD_XO_CLK 2 +#define CAM_CC_CAMNOC_NRT_AXI_CLK 3 +#define CAM_CC_CAMNOC_NRT_CRE_CLK 4 +#define CAM_CC_CAMNOC_NRT_IPE_NPS_CLK 5 +#define CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK 6 +#define CAM_CC_CAMNOC_RT_AXI_CLK 7 +#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 8 +#define CAM_CC_CAMNOC_RT_IFE_LITE_CLK 9 +#define CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK 10 +#define CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK 11 +#define CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK 12 +#define CAM_CC_CAMNOC_XO_CLK 13 +#define CAM_CC_CCI_0_CLK 14 +#define CAM_CC_CCI_0_CLK_SRC 15 +#define CAM_CC_CCI_1_CLK 16 +#define CAM_CC_CCI_1_CLK_SRC 17 +#define CAM_CC_CCI_2_CLK 18 +#define CAM_CC_CCI_2_CLK_SRC 19 +#define CAM_CC_CORE_AHB_CLK 20 +#define CAM_CC_CPHY_RX_CLK_SRC 21 +#define CAM_CC_CRE_AHB_CLK 22 +#define CAM_CC_CRE_CLK 23 +#define CAM_CC_CRE_CLK_SRC 24 +#define CAM_CC_CSI0PHYTIMER_CLK 25 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 26 +#define CAM_CC_CSI1PHYTIMER_CLK 27 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 28 +#define CAM_CC_CSI2PHYTIMER_CLK 29 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 30 +#define CAM_CC_CSI3PHYTIMER_CLK 31 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 32 +#define CAM_CC_CSI4PHYTIMER_CLK 33 +#define CAM_CC_CSI4PHYTIMER_CLK_SRC 34 +#define CAM_CC_CSI5PHYTIMER_CLK 35 +#define CAM_CC_CSI5PHYTIMER_CLK_SRC 36 +#define CAM_CC_CSID_CLK 37 +#define CAM_CC_CSID_CLK_SRC 38 +#define CAM_CC_CSID_CSIPHY_RX_CLK 39 +#define CAM_CC_CSIPHY0_CLK 40 +#define CAM_CC_CSIPHY1_CLK 41 +#define CAM_CC_CSIPHY2_CLK 42 +#define CAM_CC_CSIPHY3_CLK 43 +#define CAM_CC_CSIPHY4_CLK 44 +#define CAM_CC_CSIPHY5_CLK 45 +#define CAM_CC_DRV_AHB_CLK 46 +#define CAM_CC_DRV_XO_CLK 47 +#define CAM_CC_FAST_AHB_CLK_SRC 48 +#define CAM_CC_GDSC_CLK 49 +#define CAM_CC_ICP_0_AHB_CLK 50 +#define CAM_CC_ICP_0_CLK 51 +#define CAM_CC_ICP_0_CLK_SRC 52 +#define CAM_CC_ICP_1_AHB_CLK 53 +#define CAM_CC_ICP_1_CLK 54 +#define CAM_CC_ICP_1_CLK_SRC 55 +#define CAM_CC_IFE_LITE_AHB_CLK 56 +#define CAM_CC_IFE_LITE_CLK 57 +#define CAM_CC_IFE_LITE_CLK_SRC 58 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 59 +#define CAM_CC_IFE_LITE_CSID_CLK 60 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 61 +#define CAM_CC_IPE_NPS_AHB_CLK 62 +#define CAM_CC_IPE_NPS_CLK 63 +#define CAM_CC_IPE_NPS_CLK_SRC 64 +#define CAM_CC_IPE_NPS_FAST_AHB_CLK 65 +#define CAM_CC_IPE_PPS_CLK 66 +#define CAM_CC_IPE_PPS_FAST_AHB_CLK 67 +#define CAM_CC_JPEG_CLK 68 +#define CAM_CC_JPEG_CLK_SRC 69 +#define CAM_CC_OFE_AHB_CLK 70 +#define CAM_CC_OFE_ANCHOR_CLK 71 +#define CAM_CC_OFE_ANCHOR_FAST_AHB_CLK 72 +#define CAM_CC_OFE_CLK_SRC 73 +#define CAM_CC_OFE_HDR_CLK 74 +#define CAM_CC_OFE_HDR_FAST_AHB_CLK 75 +#define CAM_CC_OFE_MAIN_CLK 76 +#define CAM_CC_OFE_MAIN_FAST_AHB_CLK 77 +#define CAM_CC_PLL0 78 +#define CAM_CC_PLL0_OUT_EVEN 79 +#define CAM_CC_PLL0_OUT_ODD 80 +#define CAM_CC_PLL1 81 +#define CAM_CC_PLL1_OUT_EVEN 82 +#define CAM_CC_PLL2 83 +#define CAM_CC_PLL2_OUT_EVEN 84 +#define CAM_CC_PLL3 85 +#define CAM_CC_PLL3_OUT_EVEN 86 +#define CAM_CC_PLL4 87 +#define CAM_CC_PLL4_OUT_EVEN 88 +#define CAM_CC_PLL5 89 +#define CAM_CC_PLL5_OUT_EVEN 90 +#define CAM_CC_PLL6 91 +#define CAM_CC_PLL6_OUT_EVEN 92 +#define CAM_CC_PLL6_OUT_ODD 93 +#define CAM_CC_PLL7 94 +#define CAM_CC_PLL7_OUT_EVEN 95 +#define CAM_CC_QDSS_DEBUG_CLK 96 +#define CAM_CC_QDSS_DEBUG_CLK_SRC 97 +#define CAM_CC_QDSS_DEBUG_XO_CLK 98 +#define CAM_CC_SLEEP_CLK 99 +#define CAM_CC_SLOW_AHB_CLK_SRC 100 +#define CAM_CC_TFE_0_BAYER_CLK 101 +#define CAM_CC_TFE_0_BAYER_FAST_AHB_CLK 102 +#define CAM_CC_TFE_0_CLK_SRC 103 +#define CAM_CC_TFE_0_MAIN_CLK 104 +#define CAM_CC_TFE_0_MAIN_FAST_AHB_CLK 105 +#define CAM_CC_TFE_1_BAYER_CLK 106 +#define CAM_CC_TFE_1_BAYER_FAST_AHB_CLK 107 +#define CAM_CC_TFE_1_CLK_SRC 108 +#define CAM_CC_TFE_1_MAIN_CLK 109 +#define CAM_CC_TFE_1_MAIN_FAST_AHB_CLK 110 +#define CAM_CC_TFE_2_BAYER_CLK 111 +#define CAM_CC_TFE_2_BAYER_FAST_AHB_CLK 112 +#define CAM_CC_TFE_2_CLK_SRC 113 +#define CAM_CC_TFE_2_MAIN_CLK 114 +#define CAM_CC_TFE_2_MAIN_FAST_AHB_CLK 115 +#define CAM_CC_TRACENOC_TPDM_1_CMB_CLK 116 +#define CAM_CC_XO_CLK_SRC 117 + +/* CAM_CC power domains */ +#define CAM_CC_IPE_0_GDSC 0 +#define CAM_CC_OFE_GDSC 1 +#define CAM_CC_TFE_0_GDSC 2 +#define CAM_CC_TFE_1_GDSC 3 +#define CAM_CC_TFE_2_GDSC 4 +#define CAM_CC_TITAN_TOP_GDSC 5 + +/* CAM_CC resets */ +#define CAM_CC_DRV_BCR 0 +#define CAM_CC_ICP_BCR 1 +#define CAM_CC_IPE_0_BCR 2 +#define CAM_CC_OFE_BCR 3 +#define CAM_CC_QDSS_DEBUG_BCR 4 +#define CAM_CC_TFE_0_BCR 5 +#define CAM_CC_TFE_1_BCR 6 +#define CAM_CC_TFE_2_BCR 7 + +#endif From e043131550c4e1f35bf959a35c30c223b6ff5602 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:09 +0530 Subject: [PATCH 064/165] dt-bindings: clock: qcom: Add Kaanapali video clock controller Add device tree bindings for the video clock controller on Qualcomm Kaanapali SoC. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Reviewed-by: Bryan O'Donoghue Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-6-8e10adc236a8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm8450-videocc.yaml | 3 + .../clock/qcom,kaanapali-videocc.h | 58 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,kaanapali-videocc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml index b31bd8335529..e6beebd6a36e 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml @@ -15,6 +15,7 @@ description: | domains on SM8450. See also: + include/dt-bindings/clock/qcom,kaanapali-videocc.h include/dt-bindings/clock/qcom,sm8450-videocc.h include/dt-bindings/clock/qcom,sm8650-videocc.h include/dt-bindings/clock/qcom,sm8750-videocc.h @@ -22,6 +23,7 @@ description: | properties: compatible: enum: + - qcom,kaanapali-videocc - qcom,sm8450-videocc - qcom,sm8475-videocc - qcom,sm8550-videocc @@ -61,6 +63,7 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-videocc - qcom,sm8450-videocc - qcom,sm8550-videocc - qcom,sm8750-videocc diff --git a/include/dt-bindings/clock/qcom,kaanapali-videocc.h b/include/dt-bindings/clock/qcom,kaanapali-videocc.h new file mode 100644 index 000000000000..cc0d41b895c9 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-videocc.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_KAANAPALI_H + +/* VIDEO_CC clocks */ +#define VIDEO_CC_AHB_CLK 0 +#define VIDEO_CC_AHB_CLK_SRC 1 +#define VIDEO_CC_MVS0_CLK 2 +#define VIDEO_CC_MVS0_CLK_SRC 3 +#define VIDEO_CC_MVS0_FREERUN_CLK 4 +#define VIDEO_CC_MVS0_SHIFT_CLK 5 +#define VIDEO_CC_MVS0_VPP0_CLK 6 +#define VIDEO_CC_MVS0_VPP0_FREERUN_CLK 7 +#define VIDEO_CC_MVS0_VPP1_CLK 8 +#define VIDEO_CC_MVS0_VPP1_FREERUN_CLK 9 +#define VIDEO_CC_MVS0A_CLK 10 +#define VIDEO_CC_MVS0A_CLK_SRC 11 +#define VIDEO_CC_MVS0A_FREERUN_CLK 12 +#define VIDEO_CC_MVS0B_CLK 13 +#define VIDEO_CC_MVS0B_CLK_SRC 14 +#define VIDEO_CC_MVS0B_FREERUN_CLK 15 +#define VIDEO_CC_MVS0C_CLK 16 +#define VIDEO_CC_MVS0C_CLK_SRC 17 +#define VIDEO_CC_MVS0C_FREERUN_CLK 18 +#define VIDEO_CC_MVS0C_SHIFT_CLK 19 +#define VIDEO_CC_PLL0 20 +#define VIDEO_CC_PLL1 21 +#define VIDEO_CC_PLL2 22 +#define VIDEO_CC_PLL3 23 +#define VIDEO_CC_SLEEP_CLK 24 +#define VIDEO_CC_TS_XO_CLK 25 +#define VIDEO_CC_XO_CLK 26 +#define VIDEO_CC_XO_CLK_SRC 27 + +/* VIDEO_CC power domains */ +#define VIDEO_CC_MVS0A_GDSC 0 +#define VIDEO_CC_MVS0_GDSC 1 +#define VIDEO_CC_MVS0_VPP1_GDSC 2 +#define VIDEO_CC_MVS0_VPP0_GDSC 3 +#define VIDEO_CC_MVS0C_GDSC 4 + +/* VIDEO_CC resets */ +#define VIDEO_CC_INTERFACE_BCR 0 +#define VIDEO_CC_MVS0_BCR 1 +#define VIDEO_CC_MVS0_VPP0_BCR 2 +#define VIDEO_CC_MVS0_VPP1_BCR 3 +#define VIDEO_CC_MVS0A_BCR 4 +#define VIDEO_CC_MVS0C_CLK_ARES 5 +#define VIDEO_CC_MVS0C_BCR 6 +#define VIDEO_CC_MVS0_FREERUN_CLK_ARES 7 +#define VIDEO_CC_MVS0C_FREERUN_CLK_ARES 8 +#define VIDEO_CC_XO_CLK_ARES 9 + +#endif From ecc3adefa72748845c63d32e97c56f65560f30ad Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:10 +0530 Subject: [PATCH 065/165] dt-bindings: clock: qcom: document the Kaanapali GPU Clock Controller Qualcomm GX(graphics) is a clock controller which has PLLs, clocks and Power domains (GDSC), but the requirement from the SW driver is to use the GDSC power domain from the clock controller to recover the GPU firmware in case of any failure/hangs. The rest of the resources of the clock controller are being used by the firmware of GPU. This module exposes the GDSC power domains which helps the recovery of Graphics subsystem. Add bindings documentation for the Kaanapali Graphics Clock and Graphics power domain Controller for Kaanapali SoC. Signed-off-by: Jingyi Wang Reviewed-by: Bryan O'Donoghue Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-7-8e10adc236a8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- .../clock/qcom,kaanapali-gxclkctl.yaml | 63 +++++++++++++++++++ .../bindings/clock/qcom,sm8450-gpucc.yaml | 2 + .../dt-bindings/clock/qcom,kaanapali-gpucc.h | 47 ++++++++++++++ .../clock/qcom,kaanapali-gxclkctl.h | 13 ++++ 4 files changed, 125 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml create mode 100644 include/dt-bindings/clock/qcom,kaanapali-gpucc.h create mode 100644 include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h diff --git a/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml new file mode 100644 index 000000000000..5490a975f3db --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,kaanapali-gxclkctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Graphics power domain Controller on Kaanapali + +maintainers: + - Taniya Das + +description: | + Qualcomm GX(graphics) is a clock controller which has PLLs, clocks and + Power domains (GDSC). This module provides the power domains control + of gxclkctl on Qualcomm SoCs which helps the recovery of Graphics subsystem. + + See also: + include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h + +properties: + compatible: + enum: + - qcom,kaanapali-gxclkctl + + power-domains: + description: + Power domains required for the clock controller to operate + items: + - description: GFX power domain + - description: GMXC power domain + - description: GPUCC(CX) power domain + + '#power-domain-cells': + const: 1 + + reg: + maxItems: 1 + +required: + - compatible + - reg + - power-domains + - '#power-domain-cells' + +unevaluatedProperties: false + +examples: + - | + #include + soc { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@3d64000 { + compatible = "qcom,kaanapali-gxclkctl"; + reg = <0x0 0x03d64000 0x0 0x6000>; + power-domains = <&rpmhpd RPMHPD_GFX>, + <&rpmhpd RPMHPD_GMXC>, + <&gpucc 0>; + #power-domain-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml index 44380f6f8136..6feaa32569f9 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml @@ -14,6 +14,7 @@ description: | domains on Qualcomm SoCs. See also:: + include/dt-bindings/clock/qcom,kaanapali-gpucc.h include/dt-bindings/clock/qcom,milos-gpucc.h include/dt-bindings/clock/qcom,sar2130p-gpucc.h include/dt-bindings/clock/qcom,sm4450-gpucc.h @@ -26,6 +27,7 @@ description: | properties: compatible: enum: + - qcom,kaanapali-gpucc - qcom,milos-gpucc - qcom,sar2130p-gpucc - qcom,sm4450-gpucc diff --git a/include/dt-bindings/clock/qcom,kaanapali-gpucc.h b/include/dt-bindings/clock/qcom,kaanapali-gpucc.h new file mode 100644 index 000000000000..e8dc2009c71b --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-gpucc.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_KAANAPALI_H + +/* GPU_CC clocks */ +#define GPU_CC_AHB_CLK 0 +#define GPU_CC_CB_CLK 1 +#define GPU_CC_CX_ACCU_SHIFT_CLK 2 +#define GPU_CC_CX_GMU_CLK 3 +#define GPU_CC_CXO_AON_CLK 4 +#define GPU_CC_CXO_CLK 5 +#define GPU_CC_DEMET_CLK 6 +#define GPU_CC_DPM_CLK 7 +#define GPU_CC_FF_CLK_SRC 8 +#define GPU_CC_FREQ_MEASURE_CLK 9 +#define GPU_CC_GMU_CLK_SRC 10 +#define GPU_CC_GPU_SMMU_VOTE_CLK 11 +#define GPU_CC_GX_ACCU_SHIFT_CLK 12 +#define GPU_CC_GX_GMU_CLK 13 +#define GPU_CC_HUB_AON_CLK 14 +#define GPU_CC_HUB_CLK_SRC 15 +#define GPU_CC_HUB_CX_INT_CLK 16 +#define GPU_CC_HUB_DIV_CLK_SRC 17 +#define GPU_CC_MEMNOC_GFX_CLK 18 +#define GPU_CC_PLL0 19 +#define GPU_CC_PLL0_OUT_EVEN 20 +#define GPU_CC_RSCC_HUB_AON_CLK 21 +#define GPU_CC_RSCC_XO_AON_CLK 22 +#define GPU_CC_SLEEP_CLK 23 + +/* GPU_CC power domains */ +#define GPU_CC_CX_GDSC 0 + +/* GPU_CC resets */ +#define GPU_CC_CB_BCR 0 +#define GPU_CC_CX_BCR 1 +#define GPU_CC_FAST_HUB_BCR 2 +#define GPU_CC_FF_BCR 3 +#define GPU_CC_GMU_BCR 4 +#define GPU_CC_GX_BCR 5 +#define GPU_CC_XO_BCR 6 + +#endif diff --git a/include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h b/include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h new file mode 100644 index 000000000000..f32dade67cf2 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h @@ -0,0 +1,13 @@ +/* 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_GX_CLKCTL_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_GX_CLKCTL_KAANAPALI_H + +/* GX_CLKCTL power domains */ +#define GX_CLKCTL_GX_GDSC 0 +#define GX_CLKCTL_GX_SLICE_GDSC 1 + +#endif From a419f7bfb714703b9c12fab387b60cb0e0f7ec47 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 2 Dec 2025 15:56:25 +0530 Subject: [PATCH 066/165] clk: qcom: clk-alpha-pll: Add support for controlling Rivian PLL Add clock ops for Rivian ELU and EKO_T PLLs, add the register offsets for the Rivian ELU PLL. Since ELU and EKO_T shared the same offsets and PLL ops, reuse the Rivian EKO_T enum. Signed-off-by: Jingyi Wang Reviewed-by: Konrad Dybcio Signed-off-by: Taniya Das Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-3-8e10adc236a8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-alpha-pll.c | 14 ++++++++++++++ drivers/clk/qcom/clk-alpha-pll.h | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 6aeba40358c1..8586649d76f8 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -243,6 +243,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL] = 0x28, [PLL_OFF_TEST_CTL_U] = 0x2c, }, + [CLK_ALPHA_PLL_TYPE_RIVIAN_ELU] = { + [PLL_OFF_OPMODE] = 0x04, + [PLL_OFF_STATUS] = 0x0c, + [PLL_OFF_L_VAL] = 0x10, + [PLL_OFF_USER_CTL] = 0x14, + [PLL_OFF_USER_CTL_U] = 0x18, + [PLL_OFF_CONFIG_CTL] = 0x1c, + [PLL_OFF_CONFIG_CTL_U] = 0x20, + [PLL_OFF_CONFIG_CTL_U1] = 0x24, + [PLL_OFF_CONFIG_CTL_U2] = 0x28, + [PLL_OFF_TEST_CTL] = 0x2c, + [PLL_OFF_TEST_CTL_U] = 0x30, + }, [CLK_ALPHA_PLL_TYPE_DEFAULT_EVO] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, @@ -3002,6 +3015,7 @@ void qcom_clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regm clk_taycan_elu_pll_configure(pll, regmap, pll->config); break; case CLK_ALPHA_PLL_TYPE_RIVIAN_EVO: + case CLK_ALPHA_PLL_TYPE_RIVIAN_ELU: clk_rivian_evo_pll_configure(pll, regmap, pll->config); break; case CLK_ALPHA_PLL_TYPE_TRION: diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 0903a05b18cc..046e6f2583ea 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -31,6 +31,8 @@ enum { CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T = CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, + CLK_ALPHA_PLL_TYPE_RIVIAN_ELU, + CLK_ALPHA_PLL_TYPE_RIVIAN_EKO_T = CLK_ALPHA_PLL_TYPE_RIVIAN_ELU, CLK_ALPHA_PLL_TYPE_DEFAULT_EVO, CLK_ALPHA_PLL_TYPE_BRAMMO_EVO, CLK_ALPHA_PLL_TYPE_STROMER, @@ -208,6 +210,8 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; extern const struct clk_ops clk_alpha_pll_pongo_elu_ops; extern const struct clk_ops clk_alpha_pll_rivian_evo_ops; #define clk_alpha_pll_postdiv_rivian_evo_ops clk_alpha_pll_postdiv_fabia_ops +#define clk_alpha_pll_rivian_elu_ops clk_alpha_pll_rivian_evo_ops +#define clk_alpha_pll_rivian_eko_t_ops clk_alpha_pll_rivian_evo_ops extern const struct clk_ops clk_alpha_pll_regera_ops; extern const struct clk_ops clk_alpha_pll_slew_ops; From f9580bafd39cff31bd51031e8784ea44acddf20e Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 2 Dec 2025 15:56:27 +0530 Subject: [PATCH 067/165] clk: qcom: camcc: Add camera clock controller driver for SM8750 SoC Add support for the Camera Clock Controller (CAMCC) on the SM8750 platform. The CAMCC block on SM8750 includes both the primary camera clock controller and the Camera BIST clock controller, which provides the functional MCLK required for camera operations. Signed-off-by: Taniya Das Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251202-sm8750_camcc-v1-3-b3f7ef6723f1@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 10 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/cambistmclkcc-sm8750.c | 454 ++++ drivers/clk/qcom/camcc-sm8750.c | 2710 +++++++++++++++++++++++ 4 files changed, 3175 insertions(+) create mode 100644 drivers/clk/qcom/cambistmclkcc-sm8750.c create mode 100644 drivers/clk/qcom/camcc-sm8750.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 4bbe942f0e96..7d43a1ab8a34 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1086,6 +1086,16 @@ config SM_CAMCC_8650 Support for the camera clock controller on SM8650 devices. Say Y if you want to support camera devices and camera functionality. +config SM_CAMCC_8750 + tristate "SM8750 Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select SM_GCC_8750 + help + Support for the camera clock controller on SM8750 devices. + The camera clock controller has a separate cambist controller which + controls the mclk of the camera clocks. + Say Y if you want to support camera devices and camera functionality. + config SM_DISPCC_4450 tristate "SM4450 Display Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 159f03287edd..b13497abe9d2 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -138,6 +138,7 @@ obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o obj-$(CONFIG_SM_CAMCC_8450) += camcc-sm8450.o obj-$(CONFIG_SM_CAMCC_8550) += camcc-sm8550.o obj-$(CONFIG_SM_CAMCC_8650) += camcc-sm8650.o +obj-$(CONFIG_SM_CAMCC_8750) += cambistmclkcc-sm8750.o camcc-sm8750.o obj-$(CONFIG_SM_CAMCC_MILOS) += camcc-milos.o obj-$(CONFIG_SM_DISPCC_4450) += dispcc-sm4450.o obj-$(CONFIG_SM_DISPCC_6115) += dispcc-sm6115.o diff --git a/drivers/clk/qcom/cambistmclkcc-sm8750.c b/drivers/clk/qcom/cambistmclkcc-sm8750.c new file mode 100644 index 000000000000..952581f86db5 --- /dev/null +++ b/drivers/clk/qcom/cambistmclkcc-sm8750.c @@ -0,0 +1,454 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "reset.h" + +enum { + DT_IFACE, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_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_elu_vco[] = { + { 833000000, 1125000000, 0 }, + { 777000000, 1062000000, 1 }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_bist_mclk_cc_pll0_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x12000000, + .config_ctl_hi_val = 0x00890263, + .config_ctl_hi1_val = 0x1af04237, + .config_ctl_hi2_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_bist_mclk_cc_pll0 = { + .offset = 0x0, + .config = &cam_bist_mclk_cc_pll0_config, + .vco_table = rivian_elu_vco, + .num_vco = ARRAY_SIZE(rivian_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_ELU], + .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_elu_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(12000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 8), + 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, + .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, + .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, + .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, + .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, + .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, + .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, + .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, + .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, + .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_sm8750_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_sm8750_plls[] = { + &cam_bist_mclk_cc_pll0, +}; + +static u32 cam_bist_mclk_cc_sm8750_critical_cbcrs[] = { + 0x40f8, /* CAM_BIST_MCLK_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_bist_mclk_cc_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x5010, + .fast_io = true, +}; + +static 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), +}; + +static struct qcom_cc_desc cam_bist_mclk_cc_sm8750_desc = { + .config = &cam_bist_mclk_cc_sm8750_regmap_config, + .clks = cam_bist_mclk_cc_sm8750_clocks, + .num_clks = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_clocks), + .use_rpm = true, + .driver_data = &cam_bist_mclk_cc_sm8750_driver_data, +}; + +static const struct of_device_id cam_bist_mclk_cc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-cambistmclkcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_bist_mclk_cc_sm8750_match_table); + +static int cam_bist_mclk_cc_sm8750_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_bist_mclk_cc_sm8750_desc); +} + +static struct platform_driver cam_bist_mclk_cc_sm8750_driver = { + .probe = cam_bist_mclk_cc_sm8750_probe, + .driver = { + .name = "cambistmclkcc-sm8750", + .of_match_table = cam_bist_mclk_cc_sm8750_match_table, + }, +}; + +module_platform_driver(cam_bist_mclk_cc_sm8750_driver); + +MODULE_DESCRIPTION("QTI CAMBISTMCLKCC SM8750 Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-sm8750.c b/drivers/clk/qcom/camcc-sm8750.c new file mode 100644 index 000000000000..c09fa75be457 --- /dev/null +++ b/drivers/clk/qcom/camcc-sm8750.c @@ -0,0 +1,2710 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_IFACE, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_BI_TCXO_AO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL0_OUT_MAIN, + P_CAM_CC_PLL0_OUT_ODD, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_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 taycan_elu_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .alpha = 0x8000, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .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_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .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_elu_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_ELU], + .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_elu_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_ELU], + .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_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x22, + .alpha = 0xa2aa, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .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_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .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_elu_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_ELU], + .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_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x23, + .alpha = 0x4aaa, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .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_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .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_elu_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_ELU], + .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_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x25, + .alpha = 0x8777, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .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_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .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_elu_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_ELU], + .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_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x25, + .alpha = 0x8777, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .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_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .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_elu_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_ELU], + .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_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll5_config = { + .l = 0x25, + .alpha = 0x8777, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .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_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .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_elu_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_ELU], + .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_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll6_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .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_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .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_elu_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_ELU], + .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_elu_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_ELU], + .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_elu_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_ao[] = { + { P_BI_TCXO_AO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_8_ao[] = { + { .index = DT_BI_TCXO_AO }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_rt_axi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 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, + .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, + .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, + .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, + .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(266666667, P_CAM_CC_PLL0_OUT_MAIN, 4.5, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { + .cmd_rcgr = 0x11068, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .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(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_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, + .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, + .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, + .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, + .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, + .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, + .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, + .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, + .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(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 = 0x100dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, + .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(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_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, + .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, + .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, + .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, + .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(332500000, 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 = 0x10190, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_ipe_nps_clk_src, + .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, + .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(338800000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(484000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(586000000, 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 = 0x1011c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ofe_clk_src, + .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(40000000, P_CAM_CC_PLL6_OUT_ODD, 8, 0, 0), + 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, + .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(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 = 0x10100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .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(360280000, 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(716000000, 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 = 0x11018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_tfe_0_clk_src, + .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(360280000, 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(716000000, 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 = 0x11098, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_6, + .freq_tbl = ftbl_cam_cc_tfe_1_clk_src, + .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(360280000, 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(716000000, 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 = 0x11100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_7, + .freq_tbl = ftbl_cam_cc_tfe_2_clk_src, + .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_AO, 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_ao, + .freq_tbl = ftbl_cam_cc_xo_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_xo_clk_src", + .parent_data = cam_cc_parent_data_8_ao, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_8_ao), + .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_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", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_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", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_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", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .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", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .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", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *cam_cc_sm8750_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_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_sm8750_gdscs[] = { + [CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc, + [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, +}; + +static const struct qcom_reset_map cam_cc_sm8750_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_sm8750_plls[] = { + &cam_cc_pll0, + &cam_cc_pll1, + &cam_cc_pll2, + &cam_cc_pll3, + &cam_cc_pll4, + &cam_cc_pll5, + &cam_cc_pll6, +}; + +static u32 cam_cc_sm8750_critical_cbcrs[] = { + 0x113c4, /* CAM_CC_DRV_AHB_CLK */ + 0x113c0, /* CAM_CC_DRV_XO_CLK */ + 0x1137c, /* CAM_CC_GDSC_CLK */ + 0x11398, /* CAM_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_cc_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1601c, + .fast_io = true, +}; + +static struct qcom_cc_driver_data cam_cc_sm8750_driver_data = { + .alpha_plls = cam_cc_sm8750_plls, + .num_alpha_plls = ARRAY_SIZE(cam_cc_sm8750_plls), + .clk_cbcrs = cam_cc_sm8750_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_sm8750_critical_cbcrs), +}; + +static struct qcom_cc_desc cam_cc_sm8750_desc = { + .config = &cam_cc_sm8750_regmap_config, + .clks = cam_cc_sm8750_clocks, + .num_clks = ARRAY_SIZE(cam_cc_sm8750_clocks), + .resets = cam_cc_sm8750_resets, + .num_resets = ARRAY_SIZE(cam_cc_sm8750_resets), + .gdscs = cam_cc_sm8750_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_sm8750_gdscs), + .use_rpm = true, + .driver_data = &cam_cc_sm8750_driver_data, +}; + +static const struct of_device_id cam_cc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_sm8750_match_table); + +static int cam_cc_sm8750_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_cc_sm8750_desc); +} + +static struct platform_driver cam_cc_sm8750_driver = { + .probe = cam_cc_sm8750_probe, + .driver = { + .name = "camcc-sm8750", + .of_match_table = cam_cc_sm8750_match_table, + }, +}; + +module_platform_driver(cam_cc_sm8750_driver); + +MODULE_DESCRIPTION("QTI CAMCC SM8750 Driver"); +MODULE_LICENSE("GPL"); From 0f85ef379064b50ad573c6af4c0ffd39673f6968 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:04 +0530 Subject: [PATCH 068/165] clk: qcom: clk-alpha-pll: Update the PLL support for cal_l Recent QCOM PLLs require the CAL_L field to be programmed according to specific hardware recommendations, rather than using the legacy default value of 0x44. Hardcoding this value can lead to suboptimal or incorrect behavior on newer platforms. To address this, introduce a `cal_l` field in the PLL configuration structure, allowing CAL_L to be set explicitly based on platform requirements. This improves flexibility and ensures correct PLL initialization across different hardware variants. Signed-off-by: Jingyi Wang Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-1-8e10adc236a8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-alpha-pll.c | 6 +++++- drivers/clk/qcom/clk-alpha-pll.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 8586649d76f8..3fbdee6e67f9 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -2351,7 +2351,11 @@ void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regma return; } - lval |= TRION_PLL_CAL_VAL << LUCID_EVO_PLL_CAL_L_VAL_SHIFT; + if (config->cal_l) + lval |= config->cal_l << LUCID_EVO_PLL_CAL_L_VAL_SHIFT; + else + lval |= TRION_PLL_CAL_VAL << LUCID_EVO_PLL_CAL_L_VAL_SHIFT; + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), lval); clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 046e6f2583ea..a211119a5fc1 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -130,6 +130,7 @@ struct clk_alpha_pll_postdiv { struct alpha_pll_config { u32 l; + u32 cal_l; u32 alpha; u32 alpha_hi; u32 config_ctl_val; From 6d3e77facbce8e684321d9ba65137a76f2575372 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:05 +0530 Subject: [PATCH 069/165] clk: qcom: clk-alpha-pll: Add support for controlling Pongo EKO_T PLL Add clock ops for Pongo EKO_T PLL, add the pll ops for supporting the PLL. Signed-off-by: Jingyi Wang Reviewed-by: Konrad Dybcio Signed-off-by: Taniya Das Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-2-8e10adc236a8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-alpha-pll.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index a211119a5fc1..42d334492145 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -28,6 +28,7 @@ enum { CLK_ALPHA_PLL_TYPE_LUCID_EVO, CLK_ALPHA_PLL_TYPE_LUCID_OLE, CLK_ALPHA_PLL_TYPE_PONGO_ELU, + CLK_ALPHA_PLL_TYPE_PONGO_EKO_T = CLK_ALPHA_PLL_TYPE_PONGO_ELU, CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T = CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, @@ -209,6 +210,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; #define clk_alpha_pll_postdiv_taycan_eko_t_ops clk_alpha_pll_postdiv_lucid_evo_ops extern const struct clk_ops clk_alpha_pll_pongo_elu_ops; +#define clk_alpha_pll_pongo_eko_t_ops clk_alpha_pll_pongo_elu_ops extern const struct clk_ops clk_alpha_pll_rivian_evo_ops; #define clk_alpha_pll_postdiv_rivian_evo_ops clk_alpha_pll_postdiv_fabia_ops #define clk_alpha_pll_rivian_elu_ops clk_alpha_pll_rivian_evo_ops From 6c6750b7061ca5b12deaeb246439b5b64a84f9c1 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:11 +0530 Subject: [PATCH 070/165] clk: qcom: dispcc: Add support for display clock controller Kaanapali Support the clock controller driver for Kaanapali to enable display SW to be able to control the clocks. Reviewed-by: Konrad Dybcio Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-8-8e10adc236a8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 10 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/dispcc-kaanapali.c | 1956 +++++++++++++++++++++++++++ 3 files changed, 1967 insertions(+) create mode 100644 drivers/clk/qcom/dispcc-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 7d43a1ab8a34..2c6da95a423f 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -46,6 +46,16 @@ config CLK_GLYMUR_TCSRCC Support for the TCSR clock controller on GLYMUR devices. Say Y if you want to use peripheral devices such as USB/PCIe/EDP. +config CLK_KAANAPALI_DISPCC + tristate "Kaanapali Display Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the display clock controller on Qualcomm Technologies, Inc + Kaanapali devices. + Say Y if you want to support display devices and functionality such as + splash screen. + config CLK_KAANAPALI_GCC tristate "Kaanapali Global Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index b13497abe9d2..49b21aa7579f 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o obj-$(CONFIG_CLK_GLYMUR_DISPCC) += dispcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_GCC) += gcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-glymur.o +obj-$(CONFIG_CLK_KAANAPALI_DISPCC) += dispcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o diff --git a/drivers/clk/qcom/dispcc-kaanapali.c b/drivers/clk/qcom/dispcc-kaanapali.c new file mode 100644 index 000000000000..baae2ec1f72a --- /dev/null +++ b/drivers/clk/qcom/dispcc-kaanapali.c @@ -0,0 +1,1956 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +#define DISP_CC_MISC_CMD 0xF000 + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_AHB_CLK, + DT_SLEEP_CLK, + DT_DP0_PHY_PLL_LINK_CLK, + DT_DP0_PHY_PLL_VCO_DIV_CLK, + DT_DP1_PHY_PLL_LINK_CLK, + DT_DP1_PHY_PLL_VCO_DIV_CLK, + DT_DP2_PHY_PLL_LINK_CLK, + DT_DP2_PHY_PLL_VCO_DIV_CLK, + DT_DP3_PHY_PLL_LINK_CLK, + DT_DP3_PHY_PLL_VCO_DIV_CLK, + DT_DSI0_PHY_PLL_OUT_BYTECLK, + DT_DSI0_PHY_PLL_OUT_DSICLK, + DT_DSI1_PHY_PLL_OUT_BYTECLK, + DT_DSI1_PHY_PLL_OUT_DSICLK, +}; + +enum { + P_BI_TCXO, + P_DISP_CC_PLL0_OUT_MAIN, + P_DISP_CC_PLL1_OUT_EVEN, + P_DISP_CC_PLL1_OUT_MAIN, + P_DISP_CC_PLL2_OUT_MAIN, + P_DP0_PHY_PLL_LINK_CLK, + P_DP0_PHY_PLL_VCO_DIV_CLK, + P_DP1_PHY_PLL_LINK_CLK, + P_DP1_PHY_PLL_VCO_DIV_CLK, + P_DP2_PHY_PLL_LINK_CLK, + P_DP2_PHY_PLL_VCO_DIV_CLK, + P_DP3_PHY_PLL_LINK_CLK, + P_DP3_PHY_PLL_VCO_DIV_CLK, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_DSI1_PHY_PLL_OUT_BYTECLK, + P_DSI1_PHY_PLL_OUT_DSICLK, +}; + +static const struct pll_vco pongo_eko_t_vco[] = { + { 38400000, 153600000, 0 }, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 257.142858 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll0_config = { + .l = 0xd, + .cal_l = 0x48, + .alpha = 0x6492, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll disp_cc_pll0 = { + .offset = 0x0, + .config = &disp_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 300.0 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll1_config = { + .l = 0xf, + .cal_l = 0x48, + .alpha = 0xa000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll disp_cc_pll1 = { + .offset = 0x1000, + .config = &disp_cc_pll1_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 38.4 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll2_config = { + .l = 0x493, + .cal_l = 0x493, + .alpha = 0x0, + .config_ctl_val = 0x60000f68, + .config_ctl_hi_val = 0x0001c808, + .config_ctl_hi1_val = 0x00000000, + .config_ctl_hi2_val = 0x040082f4, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x0080c496, + .test_ctl_hi1_val = 0x40100080, + .test_ctl_hi2_val = 0x001001bc, + .test_ctl_hi3_val = 0x002003d8, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00e50302, +}; + +static struct clk_alpha_pll disp_cc_pll2 = { + .offset = 0x2000, + .config = &disp_cc_pll2_config, + .vco_table = pongo_eko_t_vco, + .num_vco = ARRAY_SIZE(pongo_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_PONGO_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_SLEEP_CLK, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_pongo_eko_t_ops, + }, + }, +}; + +static const struct parent_map disp_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map disp_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 3 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 }, + { P_DP1_PHY_PLL_VCO_DIV_CLK, 4 }, + { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP1_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_DP1_PHY_PLL_LINK_CLK, 2 }, + { P_DP2_PHY_PLL_LINK_CLK, 3 }, + { P_DP3_PHY_PLL_LINK_CLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP1_PHY_PLL_LINK_CLK }, + { .index = DT_DP2_PHY_PLL_LINK_CLK }, + { .index = DT_DP3_PHY_PLL_LINK_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DISP_CC_PLL2_OUT_MAIN, 2 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 3 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .hw = &disp_cc_pll2.clkr.hw }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, +}; + +static const struct parent_map disp_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_DP0_PHY_PLL_LINK_CLK, 1 }, + { P_DP0_PHY_PLL_VCO_DIV_CLK, 2 }, + { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 }, + { P_DP1_PHY_PLL_VCO_DIV_CLK, 4 }, + { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP0_PHY_PLL_LINK_CLK }, + { .index = DT_DP0_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP1_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll1.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_DP0_PHY_PLL_LINK_CLK, 1 }, + { P_DP1_PHY_PLL_LINK_CLK, 2 }, + { P_DP2_PHY_PLL_LINK_CLK, 3 }, + { P_DP3_PHY_PLL_LINK_CLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP0_PHY_PLL_LINK_CLK }, + { .index = DT_DP1_PHY_PLL_LINK_CLK }, + { .index = DT_DP2_PHY_PLL_LINK_CLK }, + { .index = DT_DP3_PHY_PLL_LINK_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_9[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL0_OUT_MAIN, 1 }, + { P_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_9[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll0.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_parent_map_10[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL2_OUT_MAIN, 2 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_10[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll2.clkr.hw }, +}; + +static const struct freq_tbl ftbl_disp_cc_esync0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_esync0_clk_src = { + .cmd_rcgr = 0x80d4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync0_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_esync1_clk_src = { + .cmd_rcgr = 0x80ec, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync1_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(120000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(165000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(200000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(233333333, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(261666667, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(283333333, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { + .cmd_rcgr = 0x8378, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_7, + .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_clk_src", + .parent_data = disp_cc_parent_data_7, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { + .cmd_rcgr = 0x8194, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = { + .cmd_rcgr = 0x81b0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_aux_clk_src = { + .cmd_rcgr = 0x8248, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = { + .cmd_rcgr = 0x81fc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_8, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_clk_src", + .parent_data = disp_cc_parent_data_8, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_pixel0_clk_src = { + .cmd_rcgr = 0x8218, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_5, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel0_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_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_pixel1_clk_src = { + .cmd_rcgr = 0x8230, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_5, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel1_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_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_aux_clk_src = { + .cmd_rcgr = 0x82ac, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_link_clk_src = { + .cmd_rcgr = 0x8290, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_pixel0_clk_src = { + .cmd_rcgr = 0x8260, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_pixel1_clk_src = { + .cmd_rcgr = 0x8278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel1_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_aux_clk_src = { + .cmd_rcgr = 0x8310, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_link_clk_src = { + .cmd_rcgr = 0x82c4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_pixel0_clk_src = { + .cmd_rcgr = 0x82e0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_pixel1_clk_src = { + .cmd_rcgr = 0x82f8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel1_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_aux_clk_src = { + .cmd_rcgr = 0x835c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_link_clk_src = { + .cmd_rcgr = 0x8340, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_pixel0_clk_src = { + .cmd_rcgr = 0x8328, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_pixel0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { + .cmd_rcgr = 0x81cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_6, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc0_clk_src", + .parent_data = disp_cc_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { + .cmd_rcgr = 0x81e4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_6, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc1_clk_src", + .parent_data = disp_cc_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(85714286, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(100000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(156000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(207000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(337000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(417000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(532000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(600000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(650000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { + .cmd_rcgr = 0x8164, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_9, + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_clk_src", + .parent_data = disp_cc_parent_data_9, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { + .cmd_rcgr = 0x811c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk0_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { + .cmd_rcgr = 0x8134, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk1_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk2_clk_src = { + .cmd_rcgr = 0x814c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk2_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { + .cmd_rcgr = 0x817c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_osc_clk_src[] = { + F(38400000, P_DISP_CC_PLL2_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_osc_clk_src = { + .cmd_rcgr = 0x8104, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_10, + .freq_tbl = ftbl_disp_cc_osc_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_osc_clk_src", + .parent_data = disp_cc_parent_data_10, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_10), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_ahb_swi_div_clk_src = { + .reg = 0x8374, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_swi_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { + .reg = 0x81ac, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = { + .reg = 0x81c8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx0_link_div_clk_src = { + .reg = 0x8214, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx1_link_div_clk_src = { + .reg = 0x82a8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx2_link_div_clk_src = { + .reg = 0x82dc, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx3_link_div_clk_src = { + .reg = 0x8358, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch disp_cc_esync0_clk = { + .halt_reg = 0x80cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_esync0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_esync1_clk = { + .halt_reg = 0x80d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_esync1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_accu_shift_clk = { + .halt_reg = 0xe060, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xe060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb1_clk = { + .halt_reg = 0xa028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb_clk = { + .halt_reg = 0x80c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb_swi_clk = { + .halt_reg = 0x80c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_swi_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_swi_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_clk = { + .halt_reg = 0x8044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_intf_clk = { + .halt_reg = 0x8048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte1_clk = { + .halt_reg = 0x804c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte1_intf_clk = { + .halt_reg = 0x8050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_aux_clk = { + .halt_reg = 0x8074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_crypto_clk = { + .halt_reg = 0x8068, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_link_clk = { + .halt_reg = 0x805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_link_intf_clk = { + .halt_reg = 0x8064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_pixel0_clk = { + .halt_reg = 0x806c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x806c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_pixel1_clk = { + .halt_reg = 0x8070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_usb_router_link_intf_clk = { + .halt_reg = 0x8060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_aux_clk = { + .halt_reg = 0x8090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_crypto_clk = { + .halt_reg = 0x808c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x808c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_link_clk = { + .halt_reg = 0x8080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_link_intf_clk = { + .halt_reg = 0x8088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_pixel0_clk = { + .halt_reg = 0x8078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_pixel1_clk = { + .halt_reg = 0x807c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x807c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_usb_router_link_intf_clk = { + .halt_reg = 0x8084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8084, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_aux_clk = { + .halt_reg = 0x80a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_crypto_clk = { + .halt_reg = 0x80a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x80a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_link_clk = { + .halt_reg = 0x809c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x809c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_link_intf_clk = { + .halt_reg = 0x80a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_pixel0_clk = { + .halt_reg = 0x8094, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8094, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_pixel1_clk = { + .halt_reg = 0x8098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8098, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_aux_clk = { + .halt_reg = 0x80b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_crypto_clk = { + .halt_reg = 0x80bc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x80bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_link_clk = { + .halt_reg = 0x80b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_link_intf_clk = { + .halt_reg = 0x80b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_pixel0_clk = { + .halt_reg = 0x80ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_esc0_clk = { + .halt_reg = 0x8054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_esc0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_esc1_clk = { + .halt_reg = 0x8058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_esc1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp1_clk = { + .halt_reg = 0xa004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_clk = { + .halt_reg = 0x8010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_lut1_clk = { + .halt_reg = 0xa014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xa014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_lut1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_lut_clk = { + .halt_reg = 0x8020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_lut_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_ss_ip_clk = { + .halt_reg = 0x8030, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_ss_ip_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { + .halt_reg = 0xc004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xc004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_non_gdsc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk0_clk = { + .halt_reg = 0x8004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk1_clk = { + .halt_reg = 0x8008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk2_clk = { + .halt_reg = 0x800c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x800c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_vsync1_clk = { + .halt_reg = 0xa024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_vsync_clk = { + .halt_reg = 0x8040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_osc_clk = { + .halt_reg = 0x80c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_osc_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_osc_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc disp_cc_mdss_core_gdsc = { + .gdscr = 0x9000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "disp_cc_mdss_core_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +static struct gdsc disp_cc_mdss_core_int2_gdsc = { + .gdscr = 0xb000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "disp_cc_mdss_core_int2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +static struct clk_regmap *disp_cc_kaanapali_clocks[] = { + [DISP_CC_ESYNC0_CLK] = &disp_cc_esync0_clk.clkr, + [DISP_CC_ESYNC0_CLK_SRC] = &disp_cc_esync0_clk_src.clkr, + [DISP_CC_ESYNC1_CLK] = &disp_cc_esync1_clk.clkr, + [DISP_CC_ESYNC1_CLK_SRC] = &disp_cc_esync1_clk_src.clkr, + [DISP_CC_MDSS_ACCU_SHIFT_CLK] = &disp_cc_mdss_accu_shift_clk.clkr, + [DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr, + [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, + [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, + [DISP_CC_MDSS_AHB_SWI_CLK] = &disp_cc_mdss_ahb_swi_clk.clkr, + [DISP_CC_MDSS_AHB_SWI_DIV_CLK_SRC] = &disp_cc_mdss_ahb_swi_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, + [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, + [DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr, + [DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr, + [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = &disp_cc_mdss_byte1_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr, + [DISP_CC_MDSS_DPTX0_AUX_CLK] = &disp_cc_mdss_dptx0_aux_clk.clkr, + [DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &disp_cc_mdss_dptx0_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_CRYPTO_CLK] = &disp_cc_mdss_dptx0_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX0_LINK_CLK] = &disp_cc_mdss_dptx0_link_clk.clkr, + [DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &disp_cc_mdss_dptx0_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx0_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &disp_cc_mdss_dptx0_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &disp_cc_mdss_dptx0_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx0_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &disp_cc_mdss_dptx0_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx0_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] = + &disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX1_AUX_CLK] = &disp_cc_mdss_dptx1_aux_clk.clkr, + [DISP_CC_MDSS_DPTX1_AUX_CLK_SRC] = &disp_cc_mdss_dptx1_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_CRYPTO_CLK] = &disp_cc_mdss_dptx1_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX1_LINK_CLK] = &disp_cc_mdss_dptx1_link_clk.clkr, + [DISP_CC_MDSS_DPTX1_LINK_CLK_SRC] = &disp_cc_mdss_dptx1_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx1_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_LINK_INTF_CLK] = &disp_cc_mdss_dptx1_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL0_CLK] = &disp_cc_mdss_dptx1_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx1_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL1_CLK] = &disp_cc_mdss_dptx1_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx1_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK] = + &disp_cc_mdss_dptx1_usb_router_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX2_AUX_CLK] = &disp_cc_mdss_dptx2_aux_clk.clkr, + [DISP_CC_MDSS_DPTX2_AUX_CLK_SRC] = &disp_cc_mdss_dptx2_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_CRYPTO_CLK] = &disp_cc_mdss_dptx2_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX2_LINK_CLK] = &disp_cc_mdss_dptx2_link_clk.clkr, + [DISP_CC_MDSS_DPTX2_LINK_CLK_SRC] = &disp_cc_mdss_dptx2_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx2_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_LINK_INTF_CLK] = &disp_cc_mdss_dptx2_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL0_CLK] = &disp_cc_mdss_dptx2_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx2_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL1_CLK] = &disp_cc_mdss_dptx2_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx2_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_AUX_CLK] = &disp_cc_mdss_dptx3_aux_clk.clkr, + [DISP_CC_MDSS_DPTX3_AUX_CLK_SRC] = &disp_cc_mdss_dptx3_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_CRYPTO_CLK] = &disp_cc_mdss_dptx3_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX3_LINK_CLK] = &disp_cc_mdss_dptx3_link_clk.clkr, + [DISP_CC_MDSS_DPTX3_LINK_CLK_SRC] = &disp_cc_mdss_dptx3_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx3_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_LINK_INTF_CLK] = &disp_cc_mdss_dptx3_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX3_PIXEL0_CLK] = &disp_cc_mdss_dptx3_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx3_pixel0_clk_src.clkr, + [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, + [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, + [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr, + [DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr, + [DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr, + [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, + [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, + [DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr, + [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, + [DISP_CC_MDSS_MDP_SS_IP_CLK] = &disp_cc_mdss_mdp_ss_ip_clk.clkr, + [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, + [DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr, + [DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr, + [DISP_CC_MDSS_PCLK2_CLK] = &disp_cc_mdss_pclk2_clk.clkr, + [DISP_CC_MDSS_PCLK2_CLK_SRC] = &disp_cc_mdss_pclk2_clk_src.clkr, + [DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, + [DISP_CC_OSC_CLK] = &disp_cc_osc_clk.clkr, + [DISP_CC_OSC_CLK_SRC] = &disp_cc_osc_clk_src.clkr, + [DISP_CC_PLL0] = &disp_cc_pll0.clkr, + [DISP_CC_PLL1] = &disp_cc_pll1.clkr, + [DISP_CC_PLL2] = &disp_cc_pll2.clkr, +}; + +static struct gdsc *disp_cc_kaanapali_gdscs[] = { + [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc, + [DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc, +}; + +static const struct qcom_reset_map disp_cc_kaanapali_resets[] = { + [DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, + [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, + [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, +}; + +static struct clk_alpha_pll *disp_cc_kaanapali_plls[] = { + &disp_cc_pll0, + &disp_cc_pll1, + &disp_cc_pll2, +}; + +static u32 disp_cc_kaanapali_critical_cbcrs[] = { + 0xe064, /* 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 regmap_config disp_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x12094, + .fast_io = true, +}; + +static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Enable clock gating for MDP clocks */ + regmap_update_bits(regmap, DISP_CC_MISC_CMD, BIT(4), BIT(4)); +} + +static struct qcom_cc_driver_data disp_cc_kaanapali_driver_data = { + .alpha_plls = disp_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(disp_cc_kaanapali_plls), + .clk_cbcrs = disp_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_kaanapali_critical_cbcrs), + .clk_regs_configure = clk_kaanapali_regs_configure, +}; + +static const struct qcom_cc_desc disp_cc_kaanapali_desc = { + .config = &disp_cc_kaanapali_regmap_config, + .clks = disp_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(disp_cc_kaanapali_clocks), + .resets = disp_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(disp_cc_kaanapali_resets), + .gdscs = disp_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(disp_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &disp_cc_kaanapali_driver_data, +}; + +static const struct of_device_id disp_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-dispcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, disp_cc_kaanapali_match_table); + +static int disp_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &disp_cc_kaanapali_desc); +} + +static struct platform_driver disp_cc_kaanapali_driver = { + .probe = disp_cc_kaanapali_probe, + .driver = { + .name = "dispcc-kaanapali", + .of_match_table = disp_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(disp_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI DISPCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); From 92aae35f667cd62359f5938e3259dc72e080e28c Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:12 +0530 Subject: [PATCH 071/165] clk: qcom: camcc: Add support for camera clock controller for Kaanapali Add support for the Camera Clock Controller (CAMCC) on the Kaanapali platform. The CAMCC block on Kaanapali includes both the primary camera clock controller and the Camera BIST clock controller, which provides the functional MCLK required for camera operations. Signed-off-by: Jingyi Wang Reviewed-by: Bryan O'Donoghue Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-9-8e10adc236a8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 10 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/cambistmclkcc-kaanapali.c | 437 ++++ drivers/clk/qcom/camcc-kaanapali.c | 2661 ++++++++++++++++++++ 4 files changed, 3109 insertions(+) create mode 100644 drivers/clk/qcom/cambistmclkcc-kaanapali.c create mode 100644 drivers/clk/qcom/camcc-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 2c6da95a423f..34491b4ac913 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -46,6 +46,16 @@ config CLK_GLYMUR_TCSRCC Support for the TCSR clock controller on GLYMUR devices. Say Y if you want to use peripheral devices such as USB/PCIe/EDP. +config CLK_KAANAPALI_CAMCC + tristate "Kaanapali Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the camera clock controller on Qualcomm Technologies, Inc + Kaanapali devices. + Say Y if you want to support camera devices and functionality such as + capturing pictures. + config CLK_KAANAPALI_DISPCC tristate "Kaanapali Display Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 49b21aa7579f..8b214cb192da 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o obj-$(CONFIG_CLK_GLYMUR_DISPCC) += dispcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_GCC) += gcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-glymur.o +obj-$(CONFIG_CLK_KAANAPALI_CAMCC) += cambistmclkcc-kaanapali.o camcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_DISPCC) += dispcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o diff --git a/drivers/clk/qcom/cambistmclkcc-kaanapali.c b/drivers/clk/qcom/cambistmclkcc-kaanapali.c new file mode 100644 index 000000000000..066c1087b0b6 --- /dev/null +++ b/drivers/clk/qcom/cambistmclkcc-kaanapali.c @@ -0,0 +1,437 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_AHB_CLK, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, + P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, +}; + +static const struct pll_vco rivian_eko_t_vco[] = { + { 883200000, 1171200000, 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 = 0x12000000, + .config_ctl_hi_val = 0x00890263, + .config_ctl_hi1_val = 0x1af04237, + .config_ctl_hi2_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_bist_mclk_cc_pll0 = { + .offset = 0x0, + .config = &cam_bist_mclk_cc_pll0_config, + .vco_table = rivian_eko_t_vco, + .num_vco = ARRAY_SIZE(rivian_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_rivian_eko_t_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 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, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .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, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .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, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .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, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .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, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .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, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .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, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .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, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .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 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_kaanapali_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, +}; + +static struct clk_alpha_pll *cam_bist_mclk_cc_kaanapali_plls[] = { + &cam_bist_mclk_cc_pll0, +}; + +static u32 cam_bist_mclk_cc_kaanapali_critical_cbcrs[] = { + 0x40e0, /* CAM_BIST_MCLK_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_bist_mclk_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x5010, + .fast_io = true, +}; + +static 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), +}; + +static const struct qcom_cc_desc cam_bist_mclk_cc_kaanapali_desc = { + .config = &cam_bist_mclk_cc_kaanapali_regmap_config, + .clks = cam_bist_mclk_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(cam_bist_mclk_cc_kaanapali_clocks), + .use_rpm = true, + .driver_data = &cam_bist_mclk_cc_kaanapali_driver_data, +}; + +static const struct of_device_id cam_bist_mclk_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-cambistmclkcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_bist_mclk_cc_kaanapali_match_table); + +static int cam_bist_mclk_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_bist_mclk_cc_kaanapali_desc); +} + +static struct platform_driver cam_bist_mclk_cc_kaanapali_driver = { + .probe = cam_bist_mclk_cc_kaanapali_probe, + .driver = { + .name = "cambistmclkcc-kaanapali", + .of_match_table = cam_bist_mclk_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(cam_bist_mclk_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI CAMBISTMCLKCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-kaanapali.c b/drivers/clk/qcom/camcc-kaanapali.c new file mode 100644 index 000000000000..82967993fcff --- /dev/null +++ b/drivers/clk/qcom/camcc-kaanapali.c @@ -0,0 +1,2661 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_AHB_CLK, + 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_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_CAM_CC_PLL7_OUT_EVEN, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 1200.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .cal_l = 0x48, + .alpha = 0x8000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00008408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .config = &cam_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_odd = { + .offset = 0x0, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll0_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 665.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x22, + .cal_l = 0x48, + .alpha = 0xa2aa, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .config = &cam_cc_pll1_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll1_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll1_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll1_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll1.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 677.6 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x23, + .cal_l = 0x48, + .alpha = 0x4aaa, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .config = &cam_cc_pll2_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_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_EKO_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_eko_t_ops, + }, +}; + +/* 720.56 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x25, + .cal_l = 0x48, + .alpha = 0x8777, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .config = &cam_cc_pll3_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll3_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = { + .offset = 0x3000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll3_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll3_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll3.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 720.56 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x25, + .cal_l = 0x48, + .alpha = 0x8777, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll4 = { + .offset = 0x4000, + .config = &cam_cc_pll4_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll4_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll4_out_even = { + .offset = 0x4000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll4_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll4_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll4_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll4.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 720.56 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll5_config = { + .l = 0x25, + .cal_l = 0x48, + .alpha = 0x8777, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll5 = { + .offset = 0x5000, + .config = &cam_cc_pll5_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll5", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll5_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll5_out_even = { + .offset = 0x5000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll5_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll5_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll5_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll5.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll6_config = { + .l = 0x32, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00008408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll6 = { + .offset = 0x6000, + .config = &cam_cc_pll6_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_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_EKO_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_eko_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_EKO_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_eko_t_ops, + }, +}; + +/* 1000.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll7_config = { + .l = 0x34, + .cal_l = 0x48, + .alpha = 0x1555, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll7 = { + .offset = 0x7000, + .config = &cam_cc_pll7_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll7", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll7_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll7_out_even = { + .offset = 0x7000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll7_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll7_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll7_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll7.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_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_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL7_OUT_EVEN, 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_out_even.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_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(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 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_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(266666667, P_CAM_CC_PLL0_OUT_MAIN, 4.5, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { + .cmd_rcgr = 0x21064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .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(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_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 = 0x211a0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .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, + .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, + .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, + .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, + .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, + .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, + .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, + .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(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, + .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(500000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(740000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(875000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(1000000000, P_CAM_CC_PLL7_OUT_EVEN, 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, + .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, + .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 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_cphy_rx_clk_src, + .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, + .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(332500000, 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 = 0x20188, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ipe_nps_clk_src, + .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, + .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(338800000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(484000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(586000000, 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 = 0x2011c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_4, + .freq_tbl = ftbl_cam_cc_ofe_clk_src, + .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_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 = 0x21314, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_qdss_debug_clk_src, + .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 = 0x20100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .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_tfe_0_clk_src[] = { + F(360280000, 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(716000000, 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_5, + .freq_tbl = ftbl_cam_cc_tfe_0_clk_src, + .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(360280000, 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(716000000, 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_6, + .freq_tbl = ftbl_cam_cc_tfe_1_clk_src, + .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(360280000, 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(716000000, 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_7, + .freq_tbl = ftbl_cam_cc_tfe_2_clk_src, + .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 = 0x2134c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_8, + .freq_tbl = ftbl_cam_cc_xo_clk_src, + .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_ops, + }, +}; + +static struct clk_branch cam_cc_cam_top_ahb_clk = { + .halt_reg = 0x2137c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2137c, + .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 = 0x2136c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2136c, + .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 = 0x201b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201b0, + .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_main_clk = { + .halt_reg = 0x20144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20144, + .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 = 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_camnoc_xo_clk = { + .halt_reg = 0x2130c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2130c, + .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 = 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 = 0x21348, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x21348, + .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 = 0x201cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201cc, + .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 = 0x201a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201a0, + .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 = 0x201d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201d0, + .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 = 0x201b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201b4, + .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 = 0x201d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_pps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_jpeg_clk = { + .halt_reg = 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 = 0x20118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20118, + .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 = 0x20148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20148, + .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 = 0x20158, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20158, + .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 = 0x20134, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20134, + .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_qdss_debug_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_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 = 0x21330, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21330, + .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 = 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_tracenoc_tpdm_1_cmb_clk = { + .halt_reg = 0x21394, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21394, + .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_gdsc = { + .gdscr = 0x21334, + .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 = 0x20174, + .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 = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +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 = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, + .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_kaanapali_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_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_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_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_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_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_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_PLL7_OUT_EVEN] = &cam_cc_pll7_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_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_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_kaanapali_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_kaanapali_resets[] = { + [CAM_CC_DRV_BCR] = { 0x2138c }, + [CAM_CC_ICP_BCR] = { 0x211f4 }, + [CAM_CC_IPE_0_BCR] = { 0x20170 }, + [CAM_CC_OFE_BCR] = { 0x200c4 }, + [CAM_CC_QDSS_DEBUG_BCR] = { 0x21310 }, + [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_kaanapali_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, +}; + +static u32 cam_cc_kaanapali_critical_cbcrs[] = { + 0x21398, /* CAM_CC_DRV_AHB_CLK */ + 0x21390, /* CAM_CC_DRV_XO_CLK */ + 0x21364, /* CAM_CC_GDSC_CLK */ + 0x21368, /* CAM_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x2601c, + .fast_io = true, +}; + +static struct qcom_cc_driver_data cam_cc_kaanapali_driver_data = { + .alpha_plls = cam_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(cam_cc_kaanapali_plls), + .clk_cbcrs = cam_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_kaanapali_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_cc_kaanapali_desc = { + .config = &cam_cc_kaanapali_regmap_config, + .clks = cam_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(cam_cc_kaanapali_clocks), + .resets = cam_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(cam_cc_kaanapali_resets), + .gdscs = cam_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &cam_cc_kaanapali_driver_data, +}; + +static const struct of_device_id cam_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_kaanapali_match_table); + +static int cam_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_cc_kaanapali_desc); +} + +static struct platform_driver cam_cc_kaanapali_driver = { + .probe = cam_cc_kaanapali_probe, + .driver = { + .name = "camcc-kaanapali", + .of_match_table = cam_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(cam_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI CAMCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); From a4ceaf4b18dd4310c17852efbf880e1c5cd5dc36 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:13 +0530 Subject: [PATCH 072/165] clk: qcom: Add support for VideoCC driver for Kaanapali Enable Kaanapali video clock driver for video SW to be able to control the clocks from the Video SW driver. Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-10-8e10adc236a8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/videocc-kaanapali.c | 821 +++++++++++++++++++++++++++ 3 files changed, 831 insertions(+) create mode 100644 drivers/clk/qcom/videocc-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 34491b4ac913..04bb4f8f2c4b 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -83,6 +83,15 @@ config CLK_KAANAPALI_TCSRCC Support for the TCSR clock controller on Kaanapali devices. Say Y if you want to use peripheral devices such as PCIe, USB, UFS. +config CLK_KAANAPALI_VIDEOCC + tristate "Kaanapali Video Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the video clock controller on Kaanapali devices. + Say Y if you want to support video devices and functionality such as + video encode/decode. + config CLK_X1E80100_CAMCC tristate "X1E80100 Camera Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 8b214cb192da..1a2e1c61f258 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_CLK_KAANAPALI_CAMCC) += cambistmclkcc-kaanapali.o camcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_DISPCC) += dispcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o +obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o diff --git a/drivers/clk/qcom/videocc-kaanapali.c b/drivers/clk/qcom/videocc-kaanapali.c new file mode 100644 index 000000000000..835a59536ba7 --- /dev/null +++ b/drivers/clk/qcom/videocc-kaanapali.c @@ -0,0 +1,821 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +#define ACCU_CFG_MASK GENMASK(25, 21) + +enum { + DT_BI_TCXO, + DT_AHB_CLK, +}; + +enum { + P_BI_TCXO, + P_VIDEO_CC_PLL0_OUT_MAIN, + P_VIDEO_CC_PLL1_OUT_MAIN, + P_VIDEO_CC_PLL2_OUT_MAIN, + P_VIDEO_CC_PLL3_OUT_MAIN, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 360.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll0_config = { + .l = 0x12, + .cal_l = 0x48, + .alpha = 0xc000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll0 = { + .offset = 0x0, + .config = &video_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 480.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll1_config = { + .l = 0x19, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll1 = { + .offset = 0x1000, + .config = &video_cc_pll1_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 480.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll2_config = { + .l = 0x19, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll2 = { + .offset = 0x2000, + .config = &video_cc_pll2_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 480.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll3_config = { + .l = 0x19, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll3 = { + .offset = 0x3000, + .config = &video_cc_pll3_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map video_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL1_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll1.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL3_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll3.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL2_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll2.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll0.clkr.hw }, +}; + +static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_ahb_clk_src = { + .cmd_rcgr = 0x8060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_ahb_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { + F(240000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(800000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(1000000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0_clk_src = { + .cmd_rcgr = 0x8030, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_1, + .freq_tbl = ftbl_video_cc_mvs0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk_src", + .parent_data = video_cc_parent_data_1, + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0a_clk_src[] = { + F(240000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0a_clk_src = { + .cmd_rcgr = 0x8000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_2, + .freq_tbl = ftbl_video_cc_mvs0a_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0a_clk_src", + .parent_data = video_cc_parent_data_2, + .num_parents = ARRAY_SIZE(video_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0b_clk_src[] = { + F(240000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(850000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0b_clk_src = { + .cmd_rcgr = 0x8018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_3, + .freq_tbl = ftbl_video_cc_mvs0b_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_clk_src", + .parent_data = video_cc_parent_data_3, + .num_parents = ARRAY_SIZE(video_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0c_clk_src[] = { + F(360000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(507000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(630000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(666000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(800000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1104000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1260000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0c_clk_src = { + .cmd_rcgr = 0x8048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_4, + .freq_tbl = ftbl_video_cc_mvs0c_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk_src", + .parent_data = video_cc_parent_data_4, + .num_parents = ARRAY_SIZE(video_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 video_cc_xo_clk_src = { + .cmd_rcgr = 0x8194, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_xo_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch video_cc_mvs0_clk = { + .halt_reg = 0x80d0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80d0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_mem_branch video_cc_mvs0_freerun_clk = { + .mem_enable_reg = 0x80e4, + .mem_ack_reg = 0x80e4, + .mem_enable_mask = BIT(3), + .mem_enable_ack_mask = GENMASK(11, 10), + .mem_enable_invert = true, + .branch = { + .halt_reg = 0x80e0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_shift_clk = { + .halt_reg = 0x81b4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x81b4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x81b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp0_clk = { + .halt_reg = 0x8134, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8134, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp0_freerun_clk = { + .halt_reg = 0x8144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp0_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp1_clk = { + .halt_reg = 0x8108, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8108, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp1_freerun_clk = { + .halt_reg = 0x8118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp1_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0a_clk = { + .halt_reg = 0x8090, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0a_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0a_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0a_freerun_clk = { + .halt_reg = 0x80a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0a_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0a_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0b_clk = { + .halt_reg = 0x80bc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80bc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0b_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0b_freerun_clk = { + .halt_reg = 0x80cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0b_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_clk = { + .halt_reg = 0x8164, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8164, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8164, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_freerun_clk = { + .halt_reg = 0x8174, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8174, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_shift_clk = { + .halt_reg = 0x81b8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x81b8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x81b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc video_cc_mvs0_vpp0_gdsc = { + .gdscr = 0x8120, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0_vpp0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_vpp1_gdsc = { + .gdscr = 0x80f4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0_vpp1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0a_gdsc = { + .gdscr = 0x807c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0a_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0c_gdsc = { + .gdscr = 0x814c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0c_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_gdsc = { + .gdscr = 0x80a8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_mvs0c_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *video_cc_kaanapali_clocks[] = { + [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, + [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, + [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, + [VIDEO_CC_MVS0_FREERUN_CLK] = &video_cc_mvs0_freerun_clk.branch.clkr, + [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, + [VIDEO_CC_MVS0_VPP0_CLK] = &video_cc_mvs0_vpp0_clk.clkr, + [VIDEO_CC_MVS0_VPP0_FREERUN_CLK] = &video_cc_mvs0_vpp0_freerun_clk.clkr, + [VIDEO_CC_MVS0_VPP1_CLK] = &video_cc_mvs0_vpp1_clk.clkr, + [VIDEO_CC_MVS0_VPP1_FREERUN_CLK] = &video_cc_mvs0_vpp1_freerun_clk.clkr, + [VIDEO_CC_MVS0A_CLK] = &video_cc_mvs0a_clk.clkr, + [VIDEO_CC_MVS0A_CLK_SRC] = &video_cc_mvs0a_clk_src.clkr, + [VIDEO_CC_MVS0A_FREERUN_CLK] = &video_cc_mvs0a_freerun_clk.clkr, + [VIDEO_CC_MVS0B_CLK] = &video_cc_mvs0b_clk.clkr, + [VIDEO_CC_MVS0B_CLK_SRC] = &video_cc_mvs0b_clk_src.clkr, + [VIDEO_CC_MVS0B_FREERUN_CLK] = &video_cc_mvs0b_freerun_clk.clkr, + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, + [VIDEO_CC_MVS0C_CLK_SRC] = &video_cc_mvs0c_clk_src.clkr, + [VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr, + [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr, + [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, + [VIDEO_CC_PLL1] = &video_cc_pll1.clkr, + [VIDEO_CC_PLL2] = &video_cc_pll2.clkr, + [VIDEO_CC_PLL3] = &video_cc_pll3.clkr, + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, +}; + +static struct gdsc *video_cc_kaanapali_gdscs[] = { + [VIDEO_CC_MVS0A_GDSC] = &video_cc_mvs0a_gdsc, + [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, + [VIDEO_CC_MVS0_VPP1_GDSC] = &video_cc_mvs0_vpp1_gdsc, + [VIDEO_CC_MVS0_VPP0_GDSC] = &video_cc_mvs0_vpp0_gdsc, + [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, +}; + +static const struct qcom_reset_map video_cc_kaanapali_resets[] = { + [VIDEO_CC_INTERFACE_BCR] = { 0x8178 }, + [VIDEO_CC_MVS0_BCR] = { 0x80a4 }, + [VIDEO_CC_MVS0_VPP0_BCR] = { 0x811c }, + [VIDEO_CC_MVS0_VPP1_BCR] = { 0x80f0 }, + [VIDEO_CC_MVS0A_BCR] = { 0x8078 }, + [VIDEO_CC_MVS0C_CLK_ARES] = { 0x8164, 2 }, + [VIDEO_CC_MVS0C_BCR] = { 0x8148 }, + [VIDEO_CC_MVS0_FREERUN_CLK_ARES] = { 0x80e0, 2 }, + [VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x8174, 2 }, + [VIDEO_CC_XO_CLK_ARES] = { 0x81ac, 2 }, +}; + +static struct clk_alpha_pll *video_cc_kaanapali_plls[] = { + &video_cc_pll0, + &video_cc_pll1, + &video_cc_pll2, + &video_cc_pll3, +}; + +static u32 video_cc_kaanapali_critical_cbcrs[] = { + 0x817c, /* VIDEO_CC_AHB_CLK */ + 0x81bc, /* VIDEO_CC_SLEEP_CLK */ + 0x81b0, /* VIDEO_CC_TS_XO_CLK */ + 0x81ac, /* VIDEO_CC_XO_CLK */ +}; + +static const struct regmap_config video_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xa010, + .fast_io = true, +}; + +static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* + * Enable clk_on sync for MVS0 and VPP clocks via VIDEO_CC_SPARE1 + * during core reset by default. + */ + regmap_set_bits(regmap, 0x9f24, BIT(0)); + + /* + * As per HW design recommendation + * Update DLY_ACCU_RED_SHIFTER_DONE to 0xF for the below GDSCs + * MVS0A CFG3, MVS0 CFG3, MVS0 VPP1 CFG3, MVS0 VPP0 CFG3, MVS0C CFG3 + */ + regmap_set_bits(regmap, 0x8088, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x80b4, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x8100, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x812c, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x8158, ACCU_CFG_MASK); +} + +static struct qcom_cc_driver_data video_cc_kaanapali_driver_data = { + .alpha_plls = video_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(video_cc_kaanapali_plls), + .clk_cbcrs = video_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_kaanapali_critical_cbcrs), + .clk_regs_configure = clk_kaanapali_regs_configure, +}; + +static const struct qcom_cc_desc video_cc_kaanapali_desc = { + .config = &video_cc_kaanapali_regmap_config, + .clks = video_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(video_cc_kaanapali_clocks), + .resets = video_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(video_cc_kaanapali_resets), + .gdscs = video_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &video_cc_kaanapali_driver_data, +}; + +static const struct of_device_id video_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_kaanapali_match_table); + +static int video_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &video_cc_kaanapali_desc); +} + +static struct platform_driver video_cc_kaanapali_driver = { + .probe = video_cc_kaanapali_probe, + .driver = { + .name = "videocc-kaanapali", + .of_match_table = video_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(video_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI VIDEOCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); From 685ec348339b118bec728458d0bc3b3e7da1ef0d Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 7 Jan 2026 15:13:14 +0530 Subject: [PATCH 073/165] clk: qcom: Add support for GPUCC and GXCLK for Kaanapali Support the graphics clock controller for Kaanapali for Graphics SW driver to use the clocks. GXCLKCTL (Graphics GX Clock Controller) is a block dedicated to managing clocks for the GPU subsystem on GX power domain. The GX clock controller driver manages only the GX GDSC and the rest of the resources of the controller are managed by the firmware. Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20260107-kaanapali-mmcc-v3-v3-11-8e10adc236a8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-kaanapali.c | 482 ++++++++++++++++++++++++++ drivers/clk/qcom/gxclkctl-kaanapali.c | 76 ++++ 4 files changed, 568 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-kaanapali.c create mode 100644 drivers/clk/qcom/gxclkctl-kaanapali.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 04bb4f8f2c4b..a8a86ea6bb74 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -75,6 +75,15 @@ config CLK_KAANAPALI_GCC Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, SD/UFS, PCIe etc. +config CLK_KAANAPALI_GPUCC + tristate "Kaanapali Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the graphics clock controller on Kaanapali devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config CLK_KAANAPALI_TCSRCC tristate "Kaanapali TCSR Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 1a2e1c61f258..6b0ad8832b55 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-glymur.o obj-$(CONFIG_CLK_KAANAPALI_CAMCC) += cambistmclkcc-kaanapali.o camcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_DISPCC) += dispcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o +obj-$(CONFIG_CLK_KAANAPALI_GPUCC) += gpucc-kaanapali.o gxclkctl-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o diff --git a/drivers/clk/qcom/gpucc-kaanapali.c b/drivers/clk/qcom/gpucc-kaanapali.c new file mode 100644 index 000000000000..52be48c15c67 --- /dev/null +++ b/drivers/clk/qcom/gpucc-kaanapali.c @@ -0,0 +1,482 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + 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_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 950.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x31, + .cal_l = 0x48, + .alpha = 0x7aaa, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .config = &gpu_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpu_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_gpu_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gpu_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { 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_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll0_out_even.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(475000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(575000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(700000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(725000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(750000000, P_GPU_CC_PLL0_OUT_EVEN, 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_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gmu_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_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_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_gpu_cc_hub_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_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 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, + .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_cxo_clk = { + .halt_reg = 0x90e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x90e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cxo_clk", + .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_gx_gmu_clk = { + .halt_reg = 0x9060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_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_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, + .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, + .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 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 = 0x8, + .pd = { + .name = "gpu_cc_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gpu_cc_kaanapali_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_CXO_CLK] = &gpu_cc_cxo_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_GX_GMU_CLK] = &gpu_cc_gx_gmu_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_PLL0] = &gpu_cc_pll0.clkr, + [GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr, +}; + +static struct gdsc *gpu_cc_kaanapali_gdscs[] = { + [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc, +}; + +static const struct qcom_reset_map gpu_cc_kaanapali_resets[] = { + [GPU_CC_CB_BCR] = { 0x93a0 }, + [GPU_CC_CX_BCR] = { 0x907c }, + [GPU_CC_FAST_HUB_BCR] = { 0x93e4 }, + [GPU_CC_FF_BCR] = { 0x9470 }, + [GPU_CC_GMU_BCR] = { 0x9314 }, + [GPU_CC_GX_BCR] = { 0x905c }, + [GPU_CC_XO_BCR] = { 0x9000 }, +}; + +static struct clk_alpha_pll *gpu_cc_kaanapali_plls[] = { + &gpu_cc_pll0, +}; + +static u32 gpu_cc_kaanapali_critical_cbcrs[] = { + 0x9008, /* GPU_CC_CXO_AON_CLK */ + 0x93e8, /* GPU_CC_RSCC_HUB_AON_CLK */ + 0x9004, /* GPU_CC_RSCC_XO_AON_CLK */ +}; + +static const struct regmap_config gpu_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x95e8, + .fast_io = true, +}; + +static struct qcom_cc_driver_data gpu_cc_kaanapali_driver_data = { + .alpha_plls = gpu_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(gpu_cc_kaanapali_plls), + .clk_cbcrs = gpu_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_kaanapali_critical_cbcrs), +}; + +static const struct qcom_cc_desc gpu_cc_kaanapali_desc = { + .config = &gpu_cc_kaanapali_regmap_config, + .clks = gpu_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_kaanapali_clocks), + .resets = gpu_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(gpu_cc_kaanapali_resets), + .gdscs = gpu_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &gpu_cc_kaanapali_driver_data, +}; + +static const struct of_device_id gpu_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_kaanapali_match_table); + +static int gpu_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gpu_cc_kaanapali_desc); +} + +static struct platform_driver gpu_cc_kaanapali_driver = { + .probe = gpu_cc_kaanapali_probe, + .driver = { + .name = "gpucc-kaanapali", + .of_match_table = gpu_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(gpu_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI GPUCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gxclkctl-kaanapali.c b/drivers/clk/qcom/gxclkctl-kaanapali.c new file mode 100644 index 000000000000..c209ce5fe4f0 --- /dev/null +++ b/drivers/clk/qcom/gxclkctl-kaanapali.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "gdsc.h" + +enum { + DT_BI_TCXO, +}; + +static struct gdsc gx_clkctl_gx_gdsc = { + .gdscr = 0x4024, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gx_clkctl_gx_gdsc", + .power_on = gdsc_gx_do_nothing_enable, + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc *gx_clkctl_gdscs[] = { + [GX_CLKCTL_GX_GDSC] = &gx_clkctl_gx_gdsc, +}; + +static const struct regmap_config gx_clkctl_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x4038, + .fast_io = true, +}; + +static const struct qcom_cc_desc gx_clkctl_kaanapali_desc = { + .config = &gx_clkctl_regmap_config, + .gdscs = gx_clkctl_gdscs, + .num_gdscs = ARRAY_SIZE(gx_clkctl_gdscs), + .use_rpm = true, +}; + +static const struct of_device_id gx_clkctl_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-gxclkctl" }, + { } +}; +MODULE_DEVICE_TABLE(of, gx_clkctl_kaanapali_match_table); + +static int gx_clkctl_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gx_clkctl_kaanapali_desc); +} + +static struct platform_driver gx_clkctl_kaanapali_driver = { + .probe = gx_clkctl_kaanapali_probe, + .driver = { + .name = "gxclkctl-kaanapali", + .of_match_table = gx_clkctl_kaanapali_match_table, + }, +}; + +module_platform_driver(gx_clkctl_kaanapali_driver); + +MODULE_DESCRIPTION("QTI GXCLKCTL Kaanapali Driver"); +MODULE_LICENSE("GPL"); From 21c1d66a1672573c1934734570bd3b05a301af9e Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 27 Nov 2025 16:56:53 +0200 Subject: [PATCH 074/165] clk: renesas: cpg-mssr: Simplify pointer math in cpg_rzt2h_mstp_read() Private state is available in all places where cpg_rzt2h_mstp_read() is called, remove the extra pointer math used to find it from clk_hw. While at it, put these statements on a single line as they do not exceed the 80 columns limit. Signed-off-by: Cosmin Tanislav Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251127145654.3253992-2-cosmin-gabriel.tanislav.xa@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-cpg-mssr.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 7f9b7aa39790..031e4b125f2d 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -237,20 +237,16 @@ struct mstp_clock { #define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw) -static u32 cpg_rzt2h_mstp_read(struct clk_hw *hw, u16 offset) +static u32 cpg_rzt2h_mstp_read(struct cpg_mssr_priv *priv, u16 offset) { - struct mstp_clock *clock = to_mstp_clock(hw); - struct cpg_mssr_priv *priv = clock->priv; void __iomem *base = RZT2H_MSTPCR_BLOCK(offset) ? priv->pub.base1 : priv->pub.base0; return readl(base + RZT2H_MSTPCR_OFFSET(offset)); } -static void cpg_rzt2h_mstp_write(struct clk_hw *hw, u16 offset, u32 value) +static void cpg_rzt2h_mstp_write(struct cpg_mssr_priv *priv, u16 offset, u32 value) { - struct mstp_clock *clock = to_mstp_clock(hw); - struct cpg_mssr_priv *priv = clock->priv; void __iomem *base = RZT2H_MSTPCR_BLOCK(offset) ? priv->pub.base1 : priv->pub.base0; @@ -286,17 +282,14 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) barrier_data(priv->pub.base0 + priv->control_regs[reg]); } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { - value = cpg_rzt2h_mstp_read(hw, - priv->control_regs[reg]); + value = cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); if (enable) value &= ~bitmask; else value |= bitmask; - cpg_rzt2h_mstp_write(hw, - priv->control_regs[reg], - value); + cpg_rzt2h_mstp_write(priv, priv->control_regs[reg], value); } else { value = readl(priv->pub.base0 + priv->control_regs[reg]); if (enable) @@ -318,7 +311,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) * the IP at least seven times. Instead of memory-mapping the IP * register, we simply add a delay after the read operation. */ - cpg_rzt2h_mstp_read(hw, priv->control_regs[reg]); + cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); udelay(10); return 0; } @@ -352,8 +345,7 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) value = readb(priv->pub.base0 + priv->control_regs[reg]); else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) - value = cpg_rzt2h_mstp_read(hw, - priv->control_regs[reg]); + value = cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); else value = readl(priv->pub.base0 + priv->status_regs[reg]); From 99669468d24ce21be12f3751e7381c47ab2c9ecd Mon Sep 17 00:00:00 2001 From: Yixun Lan Date: Fri, 19 Dec 2025 08:07:23 +0800 Subject: [PATCH 075/165] clk: spacemit: extract common ccu functions Refactor the probe function of SpacemiT's clock, and extract a common ccu file, so new clock driver added in the future can share the same code, which would lower the burden of maintenance. Since this commit changes the module name from spacemit_ccu_k1 to spacemit_ccu where the auxiliary device registered, the auxiliary device id need to be adjusted. Idea of the patch comes from the review of K3 clock driver, please refer to this disucssion[1] for more detail. This change will introduce a runtime break to reset driver, and will be fixed in follow-up commit: ecff77f7c041 ("reset: spacemit: fix auxiliary device id") Link: https://lore.kernel.org/all/aTo8sCPpVM1o9PKX@pie/ [1] Link: https://lore.kernel.org/r/20260108-06-k1-clk-common-v4-2-badf635993d3@gentoo.org Suggested-by: Yao Zi Reviewed-by: Alex Elder Signed-off-by: Yixun Lan --- drivers/clk/spacemit/ccu-k1.c | 179 +----------------------------- drivers/clk/spacemit/ccu_common.c | 171 ++++++++++++++++++++++++++++ drivers/clk/spacemit/ccu_common.h | 10 ++ 3 files changed, 186 insertions(+), 174 deletions(-) diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c index 01d9485b615d..02c792a73759 100644 --- a/drivers/clk/spacemit/ccu-k1.c +++ b/drivers/clk/spacemit/ccu-k1.c @@ -5,15 +5,10 @@ */ #include -#include #include -#include -#include -#include #include #include #include -#include #include #include "ccu_common.h" @@ -23,14 +18,6 @@ #include -struct spacemit_ccu_data { - const char *reset_name; - struct clk_hw **hws; - size_t num; -}; - -static DEFINE_IDA(auxiliary_ids); - /* APBS clocks start, APBS region contains and only contains all PLL clocks */ /* @@ -1001,167 +988,6 @@ static const struct spacemit_ccu_data k1_ccu_apbc2_data = { .reset_name = "apbc2-reset", }; -static int spacemit_ccu_register(struct device *dev, - struct regmap *regmap, - struct regmap *lock_regmap, - const struct spacemit_ccu_data *data) -{ - struct clk_hw_onecell_data *clk_data; - int i, ret; - - /* Nothing to do if the CCU does not implement any clocks */ - if (!data->hws) - return 0; - - 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 ccu_common *common; - const char *name; - - if (!hw) { - clk_data->hws[i] = ERR_PTR(-ENOENT); - continue; - } - - name = hw->init->name; - - common = hw_to_ccu_common(hw); - common->regmap = regmap; - common->lock_regmap = lock_regmap; - - ret = devm_clk_hw_register(dev, hw); - if (ret) { - dev_err(dev, "Cannot register clock %d - %s\n", - i, name); - return ret; - } - - clk_data->hws[i] = hw; - } - - ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); - if (ret) - dev_err(dev, "failed to add clock hardware provider (%d)\n", ret); - - return ret; -} - -static void spacemit_cadev_release(struct device *dev) -{ - struct auxiliary_device *adev = to_auxiliary_dev(dev); - - ida_free(&auxiliary_ids, adev->id); - kfree(to_spacemit_ccu_adev(adev)); -} - -static void spacemit_adev_unregister(void *data) -{ - struct auxiliary_device *adev = data; - - auxiliary_device_delete(adev); - auxiliary_device_uninit(adev); -} - -static int spacemit_ccu_reset_register(struct device *dev, - struct regmap *regmap, - const char *reset_name) -{ - struct spacemit_ccu_adev *cadev; - struct auxiliary_device *adev; - int ret; - - /* Nothing to do if the CCU does not implement a reset controller */ - if (!reset_name) - return 0; - - cadev = kzalloc(sizeof(*cadev), GFP_KERNEL); - if (!cadev) - return -ENOMEM; - - cadev->regmap = regmap; - - adev = &cadev->adev; - adev->name = reset_name; - adev->dev.parent = dev; - adev->dev.release = spacemit_cadev_release; - adev->dev.of_node = dev->of_node; - ret = ida_alloc(&auxiliary_ids, GFP_KERNEL); - if (ret < 0) - goto err_free_cadev; - adev->id = ret; - - ret = auxiliary_device_init(adev); - if (ret) - goto err_free_aux_id; - - ret = auxiliary_device_add(adev); - if (ret) { - auxiliary_device_uninit(adev); - return ret; - } - - return devm_add_action_or_reset(dev, spacemit_adev_unregister, adev); - -err_free_aux_id: - ida_free(&auxiliary_ids, adev->id); -err_free_cadev: - kfree(cadev); - - return ret; -} - -static int k1_ccu_probe(struct platform_device *pdev) -{ - struct regmap *base_regmap, *lock_regmap = NULL; - const struct spacemit_ccu_data *data; - struct device *dev = &pdev->dev; - int ret; - - base_regmap = device_node_to_regmap(dev->of_node); - if (IS_ERR(base_regmap)) - return dev_err_probe(dev, PTR_ERR(base_regmap), - "failed to get regmap\n"); - - /* - * The lock status of PLLs locate in MPMU region, while PLLs themselves - * are in APBS region. Reference to MPMU syscon is required to check PLL - * status. - */ - if (of_device_is_compatible(dev->of_node, "spacemit,k1-pll")) { - struct device_node *mpmu = of_parse_phandle(dev->of_node, - "spacemit,mpmu", 0); - if (!mpmu) - return dev_err_probe(dev, -ENODEV, - "Cannot parse MPMU region\n"); - - lock_regmap = device_node_to_regmap(mpmu); - of_node_put(mpmu); - - if (IS_ERR(lock_regmap)) - return dev_err_probe(dev, PTR_ERR(lock_regmap), - "failed to get lock regmap\n"); - } - - data = of_device_get_match_data(dev); - - ret = spacemit_ccu_register(dev, base_regmap, lock_regmap, data); - if (ret) - return dev_err_probe(dev, ret, "failed to register clocks\n"); - - ret = spacemit_ccu_reset_register(dev, base_regmap, data->reset_name); - if (ret) - return dev_err_probe(dev, ret, "failed to register resets\n"); - - return 0; -} - static const struct of_device_id of_k1_ccu_match[] = { { .compatible = "spacemit,k1-pll", @@ -1195,6 +1021,11 @@ static const struct of_device_id of_k1_ccu_match[] = { }; MODULE_DEVICE_TABLE(of, of_k1_ccu_match); +static int k1_ccu_probe(struct platform_device *pdev) +{ + return spacemit_ccu_probe(pdev, "spacemit,k1-pll"); +} + static struct platform_driver k1_ccu_driver = { .driver = { .name = "spacemit,k1-ccu", diff --git a/drivers/clk/spacemit/ccu_common.c b/drivers/clk/spacemit/ccu_common.c index 4412c4104dab..5f05b17f8452 100644 --- a/drivers/clk/spacemit/ccu_common.c +++ b/drivers/clk/spacemit/ccu_common.c @@ -1,6 +1,177 @@ // SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include #include +#include +#include +#include + +#include "ccu_common.h" + +static DEFINE_IDA(auxiliary_ids); +static int spacemit_ccu_register(struct device *dev, + struct regmap *regmap, + struct regmap *lock_regmap, + const struct spacemit_ccu_data *data) +{ + struct clk_hw_onecell_data *clk_data; + int i, ret; + + /* Nothing to do if the CCU does not implement any clocks */ + if (!data->hws) + return 0; + + 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 ccu_common *common; + const char *name; + + if (!hw) { + clk_data->hws[i] = ERR_PTR(-ENOENT); + continue; + } + + name = hw->init->name; + + common = hw_to_ccu_common(hw); + common->regmap = regmap; + common->lock_regmap = lock_regmap; + + ret = devm_clk_hw_register(dev, hw); + if (ret) { + dev_err(dev, "Cannot register clock %d - %s\n", + i, name); + return ret; + } + + clk_data->hws[i] = hw; + } + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); + if (ret) + dev_err(dev, "failed to add clock hardware provider (%d)\n", ret); + + return ret; +} + +static void spacemit_cadev_release(struct device *dev) +{ + struct auxiliary_device *adev = to_auxiliary_dev(dev); + + ida_free(&auxiliary_ids, adev->id); + kfree(to_spacemit_ccu_adev(adev)); +} + +static void spacemit_adev_unregister(void *data) +{ + struct auxiliary_device *adev = data; + + auxiliary_device_delete(adev); + auxiliary_device_uninit(adev); +} + +static int spacemit_ccu_reset_register(struct device *dev, + struct regmap *regmap, + const char *reset_name) +{ + struct spacemit_ccu_adev *cadev; + struct auxiliary_device *adev; + int ret; + + /* Nothing to do if the CCU does not implement a reset controller */ + if (!reset_name) + return 0; + + cadev = kzalloc(sizeof(*cadev), GFP_KERNEL); + if (!cadev) + return -ENOMEM; + + cadev->regmap = regmap; + + adev = &cadev->adev; + adev->name = reset_name; + adev->dev.parent = dev; + adev->dev.release = spacemit_cadev_release; + adev->dev.of_node = dev->of_node; + ret = ida_alloc(&auxiliary_ids, GFP_KERNEL); + if (ret < 0) + goto err_free_cadev; + adev->id = ret; + + ret = auxiliary_device_init(adev); + if (ret) + goto err_free_aux_id; + + ret = auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + return devm_add_action_or_reset(dev, spacemit_adev_unregister, adev); + +err_free_aux_id: + ida_free(&auxiliary_ids, adev->id); +err_free_cadev: + kfree(cadev); + + return ret; +} + +int spacemit_ccu_probe(struct platform_device *pdev, const char *compat) +{ + struct regmap *base_regmap, *lock_regmap = NULL; + const struct spacemit_ccu_data *data; + struct device *dev = &pdev->dev; + int ret; + + base_regmap = device_node_to_regmap(dev->of_node); + if (IS_ERR(base_regmap)) + return dev_err_probe(dev, PTR_ERR(base_regmap), + "failed to get regmap\n"); + + /* + * The lock status of PLLs locate in MPMU region, while PLLs themselves + * are in APBS region. Reference to MPMU syscon is required to check PLL + * status. + */ + if (compat && of_device_is_compatible(dev->of_node, compat)) { + struct device_node *mpmu = of_parse_phandle(dev->of_node, + "spacemit,mpmu", 0); + if (!mpmu) + return dev_err_probe(dev, -ENODEV, + "Cannot parse MPMU region\n"); + + lock_regmap = device_node_to_regmap(mpmu); + of_node_put(mpmu); + + if (IS_ERR(lock_regmap)) + return dev_err_probe(dev, PTR_ERR(lock_regmap), + "failed to get lock regmap\n"); + } + + data = of_device_get_match_data(dev); + + ret = spacemit_ccu_register(dev, base_regmap, lock_regmap, data); + if (ret) + return dev_err_probe(dev, ret, "failed to register clocks\n"); + + ret = spacemit_ccu_reset_register(dev, base_regmap, data->reset_name); + if (ret) + return dev_err_probe(dev, ret, "failed to register resets\n"); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_probe, "CLK_SPACEMIT"); MODULE_DESCRIPTION("SpacemiT CCU common clock driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/spacemit/ccu_common.h b/drivers/clk/spacemit/ccu_common.h index da72f3836e0b..7ae244b5eace 100644 --- a/drivers/clk/spacemit/ccu_common.h +++ b/drivers/clk/spacemit/ccu_common.h @@ -7,6 +7,8 @@ #ifndef _CCU_COMMON_H_ #define _CCU_COMMON_H_ +#include +#include #include struct ccu_common { @@ -36,6 +38,12 @@ static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw) return container_of(hw, struct ccu_common, hw); } +struct spacemit_ccu_data { + const char *reset_name; + struct clk_hw **hws; + size_t num; +}; + #define ccu_read(c, reg) \ ({ \ u32 tmp; \ @@ -45,4 +53,6 @@ static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw) #define ccu_update(c, reg, mask, val) \ regmap_update_bits((c)->regmap, (c)->reg_##reg, mask, val) +int spacemit_ccu_probe(struct platform_device *pdev, const char *compat); + #endif /* _CCU_COMMON_H_ */ From 0664a46f93e2fb2f75fa05b5f08949600cce88f9 Mon Sep 17 00:00:00 2001 From: Yixun Lan Date: Sat, 3 Jan 2026 14:14:36 +0800 Subject: [PATCH 076/165] clk: spacemit: add platform SoC prefix to reset name This change is needed for adding future new SpacemiT K3 reset driver. Since both K1 and K3 reset code register via the same module which its name changed to spacemit_ccu, it's necessary to encode the platform/SoC in the reset auxiliary device name to distinguish them, otherwise two reset drivers will claim to support same "compatible" auxiliary device even in the case of only one CCU clock driver got registered, which in the end lead to a broken reset driver. This change will introduce a runtime break to reset driver, and will be fixed in follow-up commit: ecff77f7c041 ("reset: spacemit: fix auxiliary device id") Link: https://lore.kernel.org/r/20260108-06-k1-clk-common-v4-3-badf635993d3@gentoo.org Reviewed-by: Alex Elder Signed-off-by: Yixun Lan --- drivers/clk/spacemit/ccu-k1.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c index 02c792a73759..dee14d25f75d 100644 --- a/drivers/clk/spacemit/ccu-k1.c +++ b/drivers/clk/spacemit/ccu-k1.c @@ -789,7 +789,7 @@ static struct clk_hw *k1_ccu_mpmu_hws[] = { }; static const struct spacemit_ccu_data k1_ccu_mpmu_data = { - .reset_name = "mpmu-reset", + .reset_name = "k1-mpmu-reset", .hws = k1_ccu_mpmu_hws, .num = ARRAY_SIZE(k1_ccu_mpmu_hws), }; @@ -900,7 +900,7 @@ static struct clk_hw *k1_ccu_apbc_hws[] = { }; static const struct spacemit_ccu_data k1_ccu_apbc_data = { - .reset_name = "apbc-reset", + .reset_name = "k1-apbc-reset", .hws = k1_ccu_apbc_hws, .num = ARRAY_SIZE(k1_ccu_apbc_hws), }; @@ -971,21 +971,21 @@ static struct clk_hw *k1_ccu_apmu_hws[] = { }; static const struct spacemit_ccu_data k1_ccu_apmu_data = { - .reset_name = "apmu-reset", + .reset_name = "k1-apmu-reset", .hws = k1_ccu_apmu_hws, .num = ARRAY_SIZE(k1_ccu_apmu_hws), }; static const struct spacemit_ccu_data k1_ccu_rcpu_data = { - .reset_name = "rcpu-reset", + .reset_name = "k1-rcpu-reset", }; static const struct spacemit_ccu_data k1_ccu_rcpu2_data = { - .reset_name = "rcpu2-reset", + .reset_name = "k1-rcpu2-reset", }; static const struct spacemit_ccu_data k1_ccu_apbc2_data = { - .reset_name = "apbc2-reset", + .reset_name = "k1-apbc2-reset", }; static const struct of_device_id of_k1_ccu_match[] = { From efe897b557e211a09f51d749eae5eca933e8bf56 Mon Sep 17 00:00:00 2001 From: Yixun Lan Date: Sat, 1 Nov 2025 20:56:42 +0800 Subject: [PATCH 077/165] dt-bindings: soc: spacemit: k3: add clock support Add compatible strings for clock drivers to support Spacemit K3 SoC, also includes all the defined clock IDs. The SpacemiT K3 SoC clock IP is scattered over several different blocks, which are APBC, APBS, APMU, DCIU, MPMU, all of them are capable of generating clock and reset signals. APMU and MPMU have additional Power Domain management functionality. Following is a brief list that shows devices managed in each block: APBC: UART, GPIO, PWM, SPI, TIMER, I2S, IR, DR, TSEN, IPC, CAN APBS: various PPL clocks control APMU: CCI, CPU, CSI, ISP, LCD, USB, QSPI, DMA, VPU, GPU, DSI, PCIe, EMAC.. DCID: SRAM, DMA, TCM MPMU: various PLL1 derived clocks, UART, WATCHDOG, I2S Link: https://lore.kernel.org/r/20260108-k3-clk-v5-1-42a11b74ad58@gentoo.org Reviewed-by: Krzysztof Kozlowski Signed-off-by: Yixun Lan --- .../bindings/clock/spacemit,k1-pll.yaml | 9 +- .../soc/spacemit/spacemit,k1-syscon.yaml | 14 +- .../dt-bindings/clock/spacemit,k3-clocks.h | 390 ++++++++++++++++++ 3 files changed, 408 insertions(+), 5 deletions(-) create mode 100644 include/dt-bindings/clock/spacemit,k3-clocks.h diff --git a/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml b/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml index 06bafd68c00a..cddf6a56dac0 100644 --- a/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml +++ b/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml @@ -4,14 +4,16 @@ $id: http://devicetree.org/schemas/clock/spacemit,k1-pll.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: SpacemiT K1 PLL +title: SpacemiT K1/K3 PLL maintainers: - Haylen Chu properties: compatible: - const: spacemit,k1-pll + enum: + - spacemit,k1-pll + - spacemit,k3-pll reg: maxItems: 1 @@ -28,7 +30,8 @@ properties: "#clock-cells": const: 1 description: - See for valid indices. + For K1 SoC, check for valid indices. + For K3 SoC, check for valid indices. required: - compatible diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml index 133a391ee68c..d87131da30bc 100644 --- a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml +++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/soc/spacemit/spacemit,k1-syscon.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: SpacemiT K1 SoC System Controller +title: SpacemiT K1/K3 SoC System Controller maintainers: - Haylen Chu @@ -22,6 +22,10 @@ properties: - spacemit,k1-syscon-rcpu - spacemit,k1-syscon-rcpu2 - spacemit,k1-syscon-apbc2 + - spacemit,k3-syscon-apbc + - spacemit,k3-syscon-apmu + - spacemit,k3-syscon-dciu + - spacemit,k3-syscon-mpmu reg: maxItems: 1 @@ -39,7 +43,8 @@ properties: "#clock-cells": const: 1 description: - See for valid indices. + For K1 SoC, check for valid indices. + For K3 SoC, check for valid indices. "#power-domain-cells": const: 1 @@ -60,6 +65,8 @@ allOf: enum: - spacemit,k1-syscon-apmu - spacemit,k1-syscon-mpmu + - spacemit,k3-syscon-apmu + - spacemit,k3-syscon-mpmu then: required: - "#power-domain-cells" @@ -74,6 +81,9 @@ allOf: - spacemit,k1-syscon-apbc - spacemit,k1-syscon-apmu - spacemit,k1-syscon-mpmu + - spacemit,k3-syscon-apbc + - spacemit,k3-syscon-apmu + - spacemit,k3-syscon-mpmu then: required: - clocks diff --git a/include/dt-bindings/clock/spacemit,k3-clocks.h b/include/dt-bindings/clock/spacemit,k3-clocks.h new file mode 100644 index 000000000000..b22336f3ae40 --- /dev/null +++ b/include/dt-bindings/clock/spacemit,k3-clocks.h @@ -0,0 +1,390 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2025 SpacemiT Technology Co. Ltd + */ + +#ifndef _DT_BINDINGS_CLOCK_SPACEMIT_K3_CLOCKS_H_ +#define _DT_BINDINGS_CLOCK_SPACEMIT_K3_CLOCKS_H_ + +/* APBS (PLL) clocks */ +#define CLK_PLL1 0 +#define CLK_PLL2 1 +#define CLK_PLL3 2 +#define CLK_PLL4 3 +#define CLK_PLL5 4 +#define CLK_PLL6 5 +#define CLK_PLL7 6 +#define CLK_PLL8 7 +#define CLK_PLL1_D2 8 +#define CLK_PLL1_D3 9 +#define CLK_PLL1_D4 10 +#define CLK_PLL1_D5 11 +#define CLK_PLL1_D6 12 +#define CLK_PLL1_D7 13 +#define CLK_PLL1_D8 14 +#define CLK_PLL1_DX 15 +#define CLK_PLL1_D64 16 +#define CLK_PLL1_D10_AUD 17 +#define CLK_PLL1_D100_AUD 18 +#define CLK_PLL2_D1 19 +#define CLK_PLL2_D2 20 +#define CLK_PLL2_D3 21 +#define CLK_PLL2_D4 22 +#define CLK_PLL2_D5 23 +#define CLK_PLL2_D6 24 +#define CLK_PLL2_D7 25 +#define CLK_PLL2_D8 26 +#define CLK_PLL2_66 27 +#define CLK_PLL2_33 28 +#define CLK_PLL2_50 29 +#define CLK_PLL2_25 30 +#define CLK_PLL2_20 31 +#define CLK_PLL2_D24_125 32 +#define CLK_PLL2_D120_25 33 +#define CLK_PLL3_D1 34 +#define CLK_PLL3_D2 35 +#define CLK_PLL3_D3 36 +#define CLK_PLL3_D4 37 +#define CLK_PLL3_D5 38 +#define CLK_PLL3_D6 39 +#define CLK_PLL3_D7 40 +#define CLK_PLL3_D8 41 +#define CLK_PLL4_D1 42 +#define CLK_PLL4_D2 43 +#define CLK_PLL4_D3 44 +#define CLK_PLL4_D4 45 +#define CLK_PLL4_D5 46 +#define CLK_PLL4_D6 47 +#define CLK_PLL4_D7 48 +#define CLK_PLL4_D8 49 +#define CLK_PLL5_D1 50 +#define CLK_PLL5_D2 51 +#define CLK_PLL5_D3 52 +#define CLK_PLL5_D4 53 +#define CLK_PLL5_D5 54 +#define CLK_PLL5_D6 55 +#define CLK_PLL5_D7 56 +#define CLK_PLL5_D8 57 +#define CLK_PLL6_D1 58 +#define CLK_PLL6_D2 59 +#define CLK_PLL6_D3 60 +#define CLK_PLL6_D4 61 +#define CLK_PLL6_D5 62 +#define CLK_PLL6_D6 63 +#define CLK_PLL6_D7 64 +#define CLK_PLL6_D8 65 +#define CLK_PLL6_80 66 +#define CLK_PLL6_40 67 +#define CLK_PLL6_20 68 +#define CLK_PLL7_D1 69 +#define CLK_PLL7_D2 70 +#define CLK_PLL7_D3 71 +#define CLK_PLL7_D4 72 +#define CLK_PLL7_D5 73 +#define CLK_PLL7_D6 74 +#define CLK_PLL7_D7 75 +#define CLK_PLL7_D8 76 +#define CLK_PLL8_D1 77 +#define CLK_PLL8_D2 78 +#define CLK_PLL8_D3 79 +#define CLK_PLL8_D4 80 +#define CLK_PLL8_D5 81 +#define CLK_PLL8_D6 82 +#define CLK_PLL8_D7 83 +#define CLK_PLL8_D8 84 + +/* MPMU clocks */ +#define CLK_MPMU_PLL1_307P2 0 +#define CLK_MPMU_PLL1_76P8 1 +#define CLK_MPMU_PLL1_61P44 2 +#define CLK_MPMU_PLL1_153P6 3 +#define CLK_MPMU_PLL1_102P4 4 +#define CLK_MPMU_PLL1_51P2 5 +#define CLK_MPMU_PLL1_51P2_AP 6 +#define CLK_MPMU_PLL1_57P6 7 +#define CLK_MPMU_PLL1_25P6 8 +#define CLK_MPMU_PLL1_12P8 9 +#define CLK_MPMU_PLL1_12P8_WDT 10 +#define CLK_MPMU_PLL1_6P4 11 +#define CLK_MPMU_PLL1_3P2 12 +#define CLK_MPMU_PLL1_1P6 13 +#define CLK_MPMU_PLL1_0P8 14 +#define CLK_MPMU_PLL1_409P6 15 +#define CLK_MPMU_PLL1_204P8 16 +#define CLK_MPMU_PLL1_491 17 +#define CLK_MPMU_PLL1_245P76 18 +#define CLK_MPMU_PLL1_614 19 +#define CLK_MPMU_PLL1_47P26 20 +#define CLK_MPMU_PLL1_31P5 21 +#define CLK_MPMU_PLL1_819 22 +#define CLK_MPMU_PLL1_1228 23 +#define CLK_MPMU_APB 24 +#define CLK_MPMU_SLOW_UART 25 +#define CLK_MPMU_SLOW_UART1 26 +#define CLK_MPMU_SLOW_UART2 27 +#define CLK_MPMU_WDT 28 +#define CLK_MPMU_WDT_BUS 29 +#define CLK_MPMU_RIPC 30 +#define CLK_MPMU_I2S_153P6 31 +#define CLK_MPMU_I2S_153P6_BASE 32 +#define CLK_MPMU_I2S_SYSCLK_SRC 33 +#define CLK_MPMU_I2S1_SYSCLK 34 +#define CLK_MPMU_I2S_BCLK 35 +#define CLK_MPMU_I2S0_SYSCLK_SEL 36 +#define CLK_MPMU_I2S2_SYSCLK_SEL 37 +#define CLK_MPMU_I2S3_SYSCLK_SEL 38 +#define CLK_MPMU_I2S4_SYSCLK_SEL 39 +#define CLK_MPMU_I2S5_SYSCLK_SEL 40 +#define CLK_MPMU_I2S0_SYSCLK_DIV 41 +#define CLK_MPMU_I2S2_SYSCLK_DIV 42 +#define CLK_MPMU_I2S3_SYSCLK_DIV 43 +#define CLK_MPMU_I2S4_SYSCLK_DIV 44 +#define CLK_MPMU_I2S5_SYSCLK_DIV 45 +#define CLK_MPMU_I2S0_SYSCLK 46 +#define CLK_MPMU_I2S2_SYSCLK 47 +#define CLK_MPMU_I2S3_SYSCLK 48 +#define CLK_MPMU_I2S4_SYSCLK 49 +#define CLK_MPMU_I2S5_SYSCLK 50 + +/* APBC clocks */ +#define CLK_APBC_UART0 0 +#define CLK_APBC_UART2 1 +#define CLK_APBC_UART3 2 +#define CLK_APBC_UART4 3 +#define CLK_APBC_UART5 4 +#define CLK_APBC_UART6 5 +#define CLK_APBC_UART7 6 +#define CLK_APBC_UART8 7 +#define CLK_APBC_UART9 8 +#define CLK_APBC_UART10 9 +#define CLK_APBC_UART0_BUS 10 +#define CLK_APBC_UART2_BUS 11 +#define CLK_APBC_UART3_BUS 12 +#define CLK_APBC_UART4_BUS 13 +#define CLK_APBC_UART5_BUS 14 +#define CLK_APBC_UART6_BUS 15 +#define CLK_APBC_UART7_BUS 16 +#define CLK_APBC_UART8_BUS 17 +#define CLK_APBC_UART9_BUS 18 +#define CLK_APBC_UART10_BUS 19 +#define CLK_APBC_GPIO 20 +#define CLK_APBC_GPIO_BUS 21 +#define CLK_APBC_PWM0 22 +#define CLK_APBC_PWM1 23 +#define CLK_APBC_PWM2 24 +#define CLK_APBC_PWM3 25 +#define CLK_APBC_PWM4 26 +#define CLK_APBC_PWM5 27 +#define CLK_APBC_PWM6 28 +#define CLK_APBC_PWM7 29 +#define CLK_APBC_PWM8 30 +#define CLK_APBC_PWM9 31 +#define CLK_APBC_PWM10 32 +#define CLK_APBC_PWM11 33 +#define CLK_APBC_PWM12 34 +#define CLK_APBC_PWM13 35 +#define CLK_APBC_PWM14 36 +#define CLK_APBC_PWM15 37 +#define CLK_APBC_PWM16 38 +#define CLK_APBC_PWM17 39 +#define CLK_APBC_PWM18 40 +#define CLK_APBC_PWM19 41 +#define CLK_APBC_PWM0_BUS 42 +#define CLK_APBC_PWM1_BUS 43 +#define CLK_APBC_PWM2_BUS 44 +#define CLK_APBC_PWM3_BUS 45 +#define CLK_APBC_PWM4_BUS 46 +#define CLK_APBC_PWM5_BUS 47 +#define CLK_APBC_PWM6_BUS 48 +#define CLK_APBC_PWM7_BUS 49 +#define CLK_APBC_PWM8_BUS 50 +#define CLK_APBC_PWM9_BUS 51 +#define CLK_APBC_PWM10_BUS 52 +#define CLK_APBC_PWM11_BUS 53 +#define CLK_APBC_PWM12_BUS 54 +#define CLK_APBC_PWM13_BUS 55 +#define CLK_APBC_PWM14_BUS 56 +#define CLK_APBC_PWM15_BUS 57 +#define CLK_APBC_PWM16_BUS 58 +#define CLK_APBC_PWM17_BUS 59 +#define CLK_APBC_PWM18_BUS 60 +#define CLK_APBC_PWM19_BUS 61 +#define CLK_APBC_SPI0_I2S_BCLK 62 +#define CLK_APBC_SPI1_I2S_BCLK 63 +#define CLK_APBC_SPI3_I2S_BCLK 64 +#define CLK_APBC_SPI0 65 +#define CLK_APBC_SPI1 66 +#define CLK_APBC_SPI3 67 +#define CLK_APBC_SPI0_BUS 68 +#define CLK_APBC_SPI1_BUS 69 +#define CLK_APBC_SPI3_BUS 70 +#define CLK_APBC_RTC 71 +#define CLK_APBC_RTC_BUS 72 +#define CLK_APBC_TWSI0 73 +#define CLK_APBC_TWSI1 74 +#define CLK_APBC_TWSI2 75 +#define CLK_APBC_TWSI4 76 +#define CLK_APBC_TWSI5 77 +#define CLK_APBC_TWSI6 78 +#define CLK_APBC_TWSI8 79 +#define CLK_APBC_TWSI0_BUS 80 +#define CLK_APBC_TWSI1_BUS 81 +#define CLK_APBC_TWSI2_BUS 82 +#define CLK_APBC_TWSI4_BUS 83 +#define CLK_APBC_TWSI5_BUS 84 +#define CLK_APBC_TWSI6_BUS 85 +#define CLK_APBC_TWSI8_BUS 86 +#define CLK_APBC_TIMERS0 87 +#define CLK_APBC_TIMERS1 88 +#define CLK_APBC_TIMERS2 89 +#define CLK_APBC_TIMERS3 90 +#define CLK_APBC_TIMERS4 91 +#define CLK_APBC_TIMERS5 92 +#define CLK_APBC_TIMERS6 93 +#define CLK_APBC_TIMERS7 94 +#define CLK_APBC_TIMERS0_BUS 95 +#define CLK_APBC_TIMERS1_BUS 96 +#define CLK_APBC_TIMERS2_BUS 97 +#define CLK_APBC_TIMERS3_BUS 98 +#define CLK_APBC_TIMERS4_BUS 99 +#define CLK_APBC_TIMERS5_BUS 100 +#define CLK_APBC_TIMERS6_BUS 101 +#define CLK_APBC_TIMERS7_BUS 102 +#define CLK_APBC_AIB 103 +#define CLK_APBC_AIB_BUS 104 +#define CLK_APBC_ONEWIRE 105 +#define CLK_APBC_ONEWIRE_BUS 106 +#define CLK_APBC_I2S0_BCLK 107 +#define CLK_APBC_I2S1_BCLK 108 +#define CLK_APBC_I2S2_BCLK 109 +#define CLK_APBC_I2S3_BCLK 110 +#define CLK_APBC_I2S4_BCLK 111 +#define CLK_APBC_I2S5_BCLK 112 +#define CLK_APBC_I2S0 113 +#define CLK_APBC_I2S1 114 +#define CLK_APBC_I2S2 115 +#define CLK_APBC_I2S3 116 +#define CLK_APBC_I2S4 117 +#define CLK_APBC_I2S5 118 +#define CLK_APBC_I2S0_BUS 119 +#define CLK_APBC_I2S1_BUS 120 +#define CLK_APBC_I2S2_BUS 121 +#define CLK_APBC_I2S3_BUS 122 +#define CLK_APBC_I2S4_BUS 123 +#define CLK_APBC_I2S5_BUS 124 +#define CLK_APBC_DRO 125 +#define CLK_APBC_IR0 126 +#define CLK_APBC_IR1 127 +#define CLK_APBC_TSEN 128 +#define CLK_APBC_TSEN_BUS 129 +#define CLK_APBC_IPC_AP2RCPU 130 +#define CLK_APBC_IPC_AP2RCPU_BUS 131 +#define CLK_APBC_CAN0 132 +#define CLK_APBC_CAN1 133 +#define CLK_APBC_CAN2 134 +#define CLK_APBC_CAN3 135 +#define CLK_APBC_CAN4 136 +#define CLK_APBC_CAN0_BUS 137 +#define CLK_APBC_CAN1_BUS 138 +#define CLK_APBC_CAN2_BUS 139 +#define CLK_APBC_CAN3_BUS 140 +#define CLK_APBC_CAN4_BUS 141 + +/* APMU clocks */ +#define CLK_APMU_AXICLK 0 +#define CLK_APMU_CCI550 1 +#define CLK_APMU_CPU_C0_CORE 2 +#define CLK_APMU_CPU_C1_CORE 3 +#define CLK_APMU_CPU_C2_CORE 4 +#define CLK_APMU_CPU_C3_CORE 5 +#define CLK_APMU_CCIC2PHY 6 +#define CLK_APMU_CCIC3PHY 7 +#define CLK_APMU_CSI 8 +#define CLK_APMU_ISP_BUS 9 +#define CLK_APMU_D1P_1228P8 10 +#define CLK_APMU_D1P_819P2 11 +#define CLK_APMU_D1P_614P4 12 +#define CLK_APMU_D1P_491P52 13 +#define CLK_APMU_D1P_409P6 14 +#define CLK_APMU_D1P_307P2 15 +#define CLK_APMU_D1P_245P76 16 +#define CLK_APMU_V2D 17 +#define CLK_APMU_DSI_ESC 18 +#define CLK_APMU_LCD_HCLK 19 +#define CLK_APMU_LCD_DSC 20 +#define CLK_APMU_LCD_PXCLK 21 +#define CLK_APMU_LCD_MCLK 22 +#define CLK_APMU_CCIC_4X 23 +#define CLK_APMU_CCIC1PHY 24 +#define CLK_APMU_SC2_HCLK 25 +#define CLK_APMU_SDH_AXI 26 +#define CLK_APMU_SDH0 27 +#define CLK_APMU_SDH1 28 +#define CLK_APMU_SDH2 29 +#define CLK_APMU_USB2_BUS 30 +#define CLK_APMU_USB3_PORTA_BUS 31 +#define CLK_APMU_USB3_PORTB_BUS 32 +#define CLK_APMU_USB3_PORTC_BUS 33 +#define CLK_APMU_USB3_PORTD_BUS 34 +#define CLK_APMU_QSPI 35 +#define CLK_APMU_QSPI_BUS 36 +#define CLK_APMU_DMA 37 +#define CLK_APMU_AES_WTM 38 +#define CLK_APMU_VPU 39 +#define CLK_APMU_DTC 40 +#define CLK_APMU_GPU 41 +#define CLK_APMU_MC_AHB 42 +#define CLK_APMU_TOP_DCLK 43 +#define CLK_APMU_UCIE 44 +#define CLK_APMU_UCIE_SBCLK 45 +#define CLK_APMU_RCPU 46 +#define CLK_APMU_DSI4LN2_DSI_ESC 47 +#define CLK_APMU_DSI4LN2_LCD_DSC 48 +#define CLK_APMU_DSI4LN2_LCD_PXCLK 49 +#define CLK_APMU_DSI4LN2_LCD_MCLK 50 +#define CLK_APMU_DSI4LN2_DPU_ACLK 51 +#define CLK_APMU_DPU_ACLK 52 +#define CLK_APMU_UFS_ACLK 53 +#define CLK_APMU_EDP0_PXCLK 54 +#define CLK_APMU_EDP1_PXCLK 55 +#define CLK_APMU_PCIE_PORTA_MSTE 56 +#define CLK_APMU_PCIE_PORTA_SLV 57 +#define CLK_APMU_PCIE_PORTB_MSTE 58 +#define CLK_APMU_PCIE_PORTB_SLV 59 +#define CLK_APMU_PCIE_PORTC_MSTE 60 +#define CLK_APMU_PCIE_PORTC_SLV 61 +#define CLK_APMU_PCIE_PORTD_MSTE 62 +#define CLK_APMU_PCIE_PORTD_SLV 63 +#define CLK_APMU_PCIE_PORTE_MSTE 64 +#define CLK_APMU_PCIE_PORTE_SLV 65 +#define CLK_APMU_EMAC0_BUS 66 +#define CLK_APMU_EMAC0_REF 67 +#define CLK_APMU_EMAC0_1588 68 +#define CLK_APMU_EMAC0_RGMII_TX 69 +#define CLK_APMU_EMAC1_BUS 70 +#define CLK_APMU_EMAC1_REF 71 +#define CLK_APMU_EMAC1_1588 72 +#define CLK_APMU_EMAC1_RGMII_TX 73 +#define CLK_APMU_EMAC2_BUS 74 +#define CLK_APMU_EMAC2_REF 75 +#define CLK_APMU_EMAC2_1588 76 +#define CLK_APMU_EMAC2_RGMII_TX 77 +#define CLK_APMU_ESPI_SCLK_SRC 78 +#define CLK_APMU_ESPI_SCLK 79 +#define CLK_APMU_ESPI_MCLK 80 +#define CLK_APMU_CAM_SRC1 81 +#define CLK_APMU_CAM_SRC2 82 +#define CLK_APMU_CAM_SRC3 83 +#define CLK_APMU_CAM_SRC4 84 +#define CLK_APMU_ISIM_VCLK0 85 +#define CLK_APMU_ISIM_VCLK1 86 +#define CLK_APMU_ISIM_VCLK2 87 +#define CLK_APMU_ISIM_VCLK3 88 + +/* DCIU clocks */ +#define CLK_DCIU_HDMA 0 +#define CLK_DCIU_DMA350 1 +#define CLK_DCIU_C2_TCM_PIPE 2 +#define CLK_DCIU_C3_TCM_PIPE 3 + +#endif /* _DT_BINDINGS_CLOCK_SPACEMIT_K3_CLOCKS_H_ */ From ace73b7e27633ec770cfb24cd4ff42c24815a9aa Mon Sep 17 00:00:00 2001 From: Yixun Lan Date: Fri, 31 Oct 2025 20:40:46 +0800 Subject: [PATCH 078/165] clk: spacemit: ccu_mix: add inverted enable gate clock K3 SoC has the clock IP which support to write value 0 for enabling the clock, while write 1 for disabling it, thus the enable BIT is inverted. So, introduce a flag to support the inverted gate clock. Link: https://lore.kernel.org/r/20260108-k3-clk-v5-2-42a11b74ad58@gentoo.org Signed-off-by: Yixun Lan --- drivers/clk/spacemit/ccu_mix.c | 12 ++++++++---- drivers/clk/spacemit/ccu_mix.h | 12 ++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/clk/spacemit/ccu_mix.c b/drivers/clk/spacemit/ccu_mix.c index 67f8b12b4f5b..9578366e9746 100644 --- a/drivers/clk/spacemit/ccu_mix.c +++ b/drivers/clk/spacemit/ccu_mix.c @@ -16,17 +16,19 @@ static void ccu_gate_disable(struct clk_hw *hw) { struct ccu_mix *mix = hw_to_ccu_mix(hw); + struct ccu_gate_config *gate = &mix->gate; + u32 val = gate->inverted ? gate->mask : 0; - ccu_update(&mix->common, ctrl, mix->gate.mask, 0); + ccu_update(&mix->common, ctrl, gate->mask, val); } static int ccu_gate_enable(struct clk_hw *hw) { struct ccu_mix *mix = hw_to_ccu_mix(hw); struct ccu_gate_config *gate = &mix->gate; + u32 val = gate->inverted ? 0 : gate->mask; - ccu_update(&mix->common, ctrl, gate->mask, gate->mask); - + ccu_update(&mix->common, ctrl, gate->mask, val); return 0; } @@ -34,8 +36,10 @@ static int ccu_gate_is_enabled(struct clk_hw *hw) { struct ccu_mix *mix = hw_to_ccu_mix(hw); struct ccu_gate_config *gate = &mix->gate; + u32 tmp = ccu_read(&mix->common, ctrl) & gate->mask; + u32 val = gate->inverted ? 0 : gate->mask; - return (ccu_read(&mix->common, ctrl) & gate->mask) == gate->mask; + return !!(tmp == val); } static unsigned long ccu_factor_recalc_rate(struct clk_hw *hw, diff --git a/drivers/clk/spacemit/ccu_mix.h b/drivers/clk/spacemit/ccu_mix.h index c406508e3504..dbba9bf49b3b 100644 --- a/drivers/clk/spacemit/ccu_mix.h +++ b/drivers/clk/spacemit/ccu_mix.h @@ -16,9 +16,11 @@ * * @mask: Mask to enable the gate. Some clocks may have more than one bit * set in this field. + * @inverted: Enable bit is inverted, 1 - disable clock, 0 - enable clock */ struct ccu_gate_config { u32 mask; + bool inverted; }; struct ccu_factor_config { @@ -48,6 +50,7 @@ struct ccu_mix { #define CCU_FACTOR_INIT(_div, _mul) { .div = _div, .mul = _mul } #define CCU_MUX_INIT(_shift, _width) { .shift = _shift, .width = _width } #define CCU_DIV_INIT(_shift, _width) { .shift = _shift, .width = _width } +#define CCU_GATE_FLAGS_INIT(_mask, _inverted) { .mask = _mask, .inverted = _inverted } #define CCU_PARENT_HW(_parent) { .hw = &_parent.common.hw } #define CCU_PARENT_NAME(_name) { .fw_name = #_name } @@ -101,6 +104,15 @@ static struct ccu_mix _name = { \ } \ } +#define CCU_GATE_FLAGS_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _inverted, _flags) \ +static struct ccu_mix _name = { \ + .gate = CCU_GATE_FLAGS_INIT(_mask_gate, _inverted), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + CCU_MIX_INITHW(_name, _parent, spacemit_ccu_gate_ops, _flags), \ + } \ +} + #define CCU_FACTOR_GATE_FLAGS_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _div, \ _mul, _flags) \ static struct ccu_mix _name = { \ From 3a086236c600739d6653c0405d86aff7d6f03c06 Mon Sep 17 00:00:00 2001 From: Yixun Lan Date: Mon, 27 Oct 2025 21:41:24 +0800 Subject: [PATCH 079/165] clk: spacemit: ccu_pll: add plla type clock Introduce a new clock PLLA for SpacemiT's K3 SoC which has a different register layout comparing to previous PPL type. And, It is configured by swcr1, swcr3 and swcr2 BIT[15:8]. Link: https://lore.kernel.org/r/20260108-k3-clk-v5-3-42a11b74ad58@gentoo.org Signed-off-by: Yixun Lan --- drivers/clk/spacemit/ccu_common.h | 1 + drivers/clk/spacemit/ccu_pll.c | 118 ++++++++++++++++++++++++++++++ drivers/clk/spacemit/ccu_pll.h | 57 ++++++++++++--- 3 files changed, 166 insertions(+), 10 deletions(-) diff --git a/drivers/clk/spacemit/ccu_common.h b/drivers/clk/spacemit/ccu_common.h index 7ae244b5eace..8691698e007d 100644 --- a/drivers/clk/spacemit/ccu_common.h +++ b/drivers/clk/spacemit/ccu_common.h @@ -26,6 +26,7 @@ struct ccu_common { /* For PLL */ struct { u32 reg_swcr1; + u32 reg_swcr2; u32 reg_swcr3; }; }; diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c index 76d0244873d8..d4066a0ed452 100644 --- a/drivers/clk/spacemit/ccu_pll.c +++ b/drivers/clk/spacemit/ccu_pll.c @@ -17,6 +17,9 @@ #define PLL_SWCR3_EN ((u32)BIT(31)) #define PLL_SWCR3_MASK GENMASK(30, 0) +#define PLLA_SWCR2_EN ((u32)BIT(16)) +#define PLLA_SWCR2_MASK GENMASK(15, 8) + static const struct ccu_pll_rate_tbl *ccu_pll_lookup_best_rate(struct ccu_pll *pll, unsigned long rate) { @@ -148,6 +151,110 @@ static int ccu_pll_init(struct clk_hw *hw) return 0; } +static const struct ccu_pll_rate_tbl *ccu_plla_lookup_matched_entry(struct ccu_pll *pll) +{ + struct ccu_pll_config *config = &pll->config; + const struct ccu_pll_rate_tbl *entry; + u32 i, swcr1, swcr2, swcr3; + + swcr1 = ccu_read(&pll->common, swcr1); + swcr2 = ccu_read(&pll->common, swcr2); + swcr2 &= PLLA_SWCR2_MASK; + swcr3 = ccu_read(&pll->common, swcr3); + + for (i = 0; i < config->tbl_num; i++) { + entry = &config->rate_tbl[i]; + + if (swcr1 == entry->swcr1 && + swcr2 == entry->swcr2 && + swcr3 == entry->swcr3) + return entry; + } + + return NULL; +} + +static void ccu_plla_update_param(struct ccu_pll *pll, const struct ccu_pll_rate_tbl *entry) +{ + struct ccu_common *common = &pll->common; + + regmap_write(common->regmap, common->reg_swcr1, entry->swcr1); + regmap_write(common->regmap, common->reg_swcr3, entry->swcr3); + ccu_update(common, swcr2, PLLA_SWCR2_MASK, entry->swcr2); +} + +static int ccu_plla_is_enabled(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + return ccu_read(common, swcr2) & PLLA_SWCR2_EN; +} + +static int ccu_plla_enable(struct clk_hw *hw) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + struct ccu_common *common = &pll->common; + unsigned int tmp; + + ccu_update(common, swcr2, PLLA_SWCR2_EN, PLLA_SWCR2_EN); + + /* check lock status */ + return regmap_read_poll_timeout_atomic(common->lock_regmap, + pll->config.reg_lock, + tmp, + tmp & pll->config.mask_lock, + PLL_DELAY_US, PLL_TIMEOUT_US); +} + +static void ccu_plla_disable(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + ccu_update(common, swcr2, PLLA_SWCR2_EN, 0); +} + +/* + * PLLAs must be gated before changing rate, which is ensured by + * flag CLK_SET_RATE_GATE. + */ +static int ccu_plla_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + const struct ccu_pll_rate_tbl *entry; + + entry = ccu_pll_lookup_best_rate(pll, rate); + ccu_plla_update_param(pll, entry); + + return 0; +} + +static unsigned long ccu_plla_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + const struct ccu_pll_rate_tbl *entry; + + entry = ccu_plla_lookup_matched_entry(pll); + + WARN_ON_ONCE(!entry); + + return entry ? entry->rate : 0; +} + +static int ccu_plla_init(struct clk_hw *hw) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + + if (ccu_plla_lookup_matched_entry(pll)) + return 0; + + ccu_plla_disable(hw); + ccu_plla_update_param(pll, &pll->config.rate_tbl[0]); + + return 0; +} + const struct clk_ops spacemit_ccu_pll_ops = { .init = ccu_pll_init, .enable = ccu_pll_enable, @@ -158,3 +265,14 @@ const struct clk_ops spacemit_ccu_pll_ops = { .is_enabled = ccu_pll_is_enabled, }; EXPORT_SYMBOL_NS_GPL(spacemit_ccu_pll_ops, "CLK_SPACEMIT"); + +const struct clk_ops spacemit_ccu_plla_ops = { + .init = ccu_plla_init, + .enable = ccu_plla_enable, + .disable = ccu_plla_disable, + .set_rate = ccu_plla_set_rate, + .recalc_rate = ccu_plla_recalc_rate, + .determine_rate = ccu_pll_determine_rate, + .is_enabled = ccu_plla_is_enabled, +}; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_plla_ops, "CLK_SPACEMIT"); diff --git a/drivers/clk/spacemit/ccu_pll.h b/drivers/clk/spacemit/ccu_pll.h index 0592f4c3068c..e41db5c97c1a 100644 --- a/drivers/clk/spacemit/ccu_pll.h +++ b/drivers/clk/spacemit/ccu_pll.h @@ -16,14 +16,31 @@ * configuration. * * @rate: PLL rate - * @swcr1: Register value of PLLX_SW1_CTRL (PLLx_SWCR1). - * @swcr3: Register value of the PLLx_SW3_CTRL's lowest 31 bits of - * PLLx_SW3_CTRL (PLLx_SWCR3). This highest bit is for enabling - * the PLL and not contained in this field. + * @swcr1: Value of register PLLx_SW1_CTRL. + * @swcr2: Value of register PLLAx_SW2_CTRL. + * @swcr3: value of register PLLx_SW3_CTRL. + * + * See below tables for the register used in PPL/PPLA clocks + * + * Regular PLL type + * | Enable | swcr3 | PLLx_SW3_CTRL - BIT[31] | + * ----------------------------------------------- + * | Config | swcr1 | PLLx_SW1_CTRL - BIT[31:0] | + * | | swcr2 | Not used | + * | | swcr3 | PLLx_SW3_CTRL - BIT[30:0] | + * + * Special PLL type A + * | Enable | swcr2 | PLLAx_SW2_CTRL - BIT[16] | + * ----------------------------------------------- + * | Config | swcr1 | PLLAx_SW1_CTRL - BIT[31:0] | + * | | swcr2 | PLLAx_SW2_CTRL - BIT[15:8] | + * | | swcr3 | PLLAx_SW3_CTRL - BIT[31:0] | + * */ struct ccu_pll_rate_tbl { unsigned long rate; u32 swcr1; + u32 swcr2; u32 swcr3; }; @@ -36,11 +53,19 @@ struct ccu_pll_config { #define CCU_PLL_RATE(_rate, _swcr1, _swcr3) \ { \ - .rate = _rate, \ + .rate = _rate, \ .swcr1 = _swcr1, \ .swcr3 = _swcr3, \ } +#define CCU_PLLA_RATE(_rate, _swcr1, _swcr2, _swcr3) \ + { \ + .rate = _rate, \ + .swcr1 = _swcr1, \ + .swcr2 = _swcr2, \ + .swcr3 = _swcr3, \ + } + struct ccu_pll { struct ccu_common common; struct ccu_pll_config config; @@ -54,26 +79,37 @@ struct ccu_pll { .mask_lock = (_mask_lock), \ } -#define CCU_PLL_HWINIT(_name, _flags) \ +#define CCU_PLL_COMMON_HWINIT(_name, _ops, _flags) \ (&(struct clk_init_data) { \ .name = #_name, \ - .ops = &spacemit_ccu_pll_ops, \ + .ops = _ops, \ .parent_data = &(struct clk_parent_data) { .index = 0 }, \ .num_parents = 1, \ .flags = _flags, \ }) -#define CCU_PLL_DEFINE(_name, _table, _reg_swcr1, _reg_swcr3, _reg_lock, \ - _mask_lock, _flags) \ +#define CCU_PLL_X_DEFINE(_name, _table, _reg_swcr1, _reg_swcr2, _reg_swcr3, \ + _reg_lock, _mask_lock, _ops, _flags) \ static struct ccu_pll _name = { \ .config = CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock), \ .common = { \ .reg_swcr1 = _reg_swcr1, \ + .reg_swcr2 = _reg_swcr2, \ .reg_swcr3 = _reg_swcr3, \ - .hw.init = CCU_PLL_HWINIT(_name, _flags) \ + .hw.init = CCU_PLL_COMMON_HWINIT(_name, _ops, _flags) \ } \ } +#define CCU_PLL_DEFINE(_name, _table, _reg_swcr1, _reg_swcr3, _reg_lock, \ + _mask_lock, _flags) \ + CCU_PLL_X_DEFINE(_name, _table, _reg_swcr1, 0, _reg_swcr3, \ + _reg_lock, _mask_lock, &spacemit_ccu_pll_ops, _flags) + +#define CCU_PLLA_DEFINE(_name, _table, _reg_swcr1, _reg_swcr2, _reg_swcr3, \ + _reg_lock, _mask_lock, _flags) \ + CCU_PLL_X_DEFINE(_name, _table, _reg_swcr1, _reg_swcr2, _reg_swcr3, \ + _reg_lock, _mask_lock, &spacemit_ccu_plla_ops, _flags) + static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw) { struct ccu_common *common = hw_to_ccu_common(hw); @@ -82,5 +118,6 @@ static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw) } extern const struct clk_ops spacemit_ccu_pll_ops; +extern const struct clk_ops spacemit_ccu_plla_ops; #endif From e371a77255b837f5d64c9d2520f87e41ea5350b9 Mon Sep 17 00:00:00 2001 From: Yixun Lan Date: Sun, 2 Nov 2025 21:17:17 +0800 Subject: [PATCH 080/165] clk: spacemit: k3: add the clock tree Add clock support to SpacemiT K3 SoC, the clock tree consist of several blocks which are APBC, APBS, APMU, DCIU, MPUM. Link: https://lore.kernel.org/r/20260108-k3-clk-v5-5-42a11b74ad58@gentoo.org Signed-off-by: Yixun Lan --- drivers/clk/spacemit/Kconfig | 6 + drivers/clk/spacemit/Makefile | 3 + drivers/clk/spacemit/ccu-k3.c | 1487 +++++++++++++++++++++++++++++++++ 3 files changed, 1496 insertions(+) create mode 100644 drivers/clk/spacemit/ccu-k3.c diff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig index 3351e8bc801d..4ebe6aaa1980 100644 --- a/drivers/clk/spacemit/Kconfig +++ b/drivers/clk/spacemit/Kconfig @@ -14,4 +14,10 @@ config SPACEMIT_K1_CCU help Support for clock controller unit in SpacemiT K1 SoC. +config SPACEMIT_K3_CCU + tristate "Support for SpacemiT K3 SoC" + select SPACEMIT_CCU + help + Support for clock controller unit in SpacemiT K3 SoC. + endmenu diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile index ad2bf315109b..0925eda384b4 100644 --- a/drivers/clk/spacemit/Makefile +++ b/drivers/clk/spacemit/Makefile @@ -8,3 +8,6 @@ spacemit-ccu-y += ccu_ddn.o obj-$(CONFIG_SPACEMIT_K1_CCU) += spacemit-ccu-k1.o spacemit-ccu-k1-y += ccu-k1.o + +obj-$(CONFIG_SPACEMIT_K3_CCU) += spacemit-ccu-k3.o +spacemit-ccu-k3-y += ccu-k3.o diff --git a/drivers/clk/spacemit/ccu-k3.c b/drivers/clk/spacemit/ccu-k3.c new file mode 100644 index 000000000000..e98afd59f05c --- /dev/null +++ b/drivers/clk/spacemit/ccu-k3.c @@ -0,0 +1,1487 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 SpacemiT Technology Co. Ltd + */ + +#include +#include +#include +#include + +#include "ccu_common.h" +#include "ccu_pll.h" +#include "ccu_mix.h" +#include "ccu_ddn.h" + +#include + +/* APBS clocks start, APBS region contains and only contains all PLL clocks */ + +/* + * PLL{1,2} must run at fixed frequencies to provide clocks in correct rates for + * peripherals. + */ +static const struct ccu_pll_rate_tbl pll1_rate_tbl[] = { + CCU_PLLA_RATE(2457600000UL, 0x0b330ccc, 0x0000cd00, 0xa0558989), +}; + +static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = { + CCU_PLLA_RATE(3000000000UL, 0x0b3e2000, 0x00000000, 0xa0558c8c), +}; + +static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = { + CCU_PLLA_RATE(2200000000UL, 0x0b2d3555, 0x00005500, 0xa0558787), +}; + +static const struct ccu_pll_rate_tbl pll4_rate_tbl[] = { + CCU_PLLA_RATE(2200000000UL, 0x0b2d3555, 0x00005500, 0xa0558787), +}; + +static const struct ccu_pll_rate_tbl pll5_rate_tbl[] = { + CCU_PLLA_RATE(2000000000UL, 0x0b292aaa, 0x0000ab00, 0xa0558686), +}; + +static const struct ccu_pll_rate_tbl pll6_rate_tbl[] = { + CCU_PLLA_RATE(3200000000UL, 0x0b422aaa, 0x0000ab00, 0xa0558e8e), +}; + +static const struct ccu_pll_rate_tbl pll7_rate_tbl[] = { + CCU_PLLA_RATE(2800000000UL, 0x0b3a1555, 0x00005500, 0xa0558b8b), +}; + +static const struct ccu_pll_rate_tbl pll8_rate_tbl[] = { + CCU_PLLA_RATE(2000000000UL, 0x0b292aaa, 0x0000ab00, 0xa0558686), +}; + +CCU_PLLA_DEFINE(pll1, pll1_rate_tbl, APBS_PLL1_SWCR1, APBS_PLL1_SWCR2, APBS_PLL1_SWCR3, + MPMU_POSR, POSR_PLL1_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll2, pll2_rate_tbl, APBS_PLL2_SWCR1, APBS_PLL2_SWCR2, APBS_PLL2_SWCR3, + MPMU_POSR, POSR_PLL2_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll3, pll3_rate_tbl, APBS_PLL3_SWCR1, APBS_PLL3_SWCR2, APBS_PLL3_SWCR3, + MPMU_POSR, POSR_PLL3_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll4, pll4_rate_tbl, APBS_PLL4_SWCR1, APBS_PLL4_SWCR2, APBS_PLL4_SWCR3, + MPMU_POSR, POSR_PLL4_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll5, pll5_rate_tbl, APBS_PLL5_SWCR1, APBS_PLL5_SWCR2, APBS_PLL5_SWCR3, + MPMU_POSR, POSR_PLL5_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll6, pll6_rate_tbl, APBS_PLL6_SWCR1, APBS_PLL6_SWCR2, APBS_PLL6_SWCR3, + MPMU_POSR, POSR_PLL6_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll7, pll7_rate_tbl, APBS_PLL7_SWCR1, APBS_PLL7_SWCR2, APBS_PLL7_SWCR3, + MPMU_POSR, POSR_PLL7_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll8, pll8_rate_tbl, APBS_PLL8_SWCR1, APBS_PLL8_SWCR2, APBS_PLL8_SWCR3, + MPMU_POSR, POSR_PLL8_LOCK, CLK_SET_RATE_GATE); + +CCU_FACTOR_GATE_DEFINE(pll1_d2, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d3, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d5, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d6, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d7, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_FLAGS_DEFINE(pll1_d8, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(7), 8, 1, + CLK_IS_CRITICAL); +CCU_DIV_GATE_DEFINE(pll1_dx, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, 23, 5, BIT(22), 0); +CCU_FACTOR_GATE_DEFINE(pll1_d64_38p4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(31), 64, 1); +CCU_FACTOR_GATE_DEFINE(pll1_aud_245p7, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(21), 10, 1); +CCU_FACTOR_DEFINE(pll1_aud_24p5, CCU_PARENT_HW(pll1_aud_245p7), 10, 1); + +CCU_FACTOR_GATE_DEFINE(pll2_d1, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d2, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d3, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d4, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d5, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d6, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d7, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d8, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(7), 8, 1); +CCU_FACTOR_DEFINE(pll2_66, CCU_PARENT_HW(pll2_d5), 9, 1); +CCU_FACTOR_DEFINE(pll2_33, CCU_PARENT_HW(pll2_66), 2, 1); +CCU_FACTOR_DEFINE(pll2_50, CCU_PARENT_HW(pll2_d5), 12, 1); +CCU_FACTOR_DEFINE(pll2_25, CCU_PARENT_HW(pll2_50), 2, 1); +CCU_FACTOR_DEFINE(pll2_20, CCU_PARENT_HW(pll2_d5), 30, 1); +CCU_FACTOR_DEFINE(pll2_d24_125, CCU_PARENT_HW(pll2_d3), 8, 1); +CCU_FACTOR_DEFINE(pll2_d120_25, CCU_PARENT_HW(pll2_d3), 40, 1); + +CCU_FACTOR_GATE_DEFINE(pll3_d1, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d2, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d3, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d4, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d5, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d6, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d7, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d8, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(7), 8, 1); + +CCU_FACTOR_GATE_DEFINE(pll4_d1, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d2, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d3, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d4, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d5, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d6, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d7, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d8, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(7), 8, 1); + +CCU_FACTOR_GATE_DEFINE(pll5_d1, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d2, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d3, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d4, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d5, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d6, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d7, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d8, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(7), 8, 1); + +CCU_FACTOR_GATE_DEFINE(pll6_d1, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d2, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d3, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d4, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d5, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d6, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d7, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d8, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(7), 8, 1); +CCU_FACTOR_DEFINE(pll6_80, CCU_PARENT_HW(pll6_d5), 8, 1); +CCU_FACTOR_DEFINE(pll6_40, CCU_PARENT_HW(pll6_d5), 16, 1); +CCU_FACTOR_DEFINE(pll6_20, CCU_PARENT_HW(pll6_d5), 32, 1); + +CCU_FACTOR_GATE_DEFINE(pll7_d1, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d2, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d3, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d4, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d5, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d6, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d7, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d8, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(7), 8, 1); + +CCU_FACTOR_GATE_DEFINE(pll8_d1, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d2, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d3, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d4, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d5, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d6, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d7, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d8, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(7), 8, 1); +/* APBS clocks end */ + +/* MPMU clocks start */ +CCU_GATE_DEFINE(pll1_d8_307p2, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(13), 0); +CCU_FACTOR_DEFINE(pll1_d32_76p8, CCU_PARENT_HW(pll1_d8_307p2), 4, 1); +CCU_FACTOR_DEFINE(pll1_d40_61p44, CCU_PARENT_HW(pll1_d8_307p2), 5, 1); +CCU_FACTOR_DEFINE(pll1_d16_153p6, CCU_PARENT_HW(pll1_d8), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d24_102p4, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(12), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d48_51p2, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(7), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d48_51p2_ap, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(11), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll1_m3d128_57p6, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(8), 16, 3); +CCU_FACTOR_GATE_DEFINE(pll1_d96_25p6, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(4), 12, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d192_12p8, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(3), 24, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d192_12p8_wdt, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(19), 24, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d384_6p4, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(2), 48, 1); + +CCU_FACTOR_DEFINE(pll1_d768_3p2, CCU_PARENT_HW(pll1_d384_6p4), 2, 1); +CCU_FACTOR_DEFINE(pll1_d1536_1p6, CCU_PARENT_HW(pll1_d384_6p4), 4, 1); +CCU_FACTOR_DEFINE(pll1_d3072_0p8, CCU_PARENT_HW(pll1_d384_6p4), 8, 1); + +CCU_GATE_DEFINE(pll1_d6_409p6, CCU_PARENT_HW(pll1_d6), MPMU_ACGR, BIT(0), 0); +CCU_FACTOR_GATE_DEFINE(pll1_d12_204p8, CCU_PARENT_HW(pll1_d6), MPMU_ACGR, BIT(5), 2, 1); + +CCU_GATE_DEFINE(pll1_d5_491p52, CCU_PARENT_HW(pll1_d5), MPMU_ACGR, BIT(21), 0); +CCU_FACTOR_GATE_DEFINE(pll1_d10_245p76, CCU_PARENT_HW(pll1_d5), MPMU_ACGR, BIT(18), 2, 1); + +CCU_GATE_DEFINE(pll1_d4_614p4, CCU_PARENT_HW(pll1_d4), MPMU_ACGR, BIT(15), 0); +CCU_FACTOR_GATE_DEFINE(pll1_d52_47p26, CCU_PARENT_HW(pll1_d4), MPMU_ACGR, BIT(10), 13, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d78_31p5, CCU_PARENT_HW(pll1_d4), MPMU_ACGR, BIT(6), 39, 2); + +CCU_GATE_DEFINE(pll1_d3_819p2, CCU_PARENT_HW(pll1_d3), MPMU_ACGR, BIT(14), 0); + +CCU_GATE_DEFINE(pll1_d2_1228p8, CCU_PARENT_HW(pll1_d2), MPMU_ACGR, BIT(16), 0); + +static const struct clk_parent_data apb_parents[] = { + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d24_102p4), +}; +CCU_MUX_DEFINE(apb_clk, apb_parents, MPMU_APBCSCR, 0, 2, 0); + +CCU_GATE_DEFINE(slow_uart, CCU_PARENT_NAME(osc_32k), MPMU_ACGR, BIT(1), CLK_IGNORE_UNUSED); +CCU_DDN_DEFINE(slow_uart1_14p74, pll1_d16_153p6, MPMU_SUCCR, 16, 13, 0, 13, 2, 0); +CCU_DDN_DEFINE(slow_uart2_48, pll1_d4_614p4, MPMU_SUCCR_1, 16, 13, 0, 13, 2, 0); + +CCU_GATE_DEFINE(wdt_clk, CCU_PARENT_HW(pll1_d96_25p6), MPMU_WDTPCR, BIT(1), 0); +CCU_GATE_DEFINE(wdt_bus_clk, CCU_PARENT_HW(apb_clk), MPMU_WDTPCR, BIT(0), 0); + +CCU_GATE_DEFINE(r_ipc_clk, CCU_PARENT_HW(apb_clk), MPMU_RIPCCR, BIT(0), 0); + +CCU_FACTOR_DEFINE(i2s_153p6, CCU_PARENT_HW(pll1_d8_307p2), 2, 1); + +static const struct clk_parent_data i2s_153p6_base_parents[] = { + CCU_PARENT_HW(i2s_153p6), + CCU_PARENT_HW(pll1_d8_307p2), +}; +CCU_MUX_DEFINE(i2s_153p6_base, i2s_153p6_base_parents, MPMU_FCCR, 29, 1, 0); + +static const struct clk_parent_data i2s_sysclk_src_parents[] = { + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(i2s_153p6_base), +}; +CCU_MUX_GATE_DEFINE(i2s_sysclk_src, i2s_sysclk_src_parents, MPMU_ISCCR, 30, 1, BIT(31), 0); + +CCU_DDN_DEFINE(i2s1_sysclk, i2s_sysclk_src, MPMU_ISCCR, 0, 15, 15, 12, 1, 0); + +CCU_DIV_GATE_DEFINE(i2s_bclk, CCU_PARENT_HW(i2s1_sysclk), MPMU_ISCCR, 27, 2, BIT(29), 0); + +static const struct clk_parent_data i2s_sysclk_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_NAME(vctcxo_24m), + CCU_PARENT_HW(pll2_d5), + CCU_PARENT_NAME(vctcxo_24m), +}; +CCU_MUX_DEFINE(i2s0_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 0, 2, 0); +CCU_MUX_DEFINE(i2s2_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 4, 2, 0); +CCU_MUX_DEFINE(i2s3_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 12, 2, 0); +CCU_MUX_DEFINE(i2s4_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 16, 2, 0); +CCU_MUX_DEFINE(i2s5_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 20, 2, 0); + +CCU_DDN_DEFINE(i2s0_sysclk_div, i2s0_sysclk_sel, MPMU_I2S0_SYSCLK, 0, 16, 16, 16, 1, 0); +CCU_DDN_DEFINE(i2s2_sysclk_div, i2s2_sysclk_sel, MPMU_I2S2_SYSCLK, 0, 16, 16, 16, 1, 0); +CCU_DDN_DEFINE(i2s3_sysclk_div, i2s3_sysclk_sel, MPMU_I2S3_SYSCLK, 0, 16, 16, 16, 1, 0); +CCU_DDN_DEFINE(i2s4_sysclk_div, i2s4_sysclk_sel, MPMU_I2S4_SYSCLK, 0, 16, 16, 16, 1, 0); +CCU_DDN_DEFINE(i2s5_sysclk_div, i2s5_sysclk_sel, MPMU_I2S5_SYSCLK, 0, 16, 16, 16, 1, 0); + +static const struct clk_parent_data i2s2_sysclk_parents[] = { + CCU_PARENT_HW(i2s1_sysclk), + CCU_PARENT_HW(i2s2_sysclk_div), +}; +CCU_GATE_DEFINE(i2s0_sysclk, CCU_PARENT_HW(i2s0_sysclk_div), MPMU_I2S_SYSCLK_CTRL, BIT(2), 0); +CCU_MUX_GATE_DEFINE(i2s2_sysclk, i2s2_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 8, 1, BIT(6), 0); +CCU_GATE_DEFINE(i2s3_sysclk, CCU_PARENT_HW(i2s3_sysclk_div), MPMU_I2S_SYSCLK_CTRL, BIT(14), 0); +CCU_GATE_DEFINE(i2s4_sysclk, CCU_PARENT_HW(i2s4_sysclk_div), MPMU_I2S_SYSCLK_CTRL, BIT(18), 0); +CCU_GATE_DEFINE(i2s5_sysclk, CCU_PARENT_HW(i2s5_sysclk_div), MPMU_I2S_SYSCLK_CTRL, BIT(22), 0); +/* MPMU clocks end */ + +/* APBC clocks start */ +static const struct clk_parent_data uart_clk_parents[] = { + CCU_PARENT_HW(pll1_m3d128_57p6), + CCU_PARENT_HW(slow_uart1_14p74), + CCU_PARENT_HW(slow_uart2_48), +}; +CCU_MUX_GATE_DEFINE(uart0_clk, uart_clk_parents, APBC_UART0_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart2_clk, uart_clk_parents, APBC_UART2_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart3_clk, uart_clk_parents, APBC_UART3_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart4_clk, uart_clk_parents, APBC_UART4_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart5_clk, uart_clk_parents, APBC_UART5_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart6_clk, uart_clk_parents, APBC_UART6_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart7_clk, uart_clk_parents, APBC_UART7_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart8_clk, uart_clk_parents, APBC_UART8_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart9_clk, uart_clk_parents, APBC_UART9_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart10_clk, uart_clk_parents, APBC_UART10_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(uart0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART5_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART6_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART7_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart8_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART8_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart9_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART9_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart10_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART10_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(gpio_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_GPIO_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(gpio_bus_clk, CCU_PARENT_HW(apb_clk), APBC_GPIO_CLK_RST, BIT(0), 0); + +static const struct clk_parent_data pwm_parents[] = { + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_NAME(osc_32k), +}; +CCU_MUX_GATE_DEFINE(pwm0_clk, pwm_parents, APBC_PWM0_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm1_clk, pwm_parents, APBC_PWM1_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm2_clk, pwm_parents, APBC_PWM2_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm3_clk, pwm_parents, APBC_PWM3_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm4_clk, pwm_parents, APBC_PWM4_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm5_clk, pwm_parents, APBC_PWM5_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm6_clk, pwm_parents, APBC_PWM6_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm7_clk, pwm_parents, APBC_PWM7_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm8_clk, pwm_parents, APBC_PWM8_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm9_clk, pwm_parents, APBC_PWM9_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm10_clk, pwm_parents, APBC_PWM10_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm11_clk, pwm_parents, APBC_PWM11_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm12_clk, pwm_parents, APBC_PWM12_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm13_clk, pwm_parents, APBC_PWM13_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm14_clk, pwm_parents, APBC_PWM14_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm15_clk, pwm_parents, APBC_PWM15_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm16_clk, pwm_parents, APBC_PWM16_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm17_clk, pwm_parents, APBC_PWM17_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm18_clk, pwm_parents, APBC_PWM18_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm19_clk, pwm_parents, APBC_PWM19_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(pwm0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM5_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM6_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM7_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm8_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM8_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm9_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM9_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm10_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM10_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm11_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM11_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm12_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM12_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm13_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM13_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm14_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM14_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm15_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM15_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm16_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM16_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm17_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM17_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm18_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM18_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm19_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM19_CLK_RST, BIT(0), 0); + +static const struct clk_parent_data i2s_bclk_parents[] = { + CCU_PARENT_NAME(vctcxo_1m), + CCU_PARENT_HW(i2s_bclk), +}; +CCU_MUX_DEFINE(spi0_i2s_bclk, i2s_bclk_parents, APBC_SSP0_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(spi1_i2s_bclk, i2s_bclk_parents, APBC_SSP1_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(spi3_i2s_bclk, i2s_bclk_parents, APBC_SSP3_CLK_RST, 3, 1, 0); + +static const struct clk_parent_data spi0_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(spi0_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(spi0_clk, spi0_parents, APBC_SSP0_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data spi1_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(spi1_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(spi1_clk, spi1_parents, APBC_SSP1_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data spi3_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(spi3_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(spi3_clk, spi3_parents, APBC_SSP3_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(spi0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSP0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(spi1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSP1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(spi3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSP3_CLK_RST, BIT(0), 0); + + +CCU_GATE_DEFINE(rtc_clk, CCU_PARENT_NAME(osc_32k), APBC_RTC_CLK_RST, + BIT(7) | BIT(1), 0); +CCU_GATE_DEFINE(rtc_bus_clk, CCU_PARENT_HW(apb_clk), APBC_RTC_CLK_RST, BIT(0), 0); + +static const struct clk_parent_data twsi_parents[] = { + CCU_PARENT_HW(pll1_d78_31p5), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d40_61p44), +}; +CCU_MUX_GATE_DEFINE(twsi0_clk, twsi_parents, APBC_TWSI0_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi1_clk, twsi_parents, APBC_TWSI1_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi2_clk, twsi_parents, APBC_TWSI2_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi4_clk, twsi_parents, APBC_TWSI4_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi5_clk, twsi_parents, APBC_TWSI5_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi6_clk, twsi_parents, APBC_TWSI6_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi8_clk, twsi_parents, APBC_TWSI8_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(twsi0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI5_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI6_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi8_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI8_CLK_RST, BIT(0), 0); + +static const struct clk_parent_data timer_parents[] = { + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_NAME(osc_32k), + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_NAME(vctcxo_3m), + CCU_PARENT_NAME(vctcxo_1m), +}; +CCU_MUX_GATE_DEFINE(timers0_clk, timer_parents, APBC_TIMERS0_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers1_clk, timer_parents, APBC_TIMERS1_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers2_clk, timer_parents, APBC_TIMERS2_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers3_clk, timer_parents, APBC_TIMERS3_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers4_clk, timer_parents, APBC_TIMERS4_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers5_clk, timer_parents, APBC_TIMERS5_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers6_clk, timer_parents, APBC_TIMERS6_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers7_clk, timer_parents, APBC_TIMERS7_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(timers0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS5_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS6_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS7_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(aib_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_AIB_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(aib_bus_clk, CCU_PARENT_HW(apb_clk), APBC_AIB_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(onewire_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_ONEWIRE_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(onewire_bus_clk, CCU_PARENT_HW(apb_clk), APBC_ONEWIRE_CLK_RST, BIT(0), 0); + +/* + * When i2s_bclk is selected as the parent clock of sspa, + * the hardware requires bit3 to be set + */ + +CCU_MUX_DEFINE(i2s0_i2s_bclk, i2s_bclk_parents, APBC_SSPA0_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(i2s1_i2s_bclk, i2s_bclk_parents, APBC_SSPA1_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(i2s2_i2s_bclk, i2s_bclk_parents, APBC_SSPA2_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(i2s3_i2s_bclk, i2s_bclk_parents, APBC_SSPA3_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(i2s4_i2s_bclk, i2s_bclk_parents, APBC_SSPA4_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(i2s5_i2s_bclk, i2s_bclk_parents, APBC_SSPA5_CLK_RST, 3, 1, 0); + +static const struct clk_parent_data i2s0_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s0_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s0_clk, i2s0_parents, APBC_SSPA0_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data i2s1_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s1_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s1_clk, i2s1_parents, APBC_SSPA1_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data i2s2_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s2_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s2_clk, i2s2_parents, APBC_SSPA2_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data i2s3_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s3_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s3_clk, i2s3_parents, APBC_SSPA3_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data i2s4_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s4_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s4_clk, i2s4_parents, APBC_SSPA4_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data i2s5_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s5_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s5_clk, i2s5_parents, APBC_SSPA5_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(i2s0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(i2s1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(i2s2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(i2s3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(i2s4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(i2s5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA5_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(dro_clk, CCU_PARENT_HW(apb_clk), APBC_DRO_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(ir0_clk, CCU_PARENT_HW(apb_clk), APBC_IR0_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(ir1_clk, CCU_PARENT_HW(apb_clk), APBC_IR1_CLK_RST, BIT(1), 0); + +CCU_GATE_DEFINE(tsen_clk, CCU_PARENT_HW(apb_clk), APBC_TSEN_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(tsen_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TSEN_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(ipc_ap2rcpu_clk, CCU_PARENT_HW(apb_clk), APBC_IPC_AP2AUD_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(ipc_ap2rcpu_bus_clk, CCU_PARENT_HW(apb_clk), APBC_IPC_AP2AUD_CLK_RST, BIT(0), 0); + +static const struct clk_parent_data can_parents[] = { + CCU_PARENT_HW(pll6_20), + CCU_PARENT_HW(pll6_40), + CCU_PARENT_HW(pll6_80), +}; +CCU_MUX_GATE_DEFINE(can0_clk, can_parents, APBC_CAN0_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(can1_clk, can_parents, APBC_CAN1_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(can2_clk, can_parents, APBC_CAN2_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(can3_clk, can_parents, APBC_CAN3_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(can4_clk, can_parents, APBC_CAN4_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(can0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_CAN0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(can1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_CAN1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(can2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_CAN2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(can3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_CAN3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(can4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_CAN4_CLK_RST, BIT(0), 0); +/* APBC clocks end */ + +/* APMU clocks start */ +static const struct clk_parent_data axi_clk_parents[] = { + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d6_409p6), +}; +CCU_MUX_DIV_FC_DEFINE(axi_clk, axi_clk_parents, APMU_ACLK_CLK_CTRL, 1, 2, BIT(4), 0, 1, 0); + +static const struct clk_parent_data cci550_clk_parents[] = { + CCU_PARENT_HW(pll1_d10_245p76), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll7_d3), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll7_d2), +}; +CCU_MUX_DIV_FC_DEFINE(cci550_clk, cci550_clk_parents, APMU_CCI550_CLK_CTRL, 8, 2, BIT(12), 0, 3, + CLK_IS_CRITICAL); + +static const struct clk_parent_data cpu_c0_clk_parents[] = { + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll3_d2), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll3_d1), +}; +CCU_MUX_DIV_FC_DEFINE(cpu_c0_core_clk, cpu_c0_clk_parents, APMU_CPU_C0_CLK_CTRL, + 3, 3, BIT(12), 0, 3, CLK_IS_CRITICAL); + +static const struct clk_parent_data cpu_c1_clk_parents[] = { + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll4_d2), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll4_d1), +}; +CCU_MUX_DIV_FC_DEFINE(cpu_c1_core_clk, cpu_c1_clk_parents, APMU_CPU_C1_CLK_CTRL, + 3, 3, BIT(12), 0, 3, CLK_IS_CRITICAL); + +static const struct clk_parent_data cpu_c2_clk_parents[] = { + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll5_d2), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll5_d1), +}; +CCU_MUX_DIV_FC_DEFINE(cpu_c2_core_clk, cpu_c2_clk_parents, APMU_CPU_C2_CLK_CTRL, + 3, 3, BIT(12), 0, 3, CLK_IS_CRITICAL); + +static const struct clk_parent_data cpu_c3_clk_parents[] = { + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll8_d2), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll8_d1), +}; +CCU_MUX_DIV_FC_DEFINE(cpu_c3_core_clk, cpu_c3_clk_parents, APMU_CPU_C3_CLK_CTRL, + 3, 3, BIT(12), 0, 3, CLK_IS_CRITICAL); + +static const struct clk_parent_data ccic2phy_parents[] = { + CCU_PARENT_HW(pll1_d24_102p4), + CCU_PARENT_HW(pll1_d48_51p2_ap), +}; +CCU_MUX_GATE_DEFINE(ccic2phy_clk, ccic2phy_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, 7, 1, BIT(5), 0); + +static const struct clk_parent_data ccic3phy_parents[] = { + CCU_PARENT_HW(pll1_d24_102p4), + CCU_PARENT_HW(pll1_d48_51p2_ap), +}; +CCU_MUX_GATE_DEFINE(ccic3phy_clk, ccic3phy_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, 31, 1, BIT(30), 0); + +static const struct clk_parent_data csi_parents[] = { + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d2_1228p8), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(csi_clk, csi_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, 20, 3, BIT(15), + 16, 3, BIT(4), 0); + +static const struct clk_parent_data isp_bus_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d10_245p76), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(isp_bus_clk, isp_bus_parents, APMU_ISP_CLK_RES_CTRL, 18, 3, BIT(23), + 21, 2, BIT(17), 0); + +CCU_GATE_DEFINE(d1p_1228p8, CCU_PARENT_HW(pll1_d2_1228p8), APMU_PMU_CLK_GATE_CTRL, BIT(31), 0); +CCU_GATE_DEFINE(d1p_819p2, CCU_PARENT_HW(pll1_d3_819p2), APMU_PMU_CLK_GATE_CTRL, BIT(30), 0); +CCU_GATE_DEFINE(d1p_614p4, CCU_PARENT_HW(pll1_d4_614p4), APMU_PMU_CLK_GATE_CTRL, BIT(29), 0); +CCU_GATE_DEFINE(d1p_491p52, CCU_PARENT_HW(pll1_d5_491p52), APMU_PMU_CLK_GATE_CTRL, BIT(28), 0); +CCU_GATE_DEFINE(d1p_409p6, CCU_PARENT_HW(pll1_d6_409p6), APMU_PMU_CLK_GATE_CTRL, BIT(27), 0); +CCU_GATE_DEFINE(d1p_307p2, CCU_PARENT_HW(pll1_d8_307p2), APMU_PMU_CLK_GATE_CTRL, BIT(26), 0); +CCU_GATE_DEFINE(d1p_245p76, CCU_PARENT_HW(pll1_d10_245p76), APMU_PMU_CLK_GATE_CTRL, BIT(22), 0); + +static const struct clk_parent_data v2d_parents[] = { + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d4_614p4), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(v2d_clk, v2d_parents, APMU_LCD_CLK_RES_CTRL1, 9, 3, BIT(28), 12, 2, + BIT(8), 0); + +static const struct clk_parent_data dsiesc_parents[] = { + CCU_PARENT_HW(pll1_d48_51p2_ap), + CCU_PARENT_HW(pll1_d52_47p26), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d32_76p8), +}; +CCU_MUX_GATE_DEFINE(dsi_esc_clk, dsiesc_parents, APMU_LCD_CLK_RES_CTRL1, 0, 2, BIT(2), 0); + +CCU_GATE_DEFINE(lcd_hclk, CCU_PARENT_HW(axi_clk), APMU_LCD_CLK_RES_CTRL1, BIT(5), 0); + +static const struct clk_parent_data lcd_dsc_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d10_245p76), + CCU_PARENT_HW(pll7_d5), + CCU_PARENT_HW(pll2_d7), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d48_51p2_ap), + CCU_PARENT_HW(pll2_d8), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(lcd_dsc_clk, lcd_dsc_parents, APMU_LCD_CLK_RES_CTRL2, + APMU_LCD_CLK_RES_CTRL1, 25, 3, BIT(26), 29, 3, BIT(14), 0); + +static const struct clk_parent_data lcdpx_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d10_245p76), + CCU_PARENT_HW(pll7_d5), + CCU_PARENT_HW(pll2_d7), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d48_51p2_ap), + CCU_PARENT_HW(pll2_d8), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(lcd_pxclk, lcdpx_parents, APMU_LCD_CLK_RES_CTRL2, + APMU_LCD_CLK_RES_CTRL1, 17, 3, BIT(30), 21, 3, BIT(16), 0); + +static const struct clk_parent_data lcdmclk_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(lcd_mclk, lcdmclk_parents, APMU_LCD_CLK_RES_CTRL2, + APMU_LCD_CLK_RES_CTRL1, 1, 4, BIT(29), 5, 3, BIT(0), 0); + +static const struct clk_parent_data ccic_4x_parents[] = { + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d2_1228p8), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(ccic_4x_clk, ccic_4x_parents, APMU_CCIC_CLK_RES_CTRL, 18, 3, + BIT(15), 23, 2, BIT(4), 0); + +static const struct clk_parent_data ccic1phy_parents[] = { + CCU_PARENT_HW(pll1_d24_102p4), + CCU_PARENT_HW(pll1_d48_51p2_ap), +}; +CCU_MUX_GATE_DEFINE(ccic1phy_clk, ccic1phy_parents, APMU_CCIC_CLK_RES_CTRL, 7, 1, BIT(5), 0); + + +static const struct clk_parent_data sc2hclk_parents[] = { + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll2_d4), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(sc2_hclk, sc2hclk_parents, APMU_CCIC_CLK_RES_CTRL, 10, 3, + BIT(16), 8, 2, BIT(3), 0); + +CCU_GATE_DEFINE(sdh_axi_aclk, CCU_PARENT_HW(axi_clk), APMU_SDH0_CLK_RES_CTRL, BIT(3), 0); +static const struct clk_parent_data sdh01_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d8), + CCU_PARENT_HW(pll2_d5), + CCU_PARENT_NAME(reserved_clk), + CCU_PARENT_NAME(reserved_clk), + CCU_PARENT_HW(pll1_dx), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(sdh0_clk, sdh01_parents, APMU_SDH0_CLK_RES_CTRL, 8, 3, + BIT(11), 5, 3, BIT(4), 0); +CCU_MUX_DIV_GATE_FC_DEFINE(sdh1_clk, sdh01_parents, APMU_SDH1_CLK_RES_CTRL, 8, 3, + BIT(11), 5, 3, BIT(4), 0); +static const struct clk_parent_data sdh2_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d8), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_NAME(reserved_clk), + CCU_PARENT_NAME(reserved_clk), + CCU_PARENT_HW(pll1_dx), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(sdh2_clk, sdh2_parents, APMU_SDH2_CLK_RES_CTRL, 8, 3, + BIT(11), 5, 3, BIT(4), 0); + +CCU_GATE_DEFINE(usb2_bus_clk, CCU_PARENT_HW(axi_clk), APMU_USB_CLK_RES_CTRL, BIT(0), 0); +CCU_GATE_DEFINE(usb3_porta_bus_clk, CCU_PARENT_HW(axi_clk), APMU_USB_CLK_RES_CTRL, BIT(4), 0); +CCU_GATE_DEFINE(usb3_portb_bus_clk, CCU_PARENT_HW(axi_clk), APMU_USB_CLK_RES_CTRL, BIT(8), 0); +CCU_GATE_DEFINE(usb3_portc_bus_clk, CCU_PARENT_HW(axi_clk), APMU_USB_CLK_RES_CTRL, BIT(12), 0); +CCU_GATE_DEFINE(usb3_portd_bus_clk, CCU_PARENT_HW(axi_clk), APMU_USB_CLK_RES_CTRL, BIT(16), 0); + +static const struct clk_parent_data qspi_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll2_d8), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d10_245p76), + CCU_PARENT_NAME(reserved_clk), + CCU_PARENT_HW(pll1_dx), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_NAME(reserved_clk), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(qspi_clk, qspi_parents, APMU_QSPI_CLK_RES_CTRL, 9, 3, + BIT(12), 6, 3, BIT(4), 0); +CCU_GATE_DEFINE(qspi_bus_clk, CCU_PARENT_HW(axi_clk), APMU_QSPI_CLK_RES_CTRL, BIT(3), 0); + +CCU_GATE_DEFINE(dma_clk, CCU_PARENT_HW(axi_clk), APMU_DMA_CLK_RES_CTRL, BIT(3), 0); + +static const struct clk_parent_data aes_wtm_parents[] = { + CCU_PARENT_HW(pll1_d12_204p8), + CCU_PARENT_HW(pll1_d24_102p4), +}; +CCU_MUX_GATE_DEFINE(aes_wtm_clk, aes_wtm_parents, APMU_AES_CLK_RES_CTRL, 6, 1, BIT(5), 0); + +static const struct clk_parent_data vpu_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll2_d5), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(vpu_clk, vpu_parents, APMU_VPU_CLK_RES_CTRL, 13, 3, + BIT(21), 10, 3, BIT(3), 0); + +CCU_GATE_DEFINE(dtc_clk, CCU_PARENT_HW(axi_clk), APMU_DTC_CLK_RES_CTRL, BIT(3), 0); + +static const struct clk_parent_data gpu_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll2_d5), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(gpu_clk, gpu_parents, APMU_GPU_CLK_RES_CTRL, 12, 3, + BIT(15), 18, 3, BIT(4), 0); + +CCU_GATE_DEFINE(mc_ahb_clk, CCU_PARENT_HW(axi_clk), APMU_PMUA_MC_CTRL, BIT(1), 0); + +static const struct clk_parent_data top_parents[] = { + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll3_d4), + CCU_PARENT_HW(pll6_d5), + CCU_PARENT_HW(pll7_d4), + CCU_PARENT_HW(pll6_d4), + CCU_PARENT_HW(pll7_d3), + CCU_PARENT_HW(pll6_d3), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(top_dclk, top_parents, APMU_TOP_DCLK_CTRL, 5, 3, + BIT(8), 2, 3, BIT(1), 0); + +static const struct clk_parent_data ucie_parents[] = { + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll3_d4), + CCU_PARENT_HW(pll6_d5), + CCU_PARENT_HW(pll7_d4), + CCU_PARENT_HW(pll6_d4), +}; +CCU_MUX_GATE_DEFINE(ucie_clk, ucie_parents, APMU_UCIE_CTRL, 4, 3, BIT(0), 0); +CCU_GATE_DEFINE(ucie_sbclk, CCU_PARENT_HW(axi_clk), APMU_UCIE_CTRL, BIT(8), 0); + +static const struct clk_parent_data rcpu_clk_parents[] = { + CCU_PARENT_HW(pll1_aud_245p7), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d6_409p6), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(rcpu_clk, rcpu_clk_parents, APMU_RCPU_CLK_RES_CTRL, + 4, 3, BIT(15), 7, 3, BIT(12), 0); + +static const struct clk_parent_data dsi4ln2_dsi_esc_parents[] = { + CCU_PARENT_HW(pll1_d48_51p2_ap), + CCU_PARENT_HW(pll1_d52_47p26), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d32_76p8), +}; +CCU_MUX_GATE_DEFINE(dsi4ln2_dsi_esc_clk, dsi4ln2_dsi_esc_parents, APMU_LCD_CLK_RES_CTRL3, + 0, 1, BIT(2), 0); + +static const struct clk_parent_data dsi4ln2_lcd_dsc_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll7_d5), + CCU_PARENT_HW(pll6_d6), + CCU_PARENT_HW(pll2_d7), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d48_51p2_ap), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(dsi4ln2_lcd_dsc_clk, dsi4ln2_lcd_dsc_parents, + APMU_LCD_CLK_RES_CTRL4, APMU_LCD_CLK_RES_CTRL3, + 25, 3, BIT(26), 29, 3, BIT(14), 0); + +static const struct clk_parent_data dsi4ln2_lcdpx_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll7_d5), + CCU_PARENT_HW(pll6_d6), + CCU_PARENT_HW(pll2_d7), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d48_51p2_ap), + CCU_PARENT_HW(pll2_d8), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(dsi4ln2_lcd_pxclk, dsi4ln2_lcdpx_parents, APMU_LCD_CLK_RES_CTRL4, + APMU_LCD_CLK_RES_CTRL3, 17, 3, BIT(30), 21, 3, BIT(16), 0); + +static const struct clk_parent_data dsi4ln2_lcd_mclk_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(dsi4ln2_lcd_mclk, dsi4ln2_lcd_mclk_parents, APMU_LCD_CLK_RES_CTRL4, + APMU_LCD_CLK_RES_CTRL3, 1, 4, BIT(29), 5, 3, BIT(0), 0); + +static const struct clk_parent_data dpu_aclk_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll2_d4), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(dsi4ln2_dpu_aclk, dpu_aclk_parents, APMU_LCD_CLK_RES_CTRL5, + 2, 3, BIT(30), 5, 3, BIT(1), 0); + +CCU_MUX_DIV_GATE_FC_DEFINE(dpu_aclk, dpu_aclk_parents, APMU_LCD_CLK_RES_CTRL5, 17, 3, BIT(31), + 20, 3, BIT(16), 0); + +static const struct clk_parent_data ufs_aclk_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll2_d4), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(ufs_aclk, ufs_aclk_parents, APMU_UFS_CLK_RES_CTRL, 5, 3, BIT(8), + 2, 3, BIT(1), 0); + +static const struct clk_parent_data edp0_pclk_parents[] = { + CCU_PARENT_HW(lcd_pxclk), + CCU_PARENT_NAME(external_clk), +}; +CCU_MUX_GATE_DEFINE(edp0_pxclk, edp0_pclk_parents, APMU_LCD_EDP_CTRL, 2, 1, BIT(1), 0); + +static const struct clk_parent_data edp1_pclk_parents[] = { + CCU_PARENT_HW(dsi4ln2_lcd_pxclk), + CCU_PARENT_NAME(external_clk), +}; +CCU_MUX_GATE_DEFINE(edp1_pxclk, edp1_pclk_parents, APMU_LCD_EDP_CTRL, 18, 1, BIT(17), 0); + +CCU_GATE_DEFINE(pciea_mstr_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_A, BIT(2), 0); +CCU_GATE_DEFINE(pciea_slv_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_A, BIT(1), 0); +CCU_GATE_DEFINE(pcieb_mstr_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_B, BIT(2), 0); +CCU_GATE_DEFINE(pcieb_slv_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_B, BIT(1), 0); +CCU_GATE_DEFINE(pciec_mstr_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_C, BIT(2), 0); +CCU_GATE_DEFINE(pciec_slv_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_C, BIT(1), 0); +CCU_GATE_DEFINE(pcied_mstr_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_D, BIT(2), 0); +CCU_GATE_DEFINE(pcied_slv_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_D, BIT(1), 0); +CCU_GATE_DEFINE(pciee_mstr_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_E, BIT(2), 0); +CCU_GATE_DEFINE(pciee_slv_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_E, BIT(1), 0); + +static const struct clk_parent_data emac_1588_parents[] = { + CCU_PARENT_NAME(vctcxo_24m), + CCU_PARENT_HW(pll2_d24_125), +}; + +CCU_GATE_DEFINE(emac0_bus_clk, CCU_PARENT_HW(axi_clk), APMU_EMAC0_CLK_RES_CTRL, BIT(0), 0); +CCU_GATE_FLAGS_DEFINE(emac0_ref_clk, CCU_PARENT_HW(pll2_d120_25), APMU_EMAC0_CLK_RES_CTRL, + BIT(14), true, 0); +CCU_MUX_DEFINE(emac0_1588_clk, emac_1588_parents, APMU_EMAC0_CLK_RES_CTRL, 15, 1, 0); +CCU_GATE_DEFINE(emac0_rgmii_tx_clk, CCU_PARENT_HW(pll2_d24_125), APMU_EMAC0_CLK_RES_CTRL, + BIT(8), 0); +CCU_GATE_DEFINE(emac1_bus_clk, CCU_PARENT_HW(axi_clk), APMU_EMAC1_CLK_RES_CTRL, BIT(0), 0); +CCU_GATE_FLAGS_DEFINE(emac1_ref_clk, CCU_PARENT_HW(pll2_d120_25), APMU_EMAC1_CLK_RES_CTRL, + BIT(14), true, 0); +CCU_MUX_DEFINE(emac1_1588_clk, emac_1588_parents, APMU_EMAC1_CLK_RES_CTRL, 15, 1, 0); +CCU_GATE_DEFINE(emac1_rgmii_tx_clk, CCU_PARENT_HW(pll2_d24_125), APMU_EMAC1_CLK_RES_CTRL, + BIT(8), 0); +CCU_GATE_DEFINE(emac2_bus_clk, CCU_PARENT_HW(axi_clk), APMU_EMAC2_CLK_RES_CTRL, BIT(0), 0); +CCU_GATE_FLAGS_DEFINE(emac2_ref_clk, CCU_PARENT_HW(pll2_d120_25), APMU_EMAC2_CLK_RES_CTRL, + BIT(14), true, 0); +CCU_MUX_DEFINE(emac2_1588_clk, emac_1588_parents, APMU_EMAC2_CLK_RES_CTRL, 15, 1, 0); +CCU_GATE_DEFINE(emac2_rgmii_tx_clk, CCU_PARENT_HW(pll2_d24_125), APMU_EMAC2_CLK_RES_CTRL, + BIT(8), 0); + +static const struct clk_parent_data espi_sclk_src_parents[] = { + CCU_PARENT_HW(pll2_20), + CCU_PARENT_HW(pll2_25), + CCU_PARENT_HW(pll2_33), + CCU_PARENT_HW(pll2_50), + CCU_PARENT_HW(pll2_66), +}; +CCU_MUX_DEFINE(espi_sclk_src, espi_sclk_src_parents, APMU_ESPI_CLK_RES_CTRL, 4, 3, 0); + +static const struct clk_parent_data espi_sclk_parents[] = { + CCU_PARENT_NAME(external_clk), + CCU_PARENT_HW(espi_sclk_src), +}; +CCU_MUX_GATE_DEFINE(espi_sclk, espi_sclk_parents, APMU_ESPI_CLK_RES_CTRL, 7, 1, BIT(3), 0); + +CCU_GATE_DEFINE(espi_mclk, CCU_PARENT_HW(axi_clk), APMU_ESPI_CLK_RES_CTRL, BIT(1), 0); + +CCU_FACTOR_DEFINE(cam_src1_clk, CCU_PARENT_HW(pll1_d6_409p6), 15, 1); +CCU_FACTOR_DEFINE(cam_src2_clk, CCU_PARENT_HW(pll2_d5), 25, 1); +CCU_FACTOR_DEFINE(cam_src3_clk, CCU_PARENT_HW(pll2_d6), 20, 1); +CCU_FACTOR_DEFINE(cam_src4_clk, CCU_PARENT_HW(pll1_d6_409p6), 16, 1); + +static const struct clk_parent_data isim_vclk_parents[] = { + CCU_PARENT_HW(cam_src1_clk), + CCU_PARENT_HW(cam_src2_clk), + CCU_PARENT_HW(cam_src3_clk), + CCU_PARENT_HW(cam_src4_clk), +}; +CCU_MUX_DIV_GATE_DEFINE(isim_vclk_out0, isim_vclk_parents, APMU_SNR_ISIM_VCLK_CTRL, 3, 4, + 1, 2, BIT(0), 0); +CCU_MUX_DIV_GATE_DEFINE(isim_vclk_out1, isim_vclk_parents, APMU_SNR_ISIM_VCLK_CTRL, 11, 4, + 9, 2, BIT(8), 0); +CCU_MUX_DIV_GATE_DEFINE(isim_vclk_out2, isim_vclk_parents, APMU_SNR_ISIM_VCLK_CTRL, 19, 4, + 17, 2, BIT(16), 0); +CCU_MUX_DIV_GATE_DEFINE(isim_vclk_out3, isim_vclk_parents, APMU_SNR_ISIM_VCLK_CTRL, 27, 4, + 25, 2, BIT(24), 0); +/* APMU clocks end */ + +/* DCIU clocks start */ +CCU_GATE_DEFINE(hdma_clk, CCU_PARENT_HW(axi_clk), DCIU_DMASYS_CLK_EN, BIT(0), 0); +CCU_GATE_DEFINE(dma350_clk, CCU_PARENT_HW(axi_clk), DCIU_DMASYS_SDMA_CLK_EN, BIT(0), 0); +CCU_GATE_DEFINE(c2_tcm_pipe_clk, CCU_PARENT_HW(axi_clk), DCIU_C2_TCM_PIPE_CLK, BIT(0), 0); +CCU_GATE_DEFINE(c3_tcm_pipe_clk, CCU_PARENT_HW(axi_clk), DCIU_C3_TCM_PIPE_CLK, BIT(0), 0); +/* DCIU clocks end */ + +static struct clk_hw *k3_ccu_pll_hws[] = { + [CLK_PLL1] = &pll1.common.hw, + [CLK_PLL2] = &pll2.common.hw, + [CLK_PLL3] = &pll3.common.hw, + [CLK_PLL4] = &pll4.common.hw, + [CLK_PLL5] = &pll5.common.hw, + [CLK_PLL6] = &pll6.common.hw, + [CLK_PLL7] = &pll7.common.hw, + [CLK_PLL8] = &pll8.common.hw, + [CLK_PLL1_D2] = &pll1_d2.common.hw, + [CLK_PLL1_D3] = &pll1_d3.common.hw, + [CLK_PLL1_D4] = &pll1_d4.common.hw, + [CLK_PLL1_D5] = &pll1_d5.common.hw, + [CLK_PLL1_D6] = &pll1_d6.common.hw, + [CLK_PLL1_D7] = &pll1_d7.common.hw, + [CLK_PLL1_D8] = &pll1_d8.common.hw, + [CLK_PLL1_DX] = &pll1_dx.common.hw, + [CLK_PLL1_D64] = &pll1_d64_38p4.common.hw, + [CLK_PLL1_D10_AUD] = &pll1_aud_245p7.common.hw, + [CLK_PLL1_D100_AUD] = &pll1_aud_24p5.common.hw, + [CLK_PLL2_D1] = &pll2_d1.common.hw, + [CLK_PLL2_D2] = &pll2_d2.common.hw, + [CLK_PLL2_D3] = &pll2_d3.common.hw, + [CLK_PLL2_D4] = &pll2_d4.common.hw, + [CLK_PLL2_D5] = &pll2_d5.common.hw, + [CLK_PLL2_D6] = &pll2_d6.common.hw, + [CLK_PLL2_D7] = &pll2_d7.common.hw, + [CLK_PLL2_D8] = &pll2_d8.common.hw, + [CLK_PLL2_66] = &pll2_66.common.hw, + [CLK_PLL2_33] = &pll2_33.common.hw, + [CLK_PLL2_50] = &pll2_50.common.hw, + [CLK_PLL2_25] = &pll2_25.common.hw, + [CLK_PLL2_20] = &pll2_20.common.hw, + [CLK_PLL2_D24_125] = &pll2_d24_125.common.hw, + [CLK_PLL2_D120_25] = &pll2_d120_25.common.hw, + [CLK_PLL3_D1] = &pll3_d1.common.hw, + [CLK_PLL3_D2] = &pll3_d2.common.hw, + [CLK_PLL3_D3] = &pll3_d3.common.hw, + [CLK_PLL3_D4] = &pll3_d4.common.hw, + [CLK_PLL3_D5] = &pll3_d5.common.hw, + [CLK_PLL3_D6] = &pll3_d6.common.hw, + [CLK_PLL3_D7] = &pll3_d7.common.hw, + [CLK_PLL3_D8] = &pll3_d8.common.hw, + [CLK_PLL4_D1] = &pll4_d1.common.hw, + [CLK_PLL4_D2] = &pll4_d2.common.hw, + [CLK_PLL4_D3] = &pll4_d3.common.hw, + [CLK_PLL4_D4] = &pll4_d4.common.hw, + [CLK_PLL4_D5] = &pll4_d5.common.hw, + [CLK_PLL4_D6] = &pll4_d6.common.hw, + [CLK_PLL4_D7] = &pll4_d7.common.hw, + [CLK_PLL4_D8] = &pll4_d8.common.hw, + [CLK_PLL5_D1] = &pll5_d1.common.hw, + [CLK_PLL5_D2] = &pll5_d2.common.hw, + [CLK_PLL5_D3] = &pll5_d3.common.hw, + [CLK_PLL5_D4] = &pll5_d4.common.hw, + [CLK_PLL5_D5] = &pll5_d5.common.hw, + [CLK_PLL5_D6] = &pll5_d6.common.hw, + [CLK_PLL5_D7] = &pll5_d7.common.hw, + [CLK_PLL5_D8] = &pll5_d8.common.hw, + [CLK_PLL6_D1] = &pll6_d1.common.hw, + [CLK_PLL6_D2] = &pll6_d2.common.hw, + [CLK_PLL6_D3] = &pll6_d3.common.hw, + [CLK_PLL6_D4] = &pll6_d4.common.hw, + [CLK_PLL6_D5] = &pll6_d5.common.hw, + [CLK_PLL6_D6] = &pll6_d6.common.hw, + [CLK_PLL6_D7] = &pll6_d7.common.hw, + [CLK_PLL6_D8] = &pll6_d8.common.hw, + [CLK_PLL6_80] = &pll6_80.common.hw, + [CLK_PLL6_40] = &pll6_40.common.hw, + [CLK_PLL6_20] = &pll6_20.common.hw, + [CLK_PLL7_D1] = &pll7_d1.common.hw, + [CLK_PLL7_D2] = &pll7_d2.common.hw, + [CLK_PLL7_D3] = &pll7_d3.common.hw, + [CLK_PLL7_D4] = &pll7_d4.common.hw, + [CLK_PLL7_D5] = &pll7_d5.common.hw, + [CLK_PLL7_D6] = &pll7_d6.common.hw, + [CLK_PLL7_D7] = &pll7_d7.common.hw, + [CLK_PLL7_D8] = &pll7_d8.common.hw, + [CLK_PLL8_D1] = &pll8_d1.common.hw, + [CLK_PLL8_D2] = &pll8_d2.common.hw, + [CLK_PLL8_D3] = &pll8_d3.common.hw, + [CLK_PLL8_D4] = &pll8_d4.common.hw, + [CLK_PLL8_D5] = &pll8_d5.common.hw, + [CLK_PLL8_D6] = &pll8_d6.common.hw, + [CLK_PLL8_D7] = &pll8_d7.common.hw, + [CLK_PLL8_D8] = &pll8_d8.common.hw, +}; + +static const struct spacemit_ccu_data k3_ccu_pll_data = { + /* The APBS CCU implements PLLs, but no resets */ + .hws = k3_ccu_pll_hws, + .num = ARRAY_SIZE(k3_ccu_pll_hws), +}; + +static struct clk_hw *k3_ccu_mpmu_hws[] = { + [CLK_MPMU_PLL1_307P2] = &pll1_d8_307p2.common.hw, + [CLK_MPMU_PLL1_76P8] = &pll1_d32_76p8.common.hw, + [CLK_MPMU_PLL1_61P44] = &pll1_d40_61p44.common.hw, + [CLK_MPMU_PLL1_153P6] = &pll1_d16_153p6.common.hw, + [CLK_MPMU_PLL1_102P4] = &pll1_d24_102p4.common.hw, + [CLK_MPMU_PLL1_51P2] = &pll1_d48_51p2.common.hw, + [CLK_MPMU_PLL1_51P2_AP] = &pll1_d48_51p2_ap.common.hw, + [CLK_MPMU_PLL1_57P6] = &pll1_m3d128_57p6.common.hw, + [CLK_MPMU_PLL1_25P6] = &pll1_d96_25p6.common.hw, + [CLK_MPMU_PLL1_12P8] = &pll1_d192_12p8.common.hw, + [CLK_MPMU_PLL1_12P8_WDT] = &pll1_d192_12p8_wdt.common.hw, + [CLK_MPMU_PLL1_6P4] = &pll1_d384_6p4.common.hw, + [CLK_MPMU_PLL1_3P2] = &pll1_d768_3p2.common.hw, + [CLK_MPMU_PLL1_1P6] = &pll1_d1536_1p6.common.hw, + [CLK_MPMU_PLL1_0P8] = &pll1_d3072_0p8.common.hw, + [CLK_MPMU_PLL1_409P6] = &pll1_d6_409p6.common.hw, + [CLK_MPMU_PLL1_204P8] = &pll1_d12_204p8.common.hw, + [CLK_MPMU_PLL1_491] = &pll1_d5_491p52.common.hw, + [CLK_MPMU_PLL1_245P76] = &pll1_d10_245p76.common.hw, + [CLK_MPMU_PLL1_614] = &pll1_d4_614p4.common.hw, + [CLK_MPMU_PLL1_47P26] = &pll1_d52_47p26.common.hw, + [CLK_MPMU_PLL1_31P5] = &pll1_d78_31p5.common.hw, + [CLK_MPMU_PLL1_819] = &pll1_d3_819p2.common.hw, + [CLK_MPMU_PLL1_1228] = &pll1_d2_1228p8.common.hw, + [CLK_MPMU_APB] = &apb_clk.common.hw, + [CLK_MPMU_SLOW_UART] = &slow_uart.common.hw, + [CLK_MPMU_SLOW_UART1] = &slow_uart1_14p74.common.hw, + [CLK_MPMU_SLOW_UART2] = &slow_uart2_48.common.hw, + [CLK_MPMU_WDT] = &wdt_clk.common.hw, + [CLK_MPMU_WDT_BUS] = &wdt_bus_clk.common.hw, + [CLK_MPMU_RIPC] = &r_ipc_clk.common.hw, + [CLK_MPMU_I2S_153P6] = &i2s_153p6.common.hw, + [CLK_MPMU_I2S_153P6_BASE] = &i2s_153p6_base.common.hw, + [CLK_MPMU_I2S_SYSCLK_SRC] = &i2s_sysclk_src.common.hw, + [CLK_MPMU_I2S1_SYSCLK] = &i2s1_sysclk.common.hw, + [CLK_MPMU_I2S_BCLK] = &i2s_bclk.common.hw, + [CLK_MPMU_I2S0_SYSCLK_SEL] = &i2s0_sysclk_sel.common.hw, + [CLK_MPMU_I2S2_SYSCLK_SEL] = &i2s2_sysclk_sel.common.hw, + [CLK_MPMU_I2S3_SYSCLK_SEL] = &i2s3_sysclk_sel.common.hw, + [CLK_MPMU_I2S4_SYSCLK_SEL] = &i2s4_sysclk_sel.common.hw, + [CLK_MPMU_I2S5_SYSCLK_SEL] = &i2s5_sysclk_sel.common.hw, + [CLK_MPMU_I2S0_SYSCLK_DIV] = &i2s0_sysclk_div.common.hw, + [CLK_MPMU_I2S2_SYSCLK_DIV] = &i2s2_sysclk_div.common.hw, + [CLK_MPMU_I2S3_SYSCLK_DIV] = &i2s3_sysclk_div.common.hw, + [CLK_MPMU_I2S4_SYSCLK_DIV] = &i2s4_sysclk_div.common.hw, + [CLK_MPMU_I2S5_SYSCLK_DIV] = &i2s5_sysclk_div.common.hw, + [CLK_MPMU_I2S0_SYSCLK] = &i2s0_sysclk.common.hw, + [CLK_MPMU_I2S2_SYSCLK] = &i2s2_sysclk.common.hw, + [CLK_MPMU_I2S3_SYSCLK] = &i2s3_sysclk.common.hw, + [CLK_MPMU_I2S4_SYSCLK] = &i2s4_sysclk.common.hw, + [CLK_MPMU_I2S5_SYSCLK] = &i2s5_sysclk.common.hw, +}; + +static const struct spacemit_ccu_data k3_ccu_mpmu_data = { + .reset_name = "k3-mpmu-reset", + .hws = k3_ccu_mpmu_hws, + .num = ARRAY_SIZE(k3_ccu_mpmu_hws), +}; + +static struct clk_hw *k3_ccu_apbc_hws[] = { + [CLK_APBC_UART0] = &uart0_clk.common.hw, + [CLK_APBC_UART2] = &uart2_clk.common.hw, + [CLK_APBC_UART3] = &uart3_clk.common.hw, + [CLK_APBC_UART4] = &uart4_clk.common.hw, + [CLK_APBC_UART5] = &uart5_clk.common.hw, + [CLK_APBC_UART6] = &uart6_clk.common.hw, + [CLK_APBC_UART7] = &uart7_clk.common.hw, + [CLK_APBC_UART8] = &uart8_clk.common.hw, + [CLK_APBC_UART9] = &uart9_clk.common.hw, + [CLK_APBC_UART10] = &uart10_clk.common.hw, + [CLK_APBC_UART0_BUS] = &uart0_bus_clk.common.hw, + [CLK_APBC_UART2_BUS] = &uart2_bus_clk.common.hw, + [CLK_APBC_UART3_BUS] = &uart3_bus_clk.common.hw, + [CLK_APBC_UART4_BUS] = &uart4_bus_clk.common.hw, + [CLK_APBC_UART5_BUS] = &uart5_bus_clk.common.hw, + [CLK_APBC_UART6_BUS] = &uart6_bus_clk.common.hw, + [CLK_APBC_UART7_BUS] = &uart7_bus_clk.common.hw, + [CLK_APBC_UART8_BUS] = &uart8_bus_clk.common.hw, + [CLK_APBC_UART9_BUS] = &uart9_bus_clk.common.hw, + [CLK_APBC_UART10_BUS] = &uart10_bus_clk.common.hw, + [CLK_APBC_GPIO] = &gpio_clk.common.hw, + [CLK_APBC_GPIO_BUS] = &gpio_bus_clk.common.hw, + [CLK_APBC_PWM0] = &pwm0_clk.common.hw, + [CLK_APBC_PWM1] = &pwm1_clk.common.hw, + [CLK_APBC_PWM2] = &pwm2_clk.common.hw, + [CLK_APBC_PWM3] = &pwm3_clk.common.hw, + [CLK_APBC_PWM4] = &pwm4_clk.common.hw, + [CLK_APBC_PWM5] = &pwm5_clk.common.hw, + [CLK_APBC_PWM6] = &pwm6_clk.common.hw, + [CLK_APBC_PWM7] = &pwm7_clk.common.hw, + [CLK_APBC_PWM8] = &pwm8_clk.common.hw, + [CLK_APBC_PWM9] = &pwm9_clk.common.hw, + [CLK_APBC_PWM10] = &pwm10_clk.common.hw, + [CLK_APBC_PWM11] = &pwm11_clk.common.hw, + [CLK_APBC_PWM12] = &pwm12_clk.common.hw, + [CLK_APBC_PWM13] = &pwm13_clk.common.hw, + [CLK_APBC_PWM14] = &pwm14_clk.common.hw, + [CLK_APBC_PWM15] = &pwm15_clk.common.hw, + [CLK_APBC_PWM16] = &pwm16_clk.common.hw, + [CLK_APBC_PWM17] = &pwm17_clk.common.hw, + [CLK_APBC_PWM18] = &pwm18_clk.common.hw, + [CLK_APBC_PWM19] = &pwm19_clk.common.hw, + [CLK_APBC_PWM0_BUS] = &pwm0_bus_clk.common.hw, + [CLK_APBC_PWM1_BUS] = &pwm1_bus_clk.common.hw, + [CLK_APBC_PWM2_BUS] = &pwm2_bus_clk.common.hw, + [CLK_APBC_PWM3_BUS] = &pwm3_bus_clk.common.hw, + [CLK_APBC_PWM4_BUS] = &pwm4_bus_clk.common.hw, + [CLK_APBC_PWM5_BUS] = &pwm5_bus_clk.common.hw, + [CLK_APBC_PWM6_BUS] = &pwm6_bus_clk.common.hw, + [CLK_APBC_PWM7_BUS] = &pwm7_bus_clk.common.hw, + [CLK_APBC_PWM8_BUS] = &pwm8_bus_clk.common.hw, + [CLK_APBC_PWM9_BUS] = &pwm9_bus_clk.common.hw, + [CLK_APBC_PWM10_BUS] = &pwm10_bus_clk.common.hw, + [CLK_APBC_PWM11_BUS] = &pwm11_bus_clk.common.hw, + [CLK_APBC_PWM12_BUS] = &pwm12_bus_clk.common.hw, + [CLK_APBC_PWM13_BUS] = &pwm13_bus_clk.common.hw, + [CLK_APBC_PWM14_BUS] = &pwm14_bus_clk.common.hw, + [CLK_APBC_PWM15_BUS] = &pwm15_bus_clk.common.hw, + [CLK_APBC_PWM16_BUS] = &pwm16_bus_clk.common.hw, + [CLK_APBC_PWM17_BUS] = &pwm17_bus_clk.common.hw, + [CLK_APBC_PWM18_BUS] = &pwm18_bus_clk.common.hw, + [CLK_APBC_PWM19_BUS] = &pwm19_bus_clk.common.hw, + [CLK_APBC_SPI0_I2S_BCLK] = &spi0_i2s_bclk.common.hw, + [CLK_APBC_SPI1_I2S_BCLK] = &spi1_i2s_bclk.common.hw, + [CLK_APBC_SPI3_I2S_BCLK] = &spi3_i2s_bclk.common.hw, + [CLK_APBC_SPI0] = &spi0_clk.common.hw, + [CLK_APBC_SPI1] = &spi1_clk.common.hw, + [CLK_APBC_SPI3] = &spi3_clk.common.hw, + [CLK_APBC_SPI0_BUS] = &spi0_bus_clk.common.hw, + [CLK_APBC_SPI1_BUS] = &spi1_bus_clk.common.hw, + [CLK_APBC_SPI3_BUS] = &spi3_bus_clk.common.hw, + [CLK_APBC_RTC] = &rtc_clk.common.hw, + [CLK_APBC_RTC_BUS] = &rtc_bus_clk.common.hw, + [CLK_APBC_TWSI0] = &twsi0_clk.common.hw, + [CLK_APBC_TWSI1] = &twsi1_clk.common.hw, + [CLK_APBC_TWSI2] = &twsi2_clk.common.hw, + [CLK_APBC_TWSI4] = &twsi4_clk.common.hw, + [CLK_APBC_TWSI5] = &twsi5_clk.common.hw, + [CLK_APBC_TWSI6] = &twsi6_clk.common.hw, + [CLK_APBC_TWSI8] = &twsi8_clk.common.hw, + [CLK_APBC_TWSI0_BUS] = &twsi0_bus_clk.common.hw, + [CLK_APBC_TWSI1_BUS] = &twsi1_bus_clk.common.hw, + [CLK_APBC_TWSI2_BUS] = &twsi2_bus_clk.common.hw, + [CLK_APBC_TWSI4_BUS] = &twsi4_bus_clk.common.hw, + [CLK_APBC_TWSI5_BUS] = &twsi5_bus_clk.common.hw, + [CLK_APBC_TWSI6_BUS] = &twsi6_bus_clk.common.hw, + [CLK_APBC_TWSI8_BUS] = &twsi8_bus_clk.common.hw, + [CLK_APBC_TIMERS0] = &timers0_clk.common.hw, + [CLK_APBC_TIMERS1] = &timers1_clk.common.hw, + [CLK_APBC_TIMERS2] = &timers2_clk.common.hw, + [CLK_APBC_TIMERS3] = &timers3_clk.common.hw, + [CLK_APBC_TIMERS4] = &timers4_clk.common.hw, + [CLK_APBC_TIMERS5] = &timers5_clk.common.hw, + [CLK_APBC_TIMERS6] = &timers6_clk.common.hw, + [CLK_APBC_TIMERS7] = &timers7_clk.common.hw, + [CLK_APBC_TIMERS0_BUS] = &timers0_bus_clk.common.hw, + [CLK_APBC_TIMERS1_BUS] = &timers1_bus_clk.common.hw, + [CLK_APBC_TIMERS2_BUS] = &timers2_bus_clk.common.hw, + [CLK_APBC_TIMERS3_BUS] = &timers3_bus_clk.common.hw, + [CLK_APBC_TIMERS4_BUS] = &timers4_bus_clk.common.hw, + [CLK_APBC_TIMERS5_BUS] = &timers5_bus_clk.common.hw, + [CLK_APBC_TIMERS6_BUS] = &timers6_bus_clk.common.hw, + [CLK_APBC_TIMERS7_BUS] = &timers7_bus_clk.common.hw, + [CLK_APBC_AIB] = &aib_clk.common.hw, + [CLK_APBC_AIB_BUS] = &aib_bus_clk.common.hw, + [CLK_APBC_ONEWIRE] = &onewire_clk.common.hw, + [CLK_APBC_ONEWIRE_BUS] = &onewire_bus_clk.common.hw, + [CLK_APBC_I2S0_BCLK] = &i2s0_i2s_bclk.common.hw, + [CLK_APBC_I2S1_BCLK] = &i2s1_i2s_bclk.common.hw, + [CLK_APBC_I2S2_BCLK] = &i2s2_i2s_bclk.common.hw, + [CLK_APBC_I2S3_BCLK] = &i2s3_i2s_bclk.common.hw, + [CLK_APBC_I2S4_BCLK] = &i2s4_i2s_bclk.common.hw, + [CLK_APBC_I2S5_BCLK] = &i2s5_i2s_bclk.common.hw, + [CLK_APBC_I2S0] = &i2s0_clk.common.hw, + [CLK_APBC_I2S1] = &i2s1_clk.common.hw, + [CLK_APBC_I2S2] = &i2s2_clk.common.hw, + [CLK_APBC_I2S3] = &i2s3_clk.common.hw, + [CLK_APBC_I2S4] = &i2s4_clk.common.hw, + [CLK_APBC_I2S5] = &i2s5_clk.common.hw, + [CLK_APBC_I2S0_BUS] = &i2s0_bus_clk.common.hw, + [CLK_APBC_I2S1_BUS] = &i2s1_bus_clk.common.hw, + [CLK_APBC_I2S2_BUS] = &i2s2_bus_clk.common.hw, + [CLK_APBC_I2S3_BUS] = &i2s3_bus_clk.common.hw, + [CLK_APBC_I2S4_BUS] = &i2s4_bus_clk.common.hw, + [CLK_APBC_I2S5_BUS] = &i2s5_bus_clk.common.hw, + [CLK_APBC_DRO] = &dro_clk.common.hw, + [CLK_APBC_IR0] = &ir0_clk.common.hw, + [CLK_APBC_IR1] = &ir1_clk.common.hw, + [CLK_APBC_TSEN] = &tsen_clk.common.hw, + [CLK_APBC_TSEN_BUS] = &tsen_bus_clk.common.hw, + [CLK_APBC_IPC_AP2RCPU] = &ipc_ap2rcpu_clk.common.hw, + [CLK_APBC_IPC_AP2RCPU_BUS] = &ipc_ap2rcpu_bus_clk.common.hw, + [CLK_APBC_CAN0] = &can0_clk.common.hw, + [CLK_APBC_CAN1] = &can1_clk.common.hw, + [CLK_APBC_CAN2] = &can2_clk.common.hw, + [CLK_APBC_CAN3] = &can3_clk.common.hw, + [CLK_APBC_CAN4] = &can4_clk.common.hw, + [CLK_APBC_CAN0_BUS] = &can0_bus_clk.common.hw, + [CLK_APBC_CAN1_BUS] = &can1_bus_clk.common.hw, + [CLK_APBC_CAN2_BUS] = &can2_bus_clk.common.hw, + [CLK_APBC_CAN3_BUS] = &can3_bus_clk.common.hw, + [CLK_APBC_CAN4_BUS] = &can4_bus_clk.common.hw, +}; + +static const struct spacemit_ccu_data k3_ccu_apbc_data = { + .reset_name = "k3-apbc-reset", + .hws = k3_ccu_apbc_hws, + .num = ARRAY_SIZE(k3_ccu_apbc_hws), +}; + +static struct clk_hw *k3_ccu_apmu_hws[] = { + [CLK_APMU_AXICLK] = &axi_clk.common.hw, + [CLK_APMU_CCI550] = &cci550_clk.common.hw, + [CLK_APMU_CPU_C0_CORE] = &cpu_c0_core_clk.common.hw, + [CLK_APMU_CPU_C1_CORE] = &cpu_c1_core_clk.common.hw, + [CLK_APMU_CPU_C2_CORE] = &cpu_c2_core_clk.common.hw, + [CLK_APMU_CPU_C3_CORE] = &cpu_c3_core_clk.common.hw, + [CLK_APMU_CCIC2PHY] = &ccic2phy_clk.common.hw, + [CLK_APMU_CCIC3PHY] = &ccic3phy_clk.common.hw, + [CLK_APMU_CSI] = &csi_clk.common.hw, + [CLK_APMU_ISP_BUS] = &isp_bus_clk.common.hw, + [CLK_APMU_D1P_1228P8] = &d1p_1228p8.common.hw, + [CLK_APMU_D1P_819P2] = &d1p_819p2.common.hw, + [CLK_APMU_D1P_614P4] = &d1p_614p4.common.hw, + [CLK_APMU_D1P_491P52] = &d1p_491p52.common.hw, + [CLK_APMU_D1P_409P6] = &d1p_409p6.common.hw, + [CLK_APMU_D1P_307P2] = &d1p_307p2.common.hw, + [CLK_APMU_D1P_245P76] = &d1p_245p76.common.hw, + [CLK_APMU_V2D] = &v2d_clk.common.hw, + [CLK_APMU_DSI_ESC] = &dsi_esc_clk.common.hw, + [CLK_APMU_LCD_HCLK] = &lcd_hclk.common.hw, + [CLK_APMU_LCD_DSC] = &lcd_dsc_clk.common.hw, + [CLK_APMU_LCD_PXCLK] = &lcd_pxclk.common.hw, + [CLK_APMU_LCD_MCLK] = &lcd_mclk.common.hw, + [CLK_APMU_CCIC_4X] = &ccic_4x_clk.common.hw, + [CLK_APMU_CCIC1PHY] = &ccic1phy_clk.common.hw, + [CLK_APMU_SC2_HCLK] = &sc2_hclk.common.hw, + [CLK_APMU_SDH_AXI] = &sdh_axi_aclk.common.hw, + [CLK_APMU_SDH0] = &sdh0_clk.common.hw, + [CLK_APMU_SDH1] = &sdh1_clk.common.hw, + [CLK_APMU_SDH2] = &sdh2_clk.common.hw, + [CLK_APMU_USB2_BUS] = &usb2_bus_clk.common.hw, + [CLK_APMU_USB3_PORTA_BUS] = &usb3_porta_bus_clk.common.hw, + [CLK_APMU_USB3_PORTB_BUS] = &usb3_portb_bus_clk.common.hw, + [CLK_APMU_USB3_PORTC_BUS] = &usb3_portc_bus_clk.common.hw, + [CLK_APMU_USB3_PORTD_BUS] = &usb3_portd_bus_clk.common.hw, + [CLK_APMU_QSPI] = &qspi_clk.common.hw, + [CLK_APMU_QSPI_BUS] = &qspi_bus_clk.common.hw, + [CLK_APMU_DMA] = &dma_clk.common.hw, + [CLK_APMU_AES_WTM] = &aes_wtm_clk.common.hw, + [CLK_APMU_VPU] = &vpu_clk.common.hw, + [CLK_APMU_DTC] = &dtc_clk.common.hw, + [CLK_APMU_GPU] = &gpu_clk.common.hw, + [CLK_APMU_MC_AHB] = &mc_ahb_clk.common.hw, + [CLK_APMU_TOP_DCLK] = &top_dclk.common.hw, + [CLK_APMU_UCIE] = &ucie_clk.common.hw, + [CLK_APMU_UCIE_SBCLK] = &ucie_sbclk.common.hw, + [CLK_APMU_RCPU] = &rcpu_clk.common.hw, + [CLK_APMU_DSI4LN2_DSI_ESC] = &dsi4ln2_dsi_esc_clk.common.hw, + [CLK_APMU_DSI4LN2_LCD_DSC] = &dsi4ln2_lcd_dsc_clk.common.hw, + [CLK_APMU_DSI4LN2_LCD_PXCLK] = &dsi4ln2_lcd_pxclk.common.hw, + [CLK_APMU_DSI4LN2_LCD_MCLK] = &dsi4ln2_lcd_mclk.common.hw, + [CLK_APMU_DSI4LN2_DPU_ACLK] = &dsi4ln2_dpu_aclk.common.hw, + [CLK_APMU_DPU_ACLK] = &dpu_aclk.common.hw, + [CLK_APMU_UFS_ACLK] = &ufs_aclk.common.hw, + [CLK_APMU_EDP0_PXCLK] = &edp0_pxclk.common.hw, + [CLK_APMU_EDP1_PXCLK] = &edp1_pxclk.common.hw, + [CLK_APMU_PCIE_PORTA_MSTE] = &pciea_mstr_clk.common.hw, + [CLK_APMU_PCIE_PORTA_SLV] = &pciea_slv_clk.common.hw, + [CLK_APMU_PCIE_PORTB_MSTE] = &pcieb_mstr_clk.common.hw, + [CLK_APMU_PCIE_PORTB_SLV] = &pcieb_slv_clk.common.hw, + [CLK_APMU_PCIE_PORTC_MSTE] = &pciec_mstr_clk.common.hw, + [CLK_APMU_PCIE_PORTC_SLV] = &pciec_slv_clk.common.hw, + [CLK_APMU_PCIE_PORTD_MSTE] = &pcied_mstr_clk.common.hw, + [CLK_APMU_PCIE_PORTD_SLV] = &pcied_slv_clk.common.hw, + [CLK_APMU_PCIE_PORTE_MSTE] = &pciee_mstr_clk.common.hw, + [CLK_APMU_PCIE_PORTE_SLV] = &pciee_slv_clk.common.hw, + [CLK_APMU_EMAC0_BUS] = &emac0_bus_clk.common.hw, + [CLK_APMU_EMAC0_REF] = &emac0_ref_clk.common.hw, + [CLK_APMU_EMAC0_1588] = &emac0_1588_clk.common.hw, + [CLK_APMU_EMAC0_RGMII_TX] = &emac0_rgmii_tx_clk.common.hw, + [CLK_APMU_EMAC1_BUS] = &emac1_bus_clk.common.hw, + [CLK_APMU_EMAC1_REF] = &emac1_ref_clk.common.hw, + [CLK_APMU_EMAC1_1588] = &emac1_1588_clk.common.hw, + [CLK_APMU_EMAC1_RGMII_TX] = &emac1_rgmii_tx_clk.common.hw, + [CLK_APMU_EMAC2_BUS] = &emac2_bus_clk.common.hw, + [CLK_APMU_EMAC2_REF] = &emac2_ref_clk.common.hw, + [CLK_APMU_EMAC2_1588] = &emac2_1588_clk.common.hw, + [CLK_APMU_EMAC2_RGMII_TX] = &emac2_rgmii_tx_clk.common.hw, + [CLK_APMU_ESPI_SCLK_SRC] = &espi_sclk_src.common.hw, + [CLK_APMU_ESPI_SCLK] = &espi_sclk.common.hw, + [CLK_APMU_ESPI_MCLK] = &espi_mclk.common.hw, + [CLK_APMU_CAM_SRC1] = &cam_src1_clk.common.hw, + [CLK_APMU_CAM_SRC2] = &cam_src2_clk.common.hw, + [CLK_APMU_CAM_SRC3] = &cam_src3_clk.common.hw, + [CLK_APMU_CAM_SRC4] = &cam_src4_clk.common.hw, + [CLK_APMU_ISIM_VCLK0] = &isim_vclk_out0.common.hw, + [CLK_APMU_ISIM_VCLK1] = &isim_vclk_out1.common.hw, + [CLK_APMU_ISIM_VCLK2] = &isim_vclk_out2.common.hw, + [CLK_APMU_ISIM_VCLK3] = &isim_vclk_out3.common.hw, +}; + +static const struct spacemit_ccu_data k3_ccu_apmu_data = { + .reset_name = "k3-apmu-reset", + .hws = k3_ccu_apmu_hws, + .num = ARRAY_SIZE(k3_ccu_apmu_hws), +}; + +static struct clk_hw *k3_ccu_dciu_hws[] = { + [CLK_DCIU_HDMA] = &hdma_clk.common.hw, + [CLK_DCIU_DMA350] = &dma350_clk.common.hw, + [CLK_DCIU_C2_TCM_PIPE] = &c2_tcm_pipe_clk.common.hw, + [CLK_DCIU_C3_TCM_PIPE] = &c3_tcm_pipe_clk.common.hw, +}; + +static const struct spacemit_ccu_data k3_ccu_dciu_data = { + .reset_name = "k3-dciu-reset", + .hws = k3_ccu_dciu_hws, + .num = ARRAY_SIZE(k3_ccu_dciu_hws), +}; + +static const struct of_device_id of_k3_ccu_match[] = { + { + .compatible = "spacemit,k3-pll", + .data = &k3_ccu_pll_data, + }, + { + .compatible = "spacemit,k3-syscon-mpmu", + .data = &k3_ccu_mpmu_data, + }, + { + .compatible = "spacemit,k3-syscon-apbc", + .data = &k3_ccu_apbc_data, + }, + { + .compatible = "spacemit,k3-syscon-apmu", + .data = &k3_ccu_apmu_data, + }, + { + .compatible = "spacemit,k3-syscon-dciu", + .data = &k3_ccu_dciu_data, + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_k3_ccu_match); + +static int k3_ccu_probe(struct platform_device *pdev) +{ + return spacemit_ccu_probe(pdev, "spacemit,k3-pll"); +} + +static struct platform_driver k3_ccu_driver = { + .driver = { + .name = "spacemit,k3-ccu", + .of_match_table = of_k3_ccu_match, + }, + .probe = k3_ccu_probe, +}; +module_platform_driver(k3_ccu_driver); + +MODULE_IMPORT_NS("CLK_SPACEMIT"); +MODULE_DESCRIPTION("SpacemiT K3 CCU driver"); +MODULE_LICENSE("GPL"); From 3132ec8c8c2c28787d0ad80e53db296713155f12 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Thu, 27 Nov 2025 16:56:54 +0200 Subject: [PATCH 081/165] clk: renesas: cpg-mssr: Handle RZ/T2H register layout in PM callbacks The register layout for RZ/T2H is not handled inside cpg_mssr_suspend_noirq() and cpg_mssr_resume_noirq(), causing a memory abort because the wrong code path is taken, as shown below. Explicitly handle the RZ/T2H register layout in cpg_mssr_suspend_noirq() and cpg_mssr_resume_noirq(), similar to how it is done inside cpg_mstp_clock_is_enabled() and cpg_mstp_clock_endisable(). [ 90.052296] Mem abort info: [ 90.055420] ESR = 0x0000000096000007 [ 90.059553] EC = 0x25: DABT (current EL), IL = 32 bits [ 90.065697] SET = 0, FnV = 0 [ 90.069211] EA = 0, S1PTW = 0 [ 90.072834] FSC = 0x07: level 3 translation fault [ 90.078109] Data abort info: [ 90.081405] ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000 [ 90.087427] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 90.093169] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 90.099008] swapper pgtable: 4k pages, 48-bit VAs, pgdp=00000000c60b4000 [ 90.106756] [ffff800082816318] pgd=0000000000000000, p4d=10000000c69ef003, pud=10000000c69f0003, pmd=100000024002b403, pte=0000000000000000 [ 90.120727] Internal error: Oops: 0000000096000007 [#1] SMP [ 90.127058] Modules linked in: sha256 cfg80211 spi_nor at24 renesas_usbhs bluetooth ecdh_generic ecc rfkill rzt2h_adc spi_rzv2h_rspi industrialio_adc gpio_keys fuse drm backlight ipv6 [ 90.145201] CPU: 0 UID: 0 PID: 307 Comm: sh Not tainted 6.18.0-rc1-next-20251016+ #47 PREEMPT [ 90.155006] Hardware name: Renesas RZ/T2H EVK Board based on r9a09g077m44 (DT) [ 90.163041] pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 90.170777] pc : cpg_mssr_suspend_noirq+0x4c/0xc0 [ 90.175983] lr : device_suspend_noirq+0x6c/0x22c [ 90.181309] sp : ffff8000838d3af0 [ 90.185026] x29: ffff8000838d3af0 x28: ffff8000825c016f x27: ffff8000825c01a0 [ 90.192973] x26: ffff8000809feeec x25: ffff8000827bebb8 x24: 0000000000000002 [ 90.200815] x23: ffff8000825c0190 x22: 0000000000000002 x21: 0000000000000000 [ 90.209058] x20: ffff8000827bebb8 x19: ffff000180128010 x18: ffff00033ef92a80 [ 90.217100] x17: ffff000180051700 x16: 0000000000000001 x15: ffff000187afc310 [ 90.224847] x14: 0000000000000254 x13: 0000000000000001 x12: 0000000000000001 [ 90.232793] x11: 00000000000000c0 x10: 0000000000000ab0 x9 : ffff8000838d38b0 [ 90.240540] x8 : ffff000186387410 x7 : 0000000000000001 x6 : 0000000000000000 [ 90.248600] x5 : ffff0001803240d4 x4 : 0000000000000003 x3 : ffff0001803240d0 [ 90.256460] x2 : ffff800082816318 x1 : 000000000000000c x0 : ffff000180324000 [ 90.264208] Call trace: [ 90.267019] cpg_mssr_suspend_noirq+0x4c/0xc0 (P) [ 90.272450] device_suspend_noirq+0x6c/0x22c [ 90.277375] dpm_noirq_suspend_devices+0x1a8/0x2a0 [ 90.282902] dpm_suspend_noirq+0x24/0xa0 [ 90.287428] suspend_devices_and_enter+0x310/0x590 [ 90.292790] pm_suspend+0x1b4/0x200 [ 90.296811] state_store+0x80/0xf4 [ 90.300676] kobj_attr_store+0x18/0x34 [ 90.305002] sysfs_kf_write+0x7c/0x94 [ 90.309232] kernfs_fop_write_iter+0x12c/0x200 [ 90.314115] vfs_write+0x240/0x380 [ 90.318041] ksys_write+0x64/0x100 [ 90.321862] __arm64_sys_write+0x18/0x24 [ 90.326013] invoke_syscall.constprop.0+0x40/0xf0 [ 90.331445] el0_svc_common.constprop.0+0xb8/0xd8 [ 90.336554] do_el0_svc+0x1c/0x28 [ 90.340375] el0_svc+0x34/0xe8 [ 90.343900] el0t_64_sync_handler+0xa0/0xe4 [ 90.348426] el0t_64_sync+0x198/0x19c [ 90.352609] Code: 8b040042 b9409004 7100049f 54000240 (b9400042) [ 90.359639] ---[ end trace 0000000000000000 ]--- Fixes: 065fe720eec6 ("clk: renesas: Add support for R9A09G077 SoC") Signed-off-by: Cosmin Tanislav Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251127145654.3253992-3-cosmin-gabriel.tanislav.xa@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-cpg-mssr.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 031e4b125f2d..976c157829f1 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -1077,11 +1077,19 @@ static int cpg_mssr_suspend_noirq(struct device *dev) /* Save module registers with bits under our control */ for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) { - if (priv->smstpcr_saved[reg].mask) - priv->smstpcr_saved[reg].val = - priv->reg_layout == CLK_REG_LAYOUT_RZ_A ? - readb(priv->pub.base0 + priv->control_regs[reg]) : - readl(priv->pub.base0 + priv->control_regs[reg]); + u32 val; + + if (!priv->smstpcr_saved[reg].mask) + continue; + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) + val = readb(priv->pub.base0 + priv->control_regs[reg]); + else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) + val = cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); + else + val = readl(priv->pub.base0 + priv->control_regs[reg]); + + priv->smstpcr_saved[reg].val = val; } /* Save core clocks */ @@ -1112,6 +1120,8 @@ static int cpg_mssr_resume_noirq(struct device *dev) if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) oldval = readb(priv->pub.base0 + priv->control_regs[reg]); + else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) + oldval = cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); else oldval = readl(priv->pub.base0 + priv->control_regs[reg]); newval = oldval & ~mask; @@ -1125,6 +1135,12 @@ static int cpg_mssr_resume_noirq(struct device *dev) readb(priv->pub.base0 + priv->control_regs[reg]); barrier_data(priv->pub.base0 + priv->control_regs[reg]); continue; + } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { + cpg_rzt2h_mstp_write(priv, priv->control_regs[reg], newval); + /* See cpg_mstp_clock_endisable() on why this is necessary. */ + cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); + udelay(10); + continue; } else writel(newval, priv->pub.base0 + priv->control_regs[reg]); From 535677e920f09c6e478e671e4527ff9af6ffc6c7 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 24 Dec 2025 16:50:47 +0000 Subject: [PATCH 082/165] clk: renesas: r9a09g077: Add CANFD clocks The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have a CANFD peripheral which has three input clocks PCLKM (peripheral clock), PCLKH (RAM clock) and PCLKCAN (CANFD clock). Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251224165049.3384870-3-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g077-cpg.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index dee25cdadf1d..93b15e06a19b 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -47,6 +47,7 @@ #define FSELXSPI1 CONF_PACK(SCKCR, 8, 3) #define DIVSEL_XSPI0 CONF_PACK(SCKCR, 6, 1) #define DIVSEL_XSPI1 CONF_PACK(SCKCR, 14, 1) +#define FSELCANFD CONF_PACK(SCKCR, 20, 1) #define SEL_PLL CONF_PACK(SCKCR, 22, 1) #define DIVCA55C0 CONF_PACK(SCKCR2, 8, 1) @@ -85,7 +86,7 @@ enum rzt2h_clk_types { enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G077_XSPI_CLK1, + LAST_DT_CORE_CLK = R9A09G077_PCLKCAN, /* External Input Clocks */ CLK_EXTAL, @@ -103,6 +104,9 @@ enum clk_ids { CLK_PLL4D1, CLK_PLL4D1_DIV3, CLK_PLL4D1_DIV4, + CLK_PLL4D3, + CLK_PLL4D3_DIV10, + CLK_PLL4D3_DIV20, CLK_SCI0ASYNC, CLK_SCI1ASYNC, CLK_SCI2ASYNC, @@ -150,6 +154,7 @@ static const char * const sel_clk_pll1[] = { ".loco", ".pll1" }; static const char * const sel_clk_pll2[] = { ".loco", ".pll2" }; static const char * const sel_clk_pll4[] = { ".loco", ".pll4" }; static const char * const sel_clk_pll4d1_div3_div4[] = { ".pll4d1_div3", ".pll4d1_div4" }; +static const char * const sel_clk_pll4d3_div10_div20[] = { ".pll4d3_div10", ".pll4d3_div20" }; static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { /* External Clock Inputs */ @@ -174,6 +179,9 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { DEF_FIXED(".pll4d1", CLK_PLL4D1, CLK_SEL_CLK_PLL4, 1, 1), DEF_FIXED(".pll4d1_div3", CLK_PLL4D1_DIV3, CLK_PLL4D1, 3, 1), DEF_FIXED(".pll4d1_div4", CLK_PLL4D1_DIV4, CLK_PLL4D1, 4, 1), + DEF_FIXED(".pll4d3", CLK_PLL4D3, CLK_SEL_CLK_PLL4, 3, 1), + DEF_FIXED(".pll4d3_div10", CLK_PLL4D3_DIV10, CLK_PLL4D3, 10, 1), + DEF_FIXED(".pll4d3_div20", CLK_PLL4D3_DIV20, CLK_PLL4D3, 20, 1), DEF_DIV(".sci0async", CLK_SCI0ASYNC, CLK_PLL4D1, DIVSCI0ASYNC, dtable_24_25_30_32), @@ -232,6 +240,8 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { FSELXSPI0, dtable_6_8_16_32_64), DEF_DIV_FSELXSPI("XSPI_CLK1", R9A09G077_XSPI_CLK1, CLK_DIVSELXSPI1_SCKCR, FSELXSPI1, dtable_6_8_16_32_64), + DEF_MUX("PCLKCAN", R9A09G077_PCLKCAN, FSELCANFD, + sel_clk_pll4d3_div10_div20, ARRAY_SIZE(sel_clk_pll4d3_div10_div20), 0), }; static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { @@ -251,6 +261,7 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { DEF_MOD("adc1", 207, R9A09G077_CLK_PCLKH), DEF_MOD("adc2", 225, R9A09G077_CLK_PCLKM), DEF_MOD("tsu", 307, R9A09G077_CLK_PCLKL), + DEF_MOD("canfd", 310, R9A09G077_CLK_PCLKM), DEF_MOD("gmac0", 400, R9A09G077_CLK_PCLKM), DEF_MOD("ethsw", 401, R9A09G077_CLK_PCLKM), DEF_MOD("ethss", 403, R9A09G077_CLK_PCLKM), From 26cc40e82230a776ead2ef6a6ed83bf80f94bb01 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 24 Dec 2025 16:50:48 +0000 Subject: [PATCH 083/165] clk: renesas: r9a09g057: Add entries for CANFD Add clock and reset entries for the CANFD IP. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251224165049.3384870-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g057-cpg.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c index 991f9a2ec12e..6943cad318b5 100644 --- a/drivers/clk/renesas/r9a09g057-cpg.c +++ b/drivers/clk/renesas/r9a09g057-cpg.c @@ -46,6 +46,7 @@ enum clk_ids { CLK_PLLCLN_DIV2, CLK_PLLCLN_DIV8, CLK_PLLCLN_DIV16, + CLK_PLLCLN_DIV20, CLK_PLLCLN_DIV64, CLK_PLLCLN_DIV256, CLK_PLLCLN_DIV1024, @@ -185,6 +186,7 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { DEF_FIXED(".pllcln_div2", CLK_PLLCLN_DIV2, CLK_PLLCLN, 1, 2), DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8), DEF_FIXED(".pllcln_div16", CLK_PLLCLN_DIV16, CLK_PLLCLN, 1, 16), + DEF_FIXED(".pllcln_div20", CLK_PLLCLN_DIV20, CLK_PLLCLN, 1, 20), DEF_FIXED(".pllcln_div64", CLK_PLLCLN_DIV64, CLK_PLLCLN, 1, 64), DEF_FIXED(".pllcln_div256", CLK_PLLCLN_DIV256, CLK_PLLCLN, 1, 256), DEF_FIXED(".pllcln_div1024", CLK_PLLCLN_DIV1024, CLK_PLLCLN, 1, 1024), @@ -440,6 +442,12 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(1, BIT(7))), DEF_MOD("riic_7_ckm", CLK_PLLCLN_DIV16, 9, 11, 4, 27, BUS_MSTOP(1, BIT(8))), + DEF_MOD("canfd_0_pclk", CLK_PLLCLN_DIV16, 9, 12, 4, 28, + BUS_MSTOP(10, BIT(14))), + DEF_MOD("canfd_0_clk_ram", CLK_PLLCLN_DIV8, 9, 13, 4, 29, + BUS_MSTOP(10, BIT(14))), + DEF_MOD("canfd_0_clkc", CLK_PLLCLN_DIV20, 9, 14, 4, 30, + BUS_MSTOP(10, BIT(14))), DEF_MOD("spi_hclk", CLK_PLLCM33_GEAR, 9, 15, 4, 31, BUS_MSTOP(4, BIT(5))), DEF_MOD("spi_aclk", CLK_PLLCM33_GEAR, 10, 0, 5, 0, @@ -634,6 +642,8 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(9, 14, 4, 15), /* RIIC_6_MRST */ DEF_RST(9, 15, 4, 16), /* RIIC_7_MRST */ DEF_RST(10, 0, 4, 17), /* RIIC_8_MRST */ + DEF_RST(10, 1, 4, 18), /* CANFD_0_RSTP_N */ + DEF_RST(10, 2, 4, 19), /* CANFD_0_RSTC_N */ DEF_RST(10, 3, 4, 20), /* SPI_HRESETN */ DEF_RST(10, 4, 4, 21), /* SPI_ARESETN */ DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */ From c2922664613277c61922bbe577f25092a85fb27e Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 24 Dec 2025 16:50:49 +0000 Subject: [PATCH 084/165] clk: renesas: r9a09g056: Add entries for CANFD Add clock and reset entries for the CANFD IP. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251224165049.3384870-5-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a09g056-cpg.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index d831246ff55d..fead173cae8b 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -46,6 +46,7 @@ enum clk_ids { CLK_PLLCLN_DIV2, CLK_PLLCLN_DIV8, CLK_PLLCLN_DIV16, + CLK_PLLCLN_DIV20, CLK_PLLCLN_DIV64, CLK_PLLCLN_DIV256, CLK_PLLCLN_DIV1024, @@ -183,6 +184,7 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_FIXED(".pllcln_div2", CLK_PLLCLN_DIV2, CLK_PLLCLN, 1, 2), DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8), DEF_FIXED(".pllcln_div16", CLK_PLLCLN_DIV16, CLK_PLLCLN, 1, 16), + DEF_FIXED(".pllcln_div20", CLK_PLLCLN_DIV20, CLK_PLLCLN, 1, 20), DEF_FIXED(".pllcln_div64", CLK_PLLCLN_DIV64, CLK_PLLCLN, 1, 64), DEF_FIXED(".pllcln_div256", CLK_PLLCLN_DIV256, CLK_PLLCLN, 1, 256), DEF_FIXED(".pllcln_div1024", CLK_PLLCLN_DIV1024, CLK_PLLCLN, 1, 1024), @@ -431,6 +433,12 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(1, BIT(7))), DEF_MOD("riic_7_ckm", CLK_PLLCLN_DIV16, 9, 11, 4, 27, BUS_MSTOP(1, BIT(8))), + DEF_MOD("canfd_0_pclk", CLK_PLLCLN_DIV16, 9, 12, 4, 28, + BUS_MSTOP(10, BIT(14))), + DEF_MOD("canfd_0_clk_ram", CLK_PLLCLN_DIV8, 9, 13, 4, 29, + BUS_MSTOP(10, BIT(14))), + DEF_MOD("canfd_0_clkc", CLK_PLLCLN_DIV20, 9, 14, 4, 30, + BUS_MSTOP(10, BIT(14))), DEF_MOD("spi_hclk", CLK_PLLCM33_GEAR, 9, 15, 4, 31, BUS_MSTOP(4, BIT(5))), DEF_MOD("spi_aclk", CLK_PLLCM33_GEAR, 10, 0, 5, 0, @@ -603,6 +611,8 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(9, 14, 4, 15), /* RIIC_6_MRST */ DEF_RST(9, 15, 4, 16), /* RIIC_7_MRST */ DEF_RST(10, 0, 4, 17), /* RIIC_8_MRST */ + DEF_RST(10, 1, 4, 18), /* CANFD_0_RSTP_N */ + DEF_RST(10, 2, 4, 19), /* CANFD_0_RSTC_N */ DEF_RST(10, 3, 4, 20), /* SPI_HRESETN */ DEF_RST(10, 4, 4, 21), /* SPI_ARESETN */ DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */ From cda6a5def5917c6c23af1003d323ecdc5f2960a9 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 5 Jan 2026 14:06:25 +0000 Subject: [PATCH 085/165] clk: renesas: cpg-mssr: Unlock before reset verification Move spin_unlock_irqrestore() before verifying the reset result and printing errors. The verification condition only uses local variables and does not require locking. Reported-by: Pavel Machek Closes: https://lore.kernel.org/all/aVujAQJSDn6WyORK@duo.ucw.cz/ Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20260105140625.2590685-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-cpg-mssr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 976c157829f1..fad3d0cf84e4 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -794,14 +794,14 @@ static int cpg_mrcr_set_reset_state(struct reset_controller_dev *rcdev, /* Verify the operation */ val = readl(reg_addr); - if (set == !(bitmask & val)) { - dev_err(priv->dev, "Reset register %u%02u operation failed\n", reg, bit); - spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); - return -EIO; - } spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); + if (set == !(bitmask & val)) { + dev_err(priv->dev, "Reset register %u%02u operation failed\n", reg, bit); + return -EIO; + } + return 0; } From 0b0201f259e1158a875c5fd01adf318ae5d32352 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 8 Jan 2026 12:34:27 +0000 Subject: [PATCH 086/165] clk: renesas: rzg2l: Deassert reset on assert timeout If the assert() fails due to timeout error, set the reset register bit back to deasserted state. This change is needed especially for handling assert error in suspend() callback that expect the device to be in operational state in case of failure. Signed-off-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20260108123433.104464-2-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rzg2l-cpg.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 0bcf64b152e0..f670c6408ea1 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -1647,6 +1647,7 @@ static int __rzg2l_cpg_assert(struct reset_controller_dev *rcdev, u32 mask = BIT(info->resets[id].bit); s8 monbit = info->resets[id].monbit; u32 value = mask << 16; + u32 mon; int ret; dev_dbg(rcdev->dev, "%s id:%ld offset:0x%x\n", @@ -1667,10 +1668,10 @@ static int __rzg2l_cpg_assert(struct reset_controller_dev *rcdev, return 0; } - ret = readl_poll_timeout_atomic(priv->base + reg, value, - assert == !!(value & mask), 10, 200); - if (ret && !assert) { - value = mask << 16; + ret = readl_poll_timeout_atomic(priv->base + reg, mon, + assert == !!(mon & mask), 10, 200); + if (ret) { + value ^= mask; writel(value, priv->base + CLK_RST_R(info->resets[id].off)); } From 879e9fc8f689cbd890f2f79b9da098697746316d Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 8 Jan 2026 12:34:28 +0000 Subject: [PATCH 087/165] clk: renesas: rzv2h: Deassert reset on assert timeout If the assert() fails due to timeout error, set the reset register bit back to deasserted state. This change is needed especially for handling assert error in suspend() callback that expect the device to be in operational state in case of failure. Signed-off-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20260108123433.104464-3-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rzv2h-cpg.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index 3f6299b9fec0..1db92284025e 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -1352,6 +1352,7 @@ static int __rzv2h_cpg_assert(struct reset_controller_dev *rcdev, u32 mask = BIT(priv->resets[id].reset_bit); u8 monbit = priv->resets[id].mon_bit; u32 value = mask << 16; + u32 mon; int ret; dev_dbg(rcdev->dev, "%s id:%ld offset:0x%x\n", @@ -1364,10 +1365,10 @@ static int __rzv2h_cpg_assert(struct reset_controller_dev *rcdev, reg = GET_RST_MON_OFFSET(priv->resets[id].mon_index); mask = BIT(monbit); - ret = readl_poll_timeout_atomic(priv->base + reg, value, - assert == !!(value & mask), 10, 200); - if (ret && !assert) { - value = mask << 16; + ret = readl_poll_timeout_atomic(priv->base + reg, mon, + assert == !!(mon & mask), 10, 200); + if (ret) { + value ^= mask; writel(value, priv->base + GET_RST_OFFSET(priv->resets[id].reset_index)); } From e1f08613e113f02a3ec18c9a7964de97f940acbf Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:32 -0500 Subject: [PATCH 088/165] clk: qcom: alpha-pll: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: 0e56e3369b60 ("clk: qcom: alpha-pll: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney Reviewed-by: Abel Vesa Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260108-clk-divider-round-rate-v1-14-535a3ed73bf3@redhat.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-alpha-pll.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 3fbdee6e67f9..f8313f9d0e30 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -1270,11 +1270,8 @@ static int clk_alpha_pll_postdiv_determine_rate(struct clk_hw *hw, else table = clk_alpha_div_table; - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - table, pll->width, - CLK_DIVIDER_POWER_OF_TWO); - - return 0; + return divider_determine_rate(hw, req, table, pll->width, + CLK_DIVIDER_POWER_OF_TWO); } static int clk_alpha_pll_postdiv_ro_determine_rate(struct clk_hw *hw, @@ -1630,11 +1627,8 @@ static int clk_trion_pll_postdiv_determine_rate(struct clk_hw *hw, { struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - pll->post_div_table, - pll->width, CLK_DIVIDER_ROUND_CLOSEST); - - return 0; + return divider_determine_rate(hw, req, pll->post_div_table, pll->width, + CLK_DIVIDER_ROUND_CLOSEST); }; static int @@ -1670,11 +1664,8 @@ static int clk_alpha_pll_postdiv_fabia_determine_rate(struct clk_hw *hw, { struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - pll->post_div_table, - pll->width, CLK_DIVIDER_ROUND_CLOSEST); - - return 0; + return divider_determine_rate(hw, req, pll->post_div_table, pll->width, + CLK_DIVIDER_ROUND_CLOSEST); } static int clk_alpha_pll_postdiv_fabia_set_rate(struct clk_hw *hw, From a8d722f03923b1c6166d39482c6df8f017e185d9 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Tue, 5 Aug 2025 07:03:58 +0400 Subject: [PATCH 089/165] clk: rockchip: Fix error pointer check after rockchip_clk_register_gate_link() Replace NULL check with IS_ERR_OR_NULL() check after calling rockchip_clk_register_gate_link() since this function returns error pointers (ERR_PTR). Fixes: c62fa612cfa6 ("clk: rockchip: implement linked gate clock support") Signed-off-by: Miaoqian Lin Link: https://patch.msgid.link/20250805030358.3665878-1-linmq006@gmail.com Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 2601df3b1066..9ac9d13e87de 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -693,7 +693,7 @@ void rockchip_clk_register_late_branches(struct device *dev, break; } - if (!pdev) + if (IS_ERR_OR_NULL(pdev)) dev_err(dev, "failed to register device for clock %s\n", list->name); } } From d93faac66dc04650d924f8f9584216d14f48fb14 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Fri, 5 Dec 2025 14:46:27 -0500 Subject: [PATCH 090/165] clk: microchip: core: remove duplicate determine_rate on pic32_sclk_ops pic32_sclk_ops previously had a sclk_round_rate() member, and this was recently converted over to sclk_determine_rate() with the help of a Coccinelle semantic patch. pic32_sclk_ops now has two conflicting determine_rate ops members. Prior to the conversion, pic32_sclk_ops already had a determine_rate member that points to __clk_mux_determine_rate(). When both the round_rate() and determine_rate() ops are defined, the clk core only uses the determine_rate() op. Let's go ahead and drop the recently converted sclk_determine_rate() to match the previous functionality prior to the conversion. Fixes: e9f039c08cdc ("clk: microchip: core: convert from round_rate() to determine_rate()") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202511222115.uvHrP95A-lkp@intel.com/ Signed-off-by: Brian Masney Reviewed-by: Claudiu Beznea Link: https://lore.kernel.org/r/20251205-clk-microchip-fixes-v3-1-a02190705e47@redhat.com Signed-off-by: Claudiu Beznea --- drivers/clk/microchip/clk-core.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/clk/microchip/clk-core.c b/drivers/clk/microchip/clk-core.c index b34348d491f3..a0163441dfe5 100644 --- a/drivers/clk/microchip/clk-core.c +++ b/drivers/clk/microchip/clk-core.c @@ -780,15 +780,6 @@ static unsigned long sclk_get_rate(struct clk_hw *hw, unsigned long parent_rate) return parent_rate / div; } -static int sclk_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - req->rate = calc_best_divided_rate(req->rate, req->best_parent_rate, - SLEW_SYSDIV, 1); - - return 0; -} - static int sclk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -912,7 +903,6 @@ static int sclk_init(struct clk_hw *hw) const struct clk_ops pic32_sclk_ops = { .get_parent = sclk_get_parent, .set_parent = sclk_set_parent, - .determine_rate = sclk_determine_rate, .set_rate = sclk_set_rate, .recalc_rate = sclk_get_rate, .init = sclk_init, From 5df96d141cccb37f0c3112a22fc1112ea48e9246 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Fri, 5 Dec 2025 14:46:28 -0500 Subject: [PATCH 091/165] clk: microchip: core: correct return value on *_get_parent() roclk_get_parent() and sclk_get_parent() has the possibility of returning -EINVAL, however the framework expects this call to always succeed since the return value is unsigned. If there is no parent map defined, then the current value programmed in the hardware is used. Let's use that same value in the case where -EINVAL is currently returned. This index is only used by clk_core_get_parent_by_index(), and it validates that it doesn't overflow the number of available parents. Reported-by: kernel test robot Reported-by: Dan Carpenter Closes: https://lore.kernel.org/r/202512050233.R9hAWsJN-lkp@intel.com/ Signed-off-by: Brian Masney Reviewed-by: Claudiu Beznea Link: https://lore.kernel.org/r/20251205-clk-microchip-fixes-v3-2-a02190705e47@redhat.com Signed-off-by: Claudiu Beznea --- drivers/clk/microchip/clk-core.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/clk/microchip/clk-core.c b/drivers/clk/microchip/clk-core.c index a0163441dfe5..82f62731fc0e 100644 --- a/drivers/clk/microchip/clk-core.c +++ b/drivers/clk/microchip/clk-core.c @@ -283,14 +283,13 @@ static u8 roclk_get_parent(struct clk_hw *hw) v = (readl(refo->ctrl_reg) >> REFO_SEL_SHIFT) & REFO_SEL_MASK; - if (!refo->parent_map) - return v; + if (refo->parent_map) { + for (i = 0; i < clk_hw_get_num_parents(hw); i++) + if (refo->parent_map[i] == v) + return i; + } - for (i = 0; i < clk_hw_get_num_parents(hw); i++) - if (refo->parent_map[i] == v) - return i; - - return -EINVAL; + return v; } static unsigned long roclk_calc_rate(unsigned long parent_rate, @@ -817,13 +816,13 @@ static u8 sclk_get_parent(struct clk_hw *hw) v = (readl(sclk->mux_reg) >> OSC_CUR_SHIFT) & OSC_CUR_MASK; - if (!sclk->parent_map) - return v; + if (sclk->parent_map) { + for (i = 0; i < clk_hw_get_num_parents(hw); i++) + if (sclk->parent_map[i] == v) + return i; + } - for (i = 0; i < clk_hw_get_num_parents(hw); i++) - if (sclk->parent_map[i] == v) - return i; - return -EINVAL; + return v; } static int sclk_set_parent(struct clk_hw *hw, u8 index) From 69ccb0f338ea00732d51c164ccfcfdb703bf3839 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Fri, 5 Dec 2025 14:46:29 -0500 Subject: [PATCH 092/165] clk: microchip: core: remove unused include asm/traps.h The asm/traps.h include file is not actually used, so let's go ahead and remove it. Signed-off-by: Brian Masney Link: https://lore.kernel.org/r/20251205-clk-microchip-fixes-v3-3-a02190705e47@redhat.com Signed-off-by: Claudiu Beznea --- drivers/clk/microchip/clk-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/microchip/clk-core.c b/drivers/clk/microchip/clk-core.c index 82f62731fc0e..f467d7bc28c8 100644 --- a/drivers/clk/microchip/clk-core.c +++ b/drivers/clk/microchip/clk-core.c @@ -10,7 +10,6 @@ #include #include #include -#include #include "clk-core.h" From baf4fc7c03bd0f68c768cfe27829674bd060c6b4 Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Thu, 20 Nov 2025 13:14:15 +0000 Subject: [PATCH 093/165] clk: thead: th1520-ap: Support CPU frequency scaling On TH1520 SoC, c910_clk feeds the CPU cluster. It could be glitchlessly reparented to one of the two PLLs: either to cpu_pll0 indirectly through c910_i0_clk, or to cpu_pll1 directly. To achieve glitchless rate change, customized clock operations are implemented for c910_clk: on rate change, the PLL not currently in use is configured to the requested rate first, then c910_clk reparents to it. Additionally, c910_bus_clk, which in turn takes c910_clk as parent, has a frequency limit of 750MHz. A clock notifier is registered on c910_clk to adjust c910_bus_clk on c910_clk rate change. Reviewed-by: Drew Fustini Signed-off-by: Yao Zi Signed-off-by: Drew Fustini --- drivers/clk/thead/clk-th1520-ap.c | 148 +++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 2 deletions(-) diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c index 79f001a047b2..3a6847f1c950 100644 --- a/drivers/clk/thead/clk-th1520-ap.c +++ b/drivers/clk/thead/clk-th1520-ap.c @@ -7,9 +7,11 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -34,6 +36,9 @@ #define TH1520_PLL_LOCK_TIMEOUT_US 44 #define TH1520_PLL_STABLE_DELAY_US 30 +/* c910_bus_clk must be kept below 750MHz for stability */ +#define TH1520_C910_BUS_MAX_RATE (750 * 1000 * 1000) + struct ccu_internal { u8 shift; u8 width; @@ -472,6 +477,72 @@ static const struct clk_ops clk_pll_ops = { .set_rate = ccu_pll_set_rate, }; +/* + * c910_clk could be reparented glitchlessly for DVFS. There are two parents, + * - c910_i0_clk, derived from cpu_pll0_clk or osc_24m. + * - cpu_pll1_clk, which provides the exact same set of rates as cpu_pll0_clk. + * + * During rate setting, always forward the request to the unused parent, and + * then switch c910_clk to it to avoid glitch. + */ +static u8 c910_clk_get_parent(struct clk_hw *hw) +{ + return clk_mux_ops.get_parent(hw); +} + +static int c910_clk_set_parent(struct clk_hw *hw, u8 index) +{ + return clk_mux_ops.set_parent(hw, index); +} + +static unsigned long c910_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate; +} + +static int c910_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + u8 alt_parent_index = !c910_clk_get_parent(hw); + struct clk_hw *alt_parent; + + alt_parent = clk_hw_get_parent_by_index(hw, alt_parent_index); + + req->rate = clk_hw_round_rate(alt_parent, req->rate); + req->best_parent_hw = alt_parent; + req->best_parent_rate = req->rate; + + return 0; +} + +static int c910_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return -EOPNOTSUPP; +} + +static int c910_clk_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate, u8 index) +{ + struct clk_hw *parent = clk_hw_get_parent_by_index(hw, index); + + clk_set_rate(parent->clk, parent_rate); + + c910_clk_set_parent(hw, index); + + return 0; +} + +static const struct clk_ops c910_clk_ops = { + .get_parent = c910_clk_get_parent, + .set_parent = c910_clk_set_parent, + .recalc_rate = c910_clk_recalc_rate, + .determine_rate = c910_clk_determine_rate, + .set_rate = c910_clk_set_rate, + .set_rate_and_parent = c910_clk_set_rate_and_parent, +}; + static const struct clk_parent_data osc_24m_clk[] = { { .index = 0 } }; @@ -672,7 +743,8 @@ static const struct clk_parent_data c910_i0_parents[] = { static struct ccu_mux c910_i0_clk = { .clkid = CLK_C910_I0, .reg = 0x100, - .mux = TH_CCU_MUX("c910-i0", c910_i0_parents, 1, 1), + .mux = TH_CCU_MUX_FLAGS("c910-i0", c910_i0_parents, 1, 1, + CLK_SET_RATE_PARENT, CLK_MUX_ROUND_CLOSEST), }; static const struct clk_parent_data c910_parents[] = { @@ -683,7 +755,14 @@ static const struct clk_parent_data c910_parents[] = { static struct ccu_mux c910_clk = { .clkid = CLK_C910, .reg = 0x100, - .mux = TH_CCU_MUX("c910", c910_parents, 0, 1), + .mux = { + .mask = BIT(0), + .shift = 0, + .hw.init = CLK_HW_INIT_PARENTS_DATA("c910", + c910_parents, + &c910_clk_ops, + CLK_SET_RATE_PARENT), + }, }; static struct ccu_div c910_bus_clk = { @@ -1372,11 +1451,69 @@ static const struct th1520_plat_data th1520_vo_platdata = { .nr_gate_clks = ARRAY_SIZE(th1520_vo_gate_clks), }; +/* + * Maintain clock rate of c910_bus_clk below TH1520_C910_BUS_MAX_RATE (750MHz) + * when its parent, c910_clk, changes the rate. + * + * Additionally, TRM is unclear about c910_bus_clk behavior when the divisor is + * set below 2, thus we should ensure the new divisor stays in (2, MAXDIVISOR). + */ +static unsigned long c910_bus_clk_divisor(struct ccu_div *cd, + unsigned long parent_rate) +{ + return clamp(DIV_ROUND_UP(parent_rate, TH1520_C910_BUS_MAX_RATE), + 2U, 1U << cd->div.width); +} + +static int c910_clk_notifier_cb(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct clk_notifier_data *cnd = data; + unsigned long new_divisor, ref_rate; + + if (action != PRE_RATE_CHANGE && action != POST_RATE_CHANGE) + return NOTIFY_DONE; + + new_divisor = c910_bus_clk_divisor(&c910_bus_clk, cnd->new_rate); + + if (cnd->new_rate > cnd->old_rate) { + /* + * Scaling up. Adjust c910_bus_clk divisor + * - before c910_clk rate change to ensure the constraints + * aren't broken after scaling to higher rates, + * - after c910_clk rate change to keep c910_bus_clk as high as + * possible + */ + ref_rate = action == PRE_RATE_CHANGE ? + cnd->old_rate : cnd->new_rate; + clk_set_rate(c910_bus_clk.common.hw.clk, + ref_rate / new_divisor); + } else if (cnd->new_rate < cnd->old_rate && + action == POST_RATE_CHANGE) { + /* + * Scaling down. Adjust c910_bus_clk divisor only after + * c910_clk rate change to keep c910_bus_clk as high as + * possible, Scaling down never breaks the constraints. + */ + clk_set_rate(c910_bus_clk.common.hw.clk, + cnd->new_rate / new_divisor); + } else { + return NOTIFY_DONE; + } + + return NOTIFY_OK; +} + +static struct notifier_block c910_clk_notifier = { + .notifier_call = c910_clk_notifier_cb, +}; + static int th1520_clk_probe(struct platform_device *pdev) { const struct th1520_plat_data *plat_data; struct device *dev = &pdev->dev; struct clk_hw_onecell_data *priv; + struct clk *notifier_clk; struct regmap *map; void __iomem *base; @@ -1463,6 +1600,13 @@ static int th1520_clk_probe(struct platform_device *pdev) ret = devm_clk_hw_register(dev, &emmc_sdio_ref_clk.hw); if (ret) return ret; + + notifier_clk = devm_clk_hw_get_clk(dev, &c910_clk.mux.hw, + "dvfs"); + ret = devm_clk_notifier_register(dev, notifier_clk, + &c910_clk_notifier); + if (ret) + return ret; } ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, priv); From 47231ba4cb225c991a6a9db7420e2607d1108a95 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 24 Dec 2025 12:22:40 +0100 Subject: [PATCH 094/165] clk: lmk04832: Simplify with scoped for each OF child loop Use scoped for-each loop when iterating over device nodes to make code a bit simpler. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Stephen Boyd --- drivers/clk/clk-lmk04832.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/clk-lmk04832.c b/drivers/clk/clk-lmk04832.c index b2107b31efa2..9bf86caad829 100644 --- a/drivers/clk/clk-lmk04832.c +++ b/drivers/clk/clk-lmk04832.c @@ -1400,7 +1400,6 @@ static int lmk04832_probe(struct spi_device *spi) { const struct lmk04832_device_info *info; int rdbk_pin = RDBK_CLKIN_SEL1; - struct device_node *child; struct lmk04832 *lmk; u8 tmp[3]; int ret; @@ -1462,14 +1461,13 @@ static int lmk04832_probe(struct spi_device *spi) device_property_read_u32(lmk->dev, "ti,sysref-pulse-count", &lmk->sysref_pulse_cnt); - for_each_child_of_node(lmk->dev->of_node, child) { + for_each_child_of_node_scoped(lmk->dev->of_node, child) { int reg; ret = of_property_read_u32(child, "reg", ®); if (ret) { dev_err(lmk->dev, "missing reg property in child: %s\n", child->full_name); - of_node_put(child); return ret; } From 9925fda8258d68878d58513b344ec9783599e26b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 24 Dec 2025 12:22:41 +0100 Subject: [PATCH 095/165] clk: scpi: Simplify with scoped for each OF child loop Use scoped for-each loop when iterating over device nodes to make code a bit simpler. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Sudeep Holla Signed-off-by: Stephen Boyd --- drivers/clk/clk-scpi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index 0b592de7bdb2..7806569cd0d5 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -265,20 +265,19 @@ static int scpi_clocks_probe(struct platform_device *pdev) { int ret; struct device *dev = &pdev->dev; - struct device_node *child, *np = dev->of_node; + struct device_node *np = dev->of_node; const struct of_device_id *match; if (!get_scpi_ops()) return -ENXIO; - for_each_available_child_of_node(np, child) { + for_each_available_child_of_node_scoped(np, child) { match = of_match_node(scpi_clk_match, child); if (!match) continue; ret = scpi_clk_add(dev, child, match); if (ret) { scpi_clocks_remove(pdev); - of_node_put(child); return ret; } From faee3e39e647d79897e15fc74146758ce09b0806 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 24 Dec 2025 12:22:42 +0100 Subject: [PATCH 096/165] clk: versatile: impd1: Simplify with scoped for each OF child loop Use scoped for-each loop when iterating over device nodes to make code a bit simpler. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Sudeep Holla Reviewed-by: Linus Walleij Signed-off-by: Stephen Boyd --- drivers/clk/versatile/clk-impd1.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c index 85c395df9c00..328dd47f1e43 100644 --- a/drivers/clk/versatile/clk-impd1.c +++ b/drivers/clk/versatile/clk-impd1.c @@ -104,15 +104,12 @@ static int integrator_impd1_clk_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; - struct device_node *child; int ret = 0; - for_each_available_child_of_node(np, child) { + for_each_available_child_of_node_scoped(np, child) { ret = integrator_impd1_clk_spawn(dev, np, child); - if (ret) { - of_node_put(child); + if (ret) break; - } } return ret; From ef9b3b4dbe767e4ac642a88dc0507927ac545047 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Wed, 31 Dec 2025 13:22:00 +0100 Subject: [PATCH 097/165] clk: clk-apple-nco: Add "apple,t8103-nco" compatible After discussion with the devicetree maintainers we agreed to not extend lists with the generic compatible "apple,nco" anymore [1]. Use "apple,t8103-nco" as base compatible as it is the SoC the driver and bindings were written for. [1]: https://lore.kernel.org/asahi/12ab93b7-1fc2-4ce0-926e-c8141cfe81bf@kernel.org/ Fixes: 6641057d5dba ("clk: clk-apple-nco: Add driver for Apple NCO") Cc: stable@vger.kernel.org Acked-by: Stephen Boyd Reviewed-by: Neal Gompa Signed-off-by: Janne Grunau Signed-off-by: Stephen Boyd --- drivers/clk/clk-apple-nco.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/clk-apple-nco.c b/drivers/clk/clk-apple-nco.c index d3ced4a0f029..434c067968bb 100644 --- a/drivers/clk/clk-apple-nco.c +++ b/drivers/clk/clk-apple-nco.c @@ -320,6 +320,7 @@ static int applnco_probe(struct platform_device *pdev) } static const struct of_device_id applnco_ids[] = { + { .compatible = "apple,t8103-nco" }, { .compatible = "apple,nco" }, { } }; From f47c1b77d0a2a9c0d49ec14302e74f933398d1a3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 1 Dec 2025 10:42:26 +0100 Subject: [PATCH 098/165] clk: Move clk_{save,restore}_context() to COMMON_CLK section The clk_save_context() and clk_restore_context() helpers are only implemented by the Common Clock Framework. They are not available when using legacy clock frameworks. Dummy implementations are provided, but only if no clock support is available at all. Hence when CONFIG_HAVE_CLK=y, but CONFIG_COMMON_CLK is not enabled: m68k-linux-gnu-ld: drivers/net/phy/air_en8811h.o: in function `en8811h_resume': air_en8811h.c:(.text+0x83e): undefined reference to `clk_restore_context' m68k-linux-gnu-ld: drivers/net/phy/air_en8811h.o: in function `en8811h_suspend': air_en8811h.c:(.text+0x856): undefined reference to `clk_save_context' Fix this by moving forward declarations and dummy implementions from the HAVE_CLK to the COMMON_CLK section. Fixes: 8b95d1ce3300c411 ("clk: Add functions to save/restore clock context en-masse") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202511301553.eaEz1nEW-lkp@intel.com/ Signed-off-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd --- include/linux/clk.h | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/include/linux/clk.h b/include/linux/clk.h index b607482ca77e..64ff118ffb1a 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -228,6 +228,23 @@ int devm_clk_rate_exclusive_get(struct device *dev, struct clk *clk); */ void clk_rate_exclusive_put(struct clk *clk); +/** + * clk_save_context - save clock context for poweroff + * + * Saves the context of the clock register for powerstates in which the + * contents of the registers will be lost. Occurs deep within the suspend + * code so locking is not necessary. + */ +int clk_save_context(void); + +/** + * clk_restore_context - restore clock context after poweroff + * + * This occurs with all clocks enabled. Occurs deep within the resume code + * so locking is not necessary. + */ +void clk_restore_context(void); + #else static inline int clk_notifier_register(struct clk *clk, @@ -293,6 +310,13 @@ static inline int devm_clk_rate_exclusive_get(struct device *dev, struct clk *cl static inline void clk_rate_exclusive_put(struct clk *clk) {} +static inline int clk_save_context(void) +{ + return 0; +} + +static inline void clk_restore_context(void) {} + #endif #ifdef CONFIG_HAVE_CLK_PREPARE @@ -933,23 +957,6 @@ struct clk *clk_get_parent(struct clk *clk); */ struct clk *clk_get_sys(const char *dev_id, const char *con_id); -/** - * clk_save_context - save clock context for poweroff - * - * Saves the context of the clock register for powerstates in which the - * contents of the registers will be lost. Occurs deep within the suspend - * code so locking is not necessary. - */ -int clk_save_context(void); - -/** - * clk_restore_context - restore clock context after poweroff - * - * This occurs with all clocks enabled. Occurs deep within the resume code - * so locking is not necessary. - */ -void clk_restore_context(void); - #else /* !CONFIG_HAVE_CLK */ static inline struct clk *clk_get(struct device *dev, const char *id) @@ -1129,13 +1136,6 @@ static inline struct clk *clk_get_sys(const char *dev_id, const char *con_id) return NULL; } -static inline int clk_save_context(void) -{ - return 0; -} - -static inline void clk_restore_context(void) {} - #endif /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ From d94f0f096ccf83b1a212788c62122c4b97ac8907 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 1 Dec 2025 10:42:27 +0100 Subject: [PATCH 099/165] clk: Merge prepare and unprepare sections contains two consecutive #ifdef/#else/#endif sections that check for CONFIG_HAVE_CLK_PREPARE: one for prepare-related functionality, and a second for unprepare-related functionality. Reduce #ifdef clutter by merging them. Signed-off-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd --- include/linux/clk.h | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/include/linux/clk.h b/include/linux/clk.h index 64ff118ffb1a..9e5291f37c50 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -329,8 +329,21 @@ static inline void clk_restore_context(void) {} * Must not be called from within atomic context. */ int clk_prepare(struct clk *clk); + +/** + * clk_unprepare - undo preparation of a clock source + * @clk: clock source + * + * This undoes a previously prepared clock. The caller must balance + * the number of prepare and unprepare calls. + * + * Must not be called from within atomic context. + */ +void clk_unprepare(struct clk *clk); + int __must_check clk_bulk_prepare(int num_clks, const struct clk_bulk_data *clks); +void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks); /** * clk_is_enabled_when_prepared - indicate if preparing a clock also enables it. @@ -355,6 +368,11 @@ static inline int clk_prepare(struct clk *clk) return 0; } +static inline void clk_unprepare(struct clk *clk) +{ + might_sleep(); +} + static inline int __must_check clk_bulk_prepare(int num_clks, const struct clk_bulk_data *clks) { @@ -362,34 +380,16 @@ clk_bulk_prepare(int num_clks, const struct clk_bulk_data *clks) return 0; } -static inline bool clk_is_enabled_when_prepared(struct clk *clk) -{ - return false; -} -#endif - -/** - * clk_unprepare - undo preparation of a clock source - * @clk: clock source - * - * This undoes a previously prepared clock. The caller must balance - * the number of prepare and unprepare calls. - * - * Must not be called from within atomic context. - */ -#ifdef CONFIG_HAVE_CLK_PREPARE -void clk_unprepare(struct clk *clk); -void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks); -#else -static inline void clk_unprepare(struct clk *clk) -{ - might_sleep(); -} static inline void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks) { might_sleep(); } + +static inline bool clk_is_enabled_when_prepared(struct clk *clk) +{ + return false; +} #endif #ifdef CONFIG_HAVE_CLK From abe368db117ea61ace90880c80a12ee3c0d619e6 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 1 Dec 2025 10:42:28 +0100 Subject: [PATCH 100/165] clk: Annotate #else and #endif Annotate the #else and #endif keywords in large #ifdef/#else/#endif sections, to improve readability. Signed-off-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd --- include/linux/clk.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/clk.h b/include/linux/clk.h index 9e5291f37c50..efb91604d3f6 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -245,7 +245,7 @@ int clk_save_context(void); */ void clk_restore_context(void); -#else +#else /* !CONFIG_COMMON_CLK */ static inline int clk_notifier_register(struct clk *clk, struct notifier_block *nb) @@ -317,7 +317,7 @@ static inline int clk_save_context(void) static inline void clk_restore_context(void) {} -#endif +#endif /* !CONFIG_COMMON_CLK */ #ifdef CONFIG_HAVE_CLK_PREPARE /** @@ -361,7 +361,7 @@ void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks); * to be right. */ bool clk_is_enabled_when_prepared(struct clk *clk); -#else +#else /* !CONFIG_HAVE_CLK_PREPARE */ static inline int clk_prepare(struct clk *clk) { might_sleep(); @@ -390,7 +390,7 @@ static inline bool clk_is_enabled_when_prepared(struct clk *clk) { return false; } -#endif +#endif /* !CONFIG_HAVE_CLK_PREPARE */ #ifdef CONFIG_HAVE_CLK /** @@ -1136,7 +1136,7 @@ static inline struct clk *clk_get_sys(const char *dev_id, const char *con_id) return NULL; } -#endif +#endif /* !CONFIG_HAVE_CLK */ /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ static inline int clk_prepare_enable(struct clk *clk) From dfb208b9aebb32dece9ceddfecf84b35a876fbd3 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Tue, 13 Jan 2026 22:11:45 +0000 Subject: [PATCH 101/165] clk: microchip: drop POLARFIRE from ARCH_MICROCHIP_POLARFIRE This driver is used by non-polarfire devices now, and the ARCH_MICROCHIP symbol has been defined for some time on RISCV so drop it without any functional change. Signed-off-by: Conor Dooley Link: https://lore.kernel.org/r/20260113-doing-surplus-dc45866f71d4@spud Signed-off-by: Claudiu Beznea --- drivers/clk/microchip/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig index 1b9e43eb5497..0c03b14699bf 100644 --- a/drivers/clk/microchip/Kconfig +++ b/drivers/clk/microchip/Kconfig @@ -5,8 +5,8 @@ config COMMON_CLK_PIC32 config MCHP_CLK_MPFS bool "Clk driver for PolarFire SoC" - depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST - default ARCH_MICROCHIP_POLARFIRE + depends on ARCH_MICROCHIP || COMPILE_TEST + default y depends on MFD_SYSCON select AUXILIARY_BUS select REGMAP_MMIO From e6584bda8d4584a58f020b559617ae7cfde51644 Mon Sep 17 00:00:00 2001 From: Pierre-Henry Moussay Date: Tue, 13 Jan 2026 22:11:46 +0000 Subject: [PATCH 102/165] dt-bindings: clock: mpfs-ccc: Add pic64gx compatibility pic64gx SoC Clock Conditioning Circuitry is compatibles with the Polarfire SoC Signed-off-by: Pierre-Henry Moussay Acked-by: Conor Dooley Reviewed-by: Claudiu Beznea Acked-by: Rob Herring (Arm) Signed-off-by: Conor Dooley Link: https://lore.kernel.org/r/20260113-guise-conceded-88030697b831@spud Signed-off-by: Claudiu Beznea --- .../devicetree/bindings/clock/microchip,mpfs-ccc.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/microchip,mpfs-ccc.yaml b/Documentation/devicetree/bindings/clock/microchip,mpfs-ccc.yaml index f1770360798f..9a6b50527c42 100644 --- a/Documentation/devicetree/bindings/clock/microchip,mpfs-ccc.yaml +++ b/Documentation/devicetree/bindings/clock/microchip,mpfs-ccc.yaml @@ -17,7 +17,11 @@ description: | properties: compatible: - const: microchip,mpfs-ccc + oneOf: + - items: + - const: microchip,pic64gx-ccc + - const: microchip,mpfs-ccc + - const: microchip,mpfs-ccc reg: items: From ec8c1f35b5aa7aa63bd398add63a8633adad532c Mon Sep 17 00:00:00 2001 From: Pierre-Henry Moussay Date: Tue, 13 Jan 2026 22:11:47 +0000 Subject: [PATCH 103/165] dt-bindings: clock: mpfs-clkcfg: Add pic64gx compatibility pic64gx has a clock controller compatible with mpfs-clkcfg. Don't permit the deprecated configuration that was never supported for this SoC. Signed-off-by: Pierre-Henry Moussay Acked-by: Krzysztof Kozlowski Reviewed-by: Claudiu Beznea Co-developed-by: Conor Dooley Signed-off-by: Conor Dooley Link: https://lore.kernel.org/r/20260113-glue-justifier-566ffab2ffd3@spud Signed-off-by: Claudiu Beznea --- .../bindings/clock/microchip,mpfs-clkcfg.yaml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml b/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml index ee4f31596d97..a23703c281d1 100644 --- a/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml +++ b/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml @@ -19,7 +19,11 @@ description: | properties: compatible: - const: microchip,mpfs-clkcfg + oneOf: + - items: + - const: microchip,pic64gx-clkcfg + - const: microchip,mpfs-clkcfg + - const: microchip,mpfs-clkcfg reg: oneOf: @@ -69,6 +73,16 @@ required: - clocks - '#clock-cells' +if: + properties: + compatible: + contains: + const: microchip,pic64gx-clkcfg +then: + properties: + reg: + maxItems: 1 + additionalProperties: false examples: From 5a4326f2e3b1edfb3329c1bee59035dc9f048b59 Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Mon, 24 Nov 2025 08:10:02 -0500 Subject: [PATCH 104/165] clk: renesas: rzg2l: Remove DSI clock rate restrictions Convert the limited MIPI clock calculations to a full range of settings based on math including H/W limitation validation. Since the required DSI division setting must be specified from external sources before calculations, expose a new API to set it. Signed-off-by: Chris Brandt Reviewed-by: Biju Das Tested-by: Biju Das Reviewed-by: Hugo Villeneuve Tested-by: Hugo Villeneuve Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251124131003.992554-2-chris.brandt@renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rzg2l-cpg.c | 174 ++++++++++++++++++++++++++------ include/linux/clk/renesas.h | 11 ++ 2 files changed, 154 insertions(+), 31 deletions(-) diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index f670c6408ea1..3ce28d553e4c 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,17 @@ #define MSTOP_OFF(conf) FIELD_GET(GENMASK(31, 16), (conf)) #define MSTOP_MASK(conf) FIELD_GET(GENMASK(15, 0), (conf)) +#define PLL5_FOUTVCO_MIN 800000000 +#define PLL5_FOUTVCO_MAX 3000000000 +#define PLL5_POSTDIV_MIN 1 +#define PLL5_POSTDIV_MAX 7 +#define PLL5_REFDIV_MIN 1 +#define PLL5_REFDIV_MAX 2 +#define PLL5_INTIN_MIN 20 +#define PLL5_INTIN_MAX 320 +#define PLL5_HSCLK_MIN 10000000 +#define PLL5_HSCLK_MAX 187500000 + /** * struct clk_hw_data - clock hardware data * @hw: clock hw @@ -129,6 +141,12 @@ struct rzg2l_pll5_param { u8 pl5_spread; }; +/* PLL5 output will be used for DPI or MIPI-DSI */ +static int dsi_div_target = PLL5_TARGET_DPI; + +/* Required division ratio for MIPI D-PHY clock depending on number of lanes and bpp. */ +static u8 dsi_div_ab_desired; + struct rzg2l_pll5_mux_dsi_div_param { u8 clksrc; u8 dsi_div_a; @@ -170,6 +188,11 @@ struct rzg2l_cpg_priv { struct rzg2l_pll5_mux_dsi_div_param mux_dsi_div_params; }; +static inline u8 rzg2l_cpg_div_ab(u8 a, u8 b) +{ + return (b + 1) << a; +} + static void rzg2l_cpg_del_clk_provider(void *data) { of_clk_del_provider(data); @@ -556,24 +579,121 @@ rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core, return clk_hw->clk; } +/* + * VCO-->[POSTDIV1,2]--FOUTPOSTDIV--------------->| + * | |-->[1/(DSI DIV A * B)]--> MIPI_DSI_VCLK + * |-->[1/2]--FOUT1PH0-->| + * | + * |------->[1/16]--------------------------------> hsclk (MIPI-PHY) + */ static unsigned long -rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params, +rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_cpg_priv *priv, + struct rzg2l_pll5_param *params, unsigned long rate) { - unsigned long foutpostdiv_rate, foutvco_rate; + const u32 extal_hz = EXTAL_FREQ_IN_MEGA_HZ * MEGA; + unsigned long foutpostdiv_rate; + unsigned int a, b, odd; + unsigned long hsclk; + u8 dsi_div_ab_calc; + u64 foutvco_rate; - params->pl5_intin = rate / MEGA; - params->pl5_fracin = div_u64(((u64)rate % MEGA) << 24, MEGA); - params->pl5_refdiv = 2; - params->pl5_postdiv1 = 1; - params->pl5_postdiv2 = 1; + if (dsi_div_target == PLL5_TARGET_DSI) { + /* Check hsclk */ + hsclk = rate * dsi_div_ab_desired / 16; + if (hsclk < PLL5_HSCLK_MIN || hsclk > PLL5_HSCLK_MAX) { + dev_err(priv->dev, "hsclk out of range\n"); + return 0; + } + + /* Determine the correct clock source based on even/odd of the divider */ + odd = dsi_div_ab_desired & 1; + if (odd) { + priv->mux_dsi_div_params.clksrc = 0; /* FOUTPOSTDIV */ + dsi_div_ab_calc = dsi_div_ab_desired; + } else { + priv->mux_dsi_div_params.clksrc = 1; /* FOUT1PH0 */ + dsi_div_ab_calc = dsi_div_ab_desired / 2; + } + + /* Calculate the DIV_DSI_A and DIV_DSI_B based on the desired divider */ + for (a = 0; a < 4; a++) { + /* FOUT1PH0: Max output of DIV_DSI_A is 750MHz so at least 1/2 to be safe */ + if (!odd && a == 0) + continue; + + /* FOUTPOSTDIV: DIV_DSI_A must always be 1/1 */ + if (odd && a != 0) + break; + + for (b = 0; b < 16; b++) { + /* FOUTPOSTDIV: DIV_DSI_B must always be odd divider 1/(b+1) */ + if (odd && b & 1) + continue; + + if (rzg2l_cpg_div_ab(a, b) == dsi_div_ab_calc) { + priv->mux_dsi_div_params.dsi_div_a = a; + priv->mux_dsi_div_params.dsi_div_b = b; + goto calc_pll_clk; + } + } + } + + dev_err(priv->dev, "Failed to calculate DIV_DSI_A,B\n"); + + return 0; + } else if (dsi_div_target == PLL5_TARGET_DPI) { + /* Fixed settings for DPI */ + priv->mux_dsi_div_params.clksrc = 0; + priv->mux_dsi_div_params.dsi_div_a = 3; /* Divided by 8 */ + priv->mux_dsi_div_params.dsi_div_b = 0; /* Divided by 1 */ + dsi_div_ab_desired = rzg2l_cpg_div_ab(priv->mux_dsi_div_params.dsi_div_a, + priv->mux_dsi_div_params.dsi_div_b); + } + +calc_pll_clk: + /* PLL5 (MIPI_DSI_PLLCLK) = VCO / POSTDIV1 / POSTDIV2 */ + for (params->pl5_postdiv1 = PLL5_POSTDIV_MIN; + params->pl5_postdiv1 <= PLL5_POSTDIV_MAX; + params->pl5_postdiv1++) { + for (params->pl5_postdiv2 = PLL5_POSTDIV_MIN; + params->pl5_postdiv2 <= PLL5_POSTDIV_MAX; + params->pl5_postdiv2++) { + foutvco_rate = rate * params->pl5_postdiv1 * params->pl5_postdiv2 * + dsi_div_ab_desired; + if (foutvco_rate <= PLL5_FOUTVCO_MIN || foutvco_rate >= PLL5_FOUTVCO_MAX) + continue; + + for (params->pl5_refdiv = PLL5_REFDIV_MIN; + params->pl5_refdiv <= PLL5_REFDIV_MAX; + params->pl5_refdiv++) { + u32 rem; + + params->pl5_intin = div_u64_rem(foutvco_rate * params->pl5_refdiv, + extal_hz, &rem); + + if (params->pl5_intin < PLL5_INTIN_MIN || + params->pl5_intin > PLL5_INTIN_MAX) + continue; + + params->pl5_fracin = div_u64((u64)rem << 24, extal_hz); + + goto clk_valid; + } + } + } + + dev_err(priv->dev, "Failed to calculate PLL5 settings\n"); + return 0; + +clk_valid: params->pl5_spread = 0x16; foutvco_rate = div_u64(mul_u32_u32(EXTAL_FREQ_IN_MEGA_HZ * MEGA, (params->pl5_intin << 24) + params->pl5_fracin), params->pl5_refdiv) >> 24; - foutpostdiv_rate = DIV_ROUND_CLOSEST(foutvco_rate, - params->pl5_postdiv1 * params->pl5_postdiv2); + foutpostdiv_rate = DIV_U64_ROUND_CLOSEST(foutvco_rate, + params->pl5_postdiv1 * params->pl5_postdiv2); return foutpostdiv_rate; } @@ -607,7 +727,7 @@ static unsigned long rzg2l_cpg_get_vclk_parent_rate(struct clk_hw *hw, struct rzg2l_pll5_param params; unsigned long parent_rate; - parent_rate = rzg2l_cpg_get_foutpostdiv_rate(¶ms, rate); + parent_rate = rzg2l_cpg_get_foutpostdiv_rate(priv, ¶ms, rate); if (priv->mux_dsi_div_params.clksrc) parent_rate /= 2; @@ -623,9 +743,19 @@ static int rzg2l_cpg_dsi_div_determine_rate(struct clk_hw *hw, req->best_parent_rate = rzg2l_cpg_get_vclk_parent_rate(hw, req->rate); + if (!req->best_parent_rate) + return -EINVAL; + return 0; } +void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) +{ + dsi_div_ab_desired = divider; + dsi_div_target = target; +} +EXPORT_SYMBOL_GPL(rzg2l_cpg_dsi_div_set_divider); + static int rzg2l_cpg_dsi_div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) @@ -796,22 +926,6 @@ struct sipll5 { #define to_sipll5(_hw) container_of(_hw, struct sipll5, hw) -static unsigned long rzg2l_cpg_get_vclk_rate(struct clk_hw *hw, - unsigned long rate) -{ - struct sipll5 *sipll5 = to_sipll5(hw); - struct rzg2l_cpg_priv *priv = sipll5->priv; - unsigned long vclk; - - vclk = rate / ((1 << priv->mux_dsi_div_params.dsi_div_a) * - (priv->mux_dsi_div_params.dsi_div_b + 1)); - - if (priv->mux_dsi_div_params.clksrc) - vclk /= 2; - - return vclk; -} - static unsigned long rzg2l_cpg_sipll5_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -856,9 +970,9 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw, if (!rate) return -EINVAL; - vclk_rate = rzg2l_cpg_get_vclk_rate(hw, rate); + vclk_rate = rate / dsi_div_ab_desired; sipll5->foutpostdiv_rate = - rzg2l_cpg_get_foutpostdiv_rate(¶ms, vclk_rate); + rzg2l_cpg_get_foutpostdiv_rate(priv, ¶ms, vclk_rate); /* Put PLL5 into standby mode */ writel(CPG_SIPLL5_STBY_RESETB_WEN, priv->base + CPG_SIPLL5_STBY); @@ -945,9 +1059,7 @@ rzg2l_cpg_sipll5_register(const struct cpg_core_clk *core, if (ret) return ERR_PTR(ret); - priv->mux_dsi_div_params.clksrc = 1; /* Use clk src 1 for DSI */ - priv->mux_dsi_div_params.dsi_div_a = 1; /* Divided by 2 */ - priv->mux_dsi_div_params.dsi_div_b = 2; /* Divided by 3 */ + rzg2l_cpg_dsi_div_set_divider(8, PLL5_TARGET_DPI); return clk_hw->clk; } diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h index 69d8159deee3..c360df9fa735 100644 --- a/include/linux/clk/renesas.h +++ b/include/linux/clk/renesas.h @@ -35,6 +35,17 @@ void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev); #define cpg_mssr_detach_dev NULL #endif +enum { + PLL5_TARGET_DPI, + PLL5_TARGET_DSI +}; + +#ifdef CONFIG_CLK_RZG2L +void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target); +#else +static inline void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) { } +#endif + /** * struct rzv2h_pll_limits - PLL parameter constraints * From 4fef3fd633be4a1a18c490a63f4131284f6ee0f4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 15 Jan 2026 13:36:56 +0100 Subject: [PATCH 105/165] clk: renesas: Add missing log message terminators Complete printed messages should be terminated by newline characters. Signed-off-by: Geert Uytterhoeven Reviewed-by: Brian Masney Link: https://patch.msgid.link/cd0b3624066b80ed0bb00d489c99e2c1a06d755f.1768480559.git.geert+renesas@glider.be --- drivers/clk/renesas/clk-vbattb.c | 4 ++-- drivers/clk/renesas/renesas-cpg-mssr.c | 2 +- drivers/clk/renesas/rzg2l-cpg.c | 6 +++--- drivers/clk/renesas/rzv2h-cpg.c | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/clk/renesas/clk-vbattb.c b/drivers/clk/renesas/clk-vbattb.c index ff9d1ead455c..2a961775b1d8 100644 --- a/drivers/clk/renesas/clk-vbattb.c +++ b/drivers/clk/renesas/clk-vbattb.c @@ -69,11 +69,11 @@ static void vbattb_clk_action(void *data) ret = reset_control_assert(rstc); if (ret) - dev_err(dev, "Failed to de-assert reset!"); + dev_err(dev, "Failed to de-assert reset!\n"); ret = pm_runtime_put_sync(dev); if (ret < 0) - dev_err(dev, "Failed to runtime suspend!"); + dev_err(dev, "Failed to runtime suspend!\n"); of_clk_del_provider(dev->of_node); } diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index fad3d0cf84e4..4824607d56c0 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -404,7 +404,7 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, } if (IS_ERR(clk)) - dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, + dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx, PTR_ERR(clk)); else dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 3ce28d553e4c..c0584bab58a3 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -979,7 +979,7 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw, ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val, !(val & CPG_SIPLL5_MON_PLL5_LOCK), 100, 250000); if (ret) { - dev_err(priv->dev, "failed to release pll5 lock"); + dev_err(priv->dev, "failed to release pll5 lock\n"); return ret; } @@ -1006,7 +1006,7 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw, ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val, (val & CPG_SIPLL5_MON_PLL5_LOCK), 100, 250000); if (ret) { - dev_err(priv->dev, "failed to lock pll5"); + dev_err(priv->dev, "failed to lock pll5\n"); return ret; } @@ -1214,7 +1214,7 @@ static struct clk } if (IS_ERR(clk)) - dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, + dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx, PTR_ERR(clk)); else dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index 1db92284025e..f6c47fb89bca 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -602,7 +602,7 @@ static int rzv2h_cpg_pll_set_rate(struct pll_clk *pll_clk, val, !(val & CPG_PLL_MON_LOCK), 100, 2000); if (ret) { - dev_err(priv->dev, "Failed to put PLLDSI into standby mode"); + dev_err(priv->dev, "Failed to put PLLDSI into standby mode\n"); return ret; } @@ -630,7 +630,7 @@ static int rzv2h_cpg_pll_set_rate(struct pll_clk *pll_clk, val, (val & CPG_PLL_MON_LOCK), 100, 2000); if (ret) { - dev_err(priv->dev, "Failed to put PLLDSI into normal mode"); + dev_err(priv->dev, "Failed to put PLLDSI into normal mode\n"); return ret; } @@ -1013,7 +1013,7 @@ static struct clk } if (IS_ERR(clk)) - dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, + dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx, PTR_ERR(clk)); else dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", From fce0d0bd9c20fefd180ea9e8362d619182f97a1d Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Thu, 15 Jan 2026 13:05:42 +0800 Subject: [PATCH 106/165] clk: tegra: tegra124-emc: Fix potential memory leak in tegra124_clk_register_emc() If clk_register() fails, call kfree to release "tegra". Fixes: 2db04f16b589 ("clk: tegra: Add EMC clock driver") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Reviewed-by: Brian Masney Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra124-emc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c index 2a6db0434281..0f6fb776b229 100644 --- a/drivers/clk/tegra/clk-tegra124-emc.c +++ b/drivers/clk/tegra/clk-tegra124-emc.c @@ -538,8 +538,10 @@ struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np tegra->hw.init = &init; clk = clk_register(NULL, &tegra->hw); - if (IS_ERR(clk)) + if (IS_ERR(clk)) { + kfree(tegra); return clk; + } tegra->prev_parent = clk_hw_get_parent_by_index( &tegra->hw, emc_get_parent(&tegra->hw))->clk; From 349f02c0f5d4ee147c582b89cadd553bd534028a Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:33 -0500 Subject: [PATCH 107/165] clk: qcom: regmap-divider: convert from divider_ro_round_rate() to divider_ro_determine_rate() The divider_ro_round_rate() function is now deprecated, so let's migrate to divider_ro_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: b6f90511c165 ("clk: qcom: regmap-divider: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney Reviewed-by: Abel Vesa Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260108-clk-divider-round-rate-v1-15-535a3ed73bf3@redhat.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-regmap-divider.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/clk/qcom/clk-regmap-divider.c b/drivers/clk/qcom/clk-regmap-divider.c index 4f5395f0ab6d..af9c01dd7853 100644 --- a/drivers/clk/qcom/clk-regmap-divider.c +++ b/drivers/clk/qcom/clk-regmap-divider.c @@ -26,12 +26,8 @@ static int div_ro_determine_rate(struct clk_hw *hw, val >>= divider->shift; val &= BIT(divider->width) - 1; - req->rate = divider_ro_round_rate(hw, req->rate, - &req->best_parent_rate, NULL, - divider->width, - CLK_DIVIDER_ROUND_CLOSEST, val); - - return 0; + return divider_ro_determine_rate(hw, req, NULL, divider->width, + CLK_DIVIDER_ROUND_CLOSEST, val); } static int div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) From d8300e6e078a3a44ac0c75c6d8ba46d78ab94035 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:34 -0500 Subject: [PATCH 108/165] clk: qcom: regmap-divider: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: b6f90511c165 ("clk: qcom: regmap-divider: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney Reviewed-by: Abel Vesa Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260108-clk-divider-round-rate-v1-16-535a3ed73bf3@redhat.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-regmap-divider.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/clk/qcom/clk-regmap-divider.c b/drivers/clk/qcom/clk-regmap-divider.c index af9c01dd7853..672e82caf205 100644 --- a/drivers/clk/qcom/clk-regmap-divider.c +++ b/drivers/clk/qcom/clk-regmap-divider.c @@ -34,12 +34,8 @@ static int div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct clk_regmap_div *divider = to_clk_regmap_div(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - NULL, - divider->width, - CLK_DIVIDER_ROUND_CLOSEST); - - return 0; + return divider_determine_rate(hw, req, NULL, divider->width, + CLK_DIVIDER_ROUND_CLOSEST); } static int div_set_rate(struct clk_hw *hw, unsigned long rate, From 1acce02756a3be28b405744bce09075160fdd31d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 6 Jan 2026 13:19:47 +0100 Subject: [PATCH 109/165] clk: tegra: Adjust callbacks in tegra_clock_pm System suspend and resume callbacks run after the core has bumped up the runtime PM usage counters of all devices, so these callbacks need not worry about runtime PM reference counting. Accordingly, to eliminate useless overhead related to runtime PM usage counter manipulation, set the suspend callback pointer in tegra_clock_pm to a wrapper around pm_runtime_resume() called tegra_clock_suspend() and do not set the resume callback in it at all. This will also facilitate a planned change of the pm_runtime_put() return type to void in the future. Signed-off-by: Rafael J. Wysocki Acked-by: Jon Hunter Tested-by: Jon Hunter Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-device.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-device.c b/drivers/clk/tegra/clk-device.c index 8c8e2b853a99..e0531f6dcfb0 100644 --- a/drivers/clk/tegra/clk-device.c +++ b/drivers/clk/tegra/clk-device.c @@ -174,8 +174,19 @@ static int tegra_clock_probe(struct platform_device *pdev) * problem. In practice this makes no difference from a power management * perspective since voltage is kept at a nominal level during suspend anyways. */ +static inline int tegra_clock_suspend(struct device *dev) +{ + int ret; + + ret = pm_runtime_resume(dev); + if (ret < 0) + return ret; + + return 0; +} + static const struct dev_pm_ops tegra_clock_pm = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_resume_and_get, pm_runtime_put) + SET_SYSTEM_SLEEP_PM_OPS(tegra_clock_suspend, NULL) }; static const struct of_device_id tegra_clock_match[] = { From 2ea99dade57e094625726de1ced1e99b48fc767a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 2 Jan 2026 13:50:20 +0100 Subject: [PATCH 110/165] clk: tegra: tegra124-emc: Simplify with scoped for each OF child loop Use scoped for-each loop when iterating over device nodes to make code a bit simpler. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Jon Hunter Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra124-emc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c index 0f6fb776b229..251209ac50db 100644 --- a/drivers/clk/tegra/clk-tegra124-emc.c +++ b/drivers/clk/tegra/clk-tegra124-emc.c @@ -444,7 +444,6 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra, u32 ram_code) { struct emc_timing *timings_ptr; - struct device_node *child; int child_count = of_get_child_count(node); int i = 0, err; size_t size; @@ -458,12 +457,11 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra, timings_ptr = tegra->timings + tegra->num_timings; tegra->num_timings += child_count; - for_each_child_of_node(node, child) { + for_each_child_of_node_scoped(node, child) { struct emc_timing *timing = timings_ptr + (i++); err = load_one_timing_from_dt(tegra, timing, child); if (err) { - of_node_put(child); kfree(tegra->timings); return err; } From f521678d1921e0c1a206fa03a87b318d3e97d89b Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Thu, 4 Dec 2025 08:17:00 +0200 Subject: [PATCH 111/165] clk: tegra20: Reparent dsi clock to pll_d_out0 Reparent DSI clock to PLLD_OUT0 instead of directly descend from PLLD. Signed-off-by: Svyatoslav Ryhel Acked-by: Stephen Boyd Reviewed-by: Mikko Perttunen Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra20.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 2c58ce25af75..c606c2b160d6 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -802,9 +802,9 @@ static void __init tegra20_periph_clk_init(void) clks[TEGRA20_CLK_MC] = clk; /* dsi */ - clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0, - 48, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "dsi"); + clk = tegra_clk_register_periph_gate("dsi", "pll_d_out0", 0, + clk_base, 0, TEGRA20_CLK_DSI, + periph_clk_enb_refcnt); clks[TEGRA20_CLK_DSI] = clk; /* pex */ From a6d8abf5b4549f8dafe68777f54436d3ab2fbacd Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Wed, 22 Oct 2025 17:20:29 +0300 Subject: [PATCH 112/165] clk: tegra: Set CSUS as vi_sensor's gate for Tegra20, Tegra30 and Tegra114 The CSUS clock is a clock gate for the output clock signal primarily sourced from the VI_SENSOR clock. This clock signal is used as an input MCLK clock for cameras. Unlike later Tegra SoCs, the Tegra 20 can change its CSUS parent, which is why csus_mux is added in a similar way to how CDEV1 and CDEV2 are handled. Signed-off-by: Svyatoslav Ryhel Reviewed-by: Mikko Perttunen Tested-by: Luca Ceresoli # tegra20, parallel camera Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra114.c | 7 ++++++- drivers/clk/tegra/clk-tegra20.c | 20 +++++++++++++------- drivers/clk/tegra/clk-tegra30.c | 7 ++++++- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 6c8e053311c3..a4f40533cc43 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -690,7 +690,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { [tegra_clk_tsec] = { .dt_id = TEGRA114_CLK_TSEC, .present = true }, [tegra_clk_xusb_host] = { .dt_id = TEGRA114_CLK_XUSB_HOST, .present = true }, [tegra_clk_msenc] = { .dt_id = TEGRA114_CLK_MSENC, .present = true }, - [tegra_clk_csus] = { .dt_id = TEGRA114_CLK_CSUS, .present = true }, [tegra_clk_mselect] = { .dt_id = TEGRA114_CLK_MSELECT, .present = true }, [tegra_clk_tsensor] = { .dt_id = TEGRA114_CLK_TSENSOR, .present = true }, [tegra_clk_i2s3] = { .dt_id = TEGRA114_CLK_I2S3, .present = true }, @@ -1046,6 +1045,12 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base, 0, 82, periph_clk_enb_refcnt); clks[TEGRA114_CLK_DSIB] = clk; + /* csus */ + clk = tegra_clk_register_periph_gate("csus", "vi_sensor", 0, + clk_base, 0, TEGRA114_CLK_CSUS, + periph_clk_enb_refcnt); + clks[TEGRA114_CLK_CSUS] = clk; + /* emc mux */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, ARRAY_SIZE(mux_pllmcp_clkm), diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index c606c2b160d6..9da82dd7965b 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -530,7 +530,6 @@ static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = { [tegra_clk_rtc] = { .dt_id = TEGRA20_CLK_RTC, .present = true }, [tegra_clk_timer] = { .dt_id = TEGRA20_CLK_TIMER, .present = true }, [tegra_clk_kbc] = { .dt_id = TEGRA20_CLK_KBC, .present = true }, - [tegra_clk_csus] = { .dt_id = TEGRA20_CLK_CSUS, .present = true }, [tegra_clk_vcp] = { .dt_id = TEGRA20_CLK_VCP, .present = true }, [tegra_clk_bsea] = { .dt_id = TEGRA20_CLK_BSEA, .present = true }, [tegra_clk_bsev] = { .dt_id = TEGRA20_CLK_BSEV, .present = true }, @@ -834,6 +833,12 @@ static void __init tegra20_periph_clk_init(void) clk_base, 0, 93, periph_clk_enb_refcnt); clks[TEGRA20_CLK_CDEV2] = clk; + /* csus */ + clk = tegra_clk_register_periph_gate("csus", "csus_mux", 0, + clk_base, 0, TEGRA20_CLK_CSUS, + periph_clk_enb_refcnt); + clks[TEGRA20_CLK_CSUS] = clk; + for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { data = &tegra_periph_clk_list[i]; clk = tegra_clk_register_periph_data(clk_base, data); @@ -1093,14 +1098,15 @@ static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec, hw = __clk_get_hw(clk); /* - * Tegra20 CDEV1 and CDEV2 clocks are a bit special case, their parent - * clock is created by the pinctrl driver. It is possible for clk user - * to request these clocks before pinctrl driver got probed and hence - * user will get an orphaned clock. That might be undesirable because - * user may expect parent clock to be enabled by the child. + * Tegra20 CDEV1, CDEV2 and CSUS clocks are a bit special case, their + * parent clock is created by the pinctrl driver. It is possible for + * clk user to request these clocks before pinctrl driver got probed + * and hence user will get an orphaned clock. That might be undesirable + * because user may expect parent clock to be enabled by the child. */ if (clkspec->args[0] == TEGRA20_CLK_CDEV1 || - clkspec->args[0] == TEGRA20_CLK_CDEV2) { + clkspec->args[0] == TEGRA20_CLK_CDEV2 || + clkspec->args[0] == TEGRA20_CLK_CSUS) { parent_hw = clk_hw_get_parent(hw); if (!parent_hw) return ERR_PTR(-EPROBE_DEFER); diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index e7ebb63970d3..ca738bc64615 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -780,7 +780,6 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = { [tegra_clk_rtc] = { .dt_id = TEGRA30_CLK_RTC, .present = true }, [tegra_clk_timer] = { .dt_id = TEGRA30_CLK_TIMER, .present = true }, [tegra_clk_kbc] = { .dt_id = TEGRA30_CLK_KBC, .present = true }, - [tegra_clk_csus] = { .dt_id = TEGRA30_CLK_CSUS, .present = true }, [tegra_clk_vcp] = { .dt_id = TEGRA30_CLK_VCP, .present = true }, [tegra_clk_bsea] = { .dt_id = TEGRA30_CLK_BSEA, .present = true }, [tegra_clk_bsev] = { .dt_id = TEGRA30_CLK_BSEV, .present = true }, @@ -1009,6 +1008,12 @@ static void __init tegra30_periph_clk_init(void) 0, 48, periph_clk_enb_refcnt); clks[TEGRA30_CLK_DSIA] = clk; + /* csus */ + clk = tegra_clk_register_periph_gate("csus", "vi_sensor", 0, + clk_base, 0, TEGRA30_CLK_CSUS, + periph_clk_enb_refcnt); + clks[TEGRA30_CLK_CSUS] = clk; + /* pcie */ clk = tegra_clk_register_periph_gate("pcie", "clk_m", 0, clk_base, 0, 70, periph_clk_enb_refcnt); From e897e86711b28f815fbbe542fe87a66b39123d1e Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Wed, 22 Oct 2025 17:20:31 +0300 Subject: [PATCH 113/165] clk: tegra30: Add CSI pad clock gates Tegra30 has CSI pad bits in both PLLD and PLLD2 clocks that are required for the correct work of the CSI block. Add CSI pad A and pad B clock gates with PLLD/PLLD2 parents, respectively. Add a plld2 spinlock, like one plld uses, to prevent simultaneous access since both the PLLDx and CSIx_PAD clocks use the same registers Signed-off-by: Svyatoslav Ryhel Reviewed-by: Mikko Perttunen Tested-by: Luca Ceresoli # tegra20, parallel camera Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra30.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index ca738bc64615..61fe527ee6c1 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -154,6 +154,7 @@ static unsigned long input_freq; static DEFINE_SPINLOCK(cml_lock); static DEFINE_SPINLOCK(pll_d_lock); +static DEFINE_SPINLOCK(pll_d2_lock); #define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ @@ -859,7 +860,7 @@ static void __init tegra30_pll_init(void) /* PLLD2 */ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0, - &pll_d2_params, NULL); + &pll_d2_params, &pll_d2_lock); clks[TEGRA30_CLK_PLL_D2] = clk; /* PLLD2_OUT0 */ @@ -1008,6 +1009,16 @@ static void __init tegra30_periph_clk_init(void) 0, 48, periph_clk_enb_refcnt); clks[TEGRA30_CLK_DSIA] = clk; + /* csia_pad */ + clk = clk_register_gate(NULL, "csia_pad", "pll_d", CLK_SET_RATE_PARENT, + clk_base + PLLD_BASE, 26, 0, &pll_d_lock); + clks[TEGRA30_CLK_CSIA_PAD] = clk; + + /* csib_pad */ + clk = clk_register_gate(NULL, "csib_pad", "pll_d2", CLK_SET_RATE_PARENT, + clk_base + PLLD2_BASE, 26, 0, &pll_d2_lock); + clks[TEGRA30_CLK_CSIB_PAD] = clk; + /* csus */ clk = tegra_clk_register_periph_gate("csus", "vi_sensor", 0, clk_base, 0, TEGRA30_CLK_CSUS, From aafaa4d875fb8ff525c514e69eb0440c69425c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Fri, 9 Jan 2026 17:27:23 +0000 Subject: [PATCH 114/165] clk: samsung: avoid warning message on legacy Exynos (auto clock gating) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We currently print a warning message that the IO memory size is not compatible with automatic clock gating for many Exynos-based boards, including legacy ones, even if not requested to enable automatic clock gating in the first place. Change the test in question to avoid that warning. Fixes: 298fac4f4b96 ("clk: samsung: Implement automatic clock gating mode for CMUs") Reported-by: Marek Szyprowski Closes: https://lore.kernel.org/all/8b2c412d-3e1e-4be0-a9d5-ef67f6f0d409@samsung.com/ Suggested-by: Marek Szyprowski Signed-off-by: André Draszik Reviewed-by: Peter Griffin Link: https://patch.msgid.link/20260109-clk-samsung-autoclk-updates-v1-1-2394dcf242a9@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 06ea5deef4ee..417ec1786b5e 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -462,7 +462,7 @@ void __init samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, const struct samsung_cmu_info *cmu, struct device_node *np) { - if (samsung_is_auto_capable(np) && cmu->auto_clock_gate) + if (cmu->auto_clock_gate && samsung_is_auto_capable(np)) ctx->auto_clock_gate = cmu->auto_clock_gate; ctx->gate_dbg_offset = cmu->gate_dbg_offset; From c9d24fe079027f143992a4a1c0be74c4f4455f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Fri, 9 Jan 2026 17:27:24 +0000 Subject: [PATCH 115/165] clk: samsung: fix sysreg save/restore when PM is enabled for CMU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, sysreg registers of a CMU that has PM and automatic clock gating enabled are not saved / restored during runtime PM (RPM) or s2idle. During normal suspend, they are accessed too late, after the CMU (and potentially power domain) have been shut down, causing an SError. The reason is that these registers are registered to be saved/restored via a syscore suspend handler which doesn't run during RPM or s2idle. During normal suspend, this handler runs after the CMU has been shut down. This registration happens as part of samsung_clk_extended_sleep_init() via samsung_en_dyn_root_clk_gating(). When PM is enabled for a CMU, registers must be saved/restored via exynos_arm64_cmu_suspend() / exynos_arm64_cmu_resume() respectively instead. These use their own data structures and are unrelated to anything that samsung_clk_extended_sleep_init() does. Calling it unconditionally from samsung_en_dyn_root_clk_gating() therefore isn't useful. Update the code to prepare sysreg save / restore in a similar way to how it handles other clock registers in the PM case already. exynos_arm64_cmu_suspend() / exynos_arm64_cmu_resume() already handle sysreg save/restore, just the setup was incorrect. Fixes: 298fac4f4b96 ("clk: samsung: Implement automatic clock gating mode for CMUs") Signed-off-by: André Draszik Reviewed-by: Peter Griffin Link: https://patch.msgid.link/20260109-clk-samsung-autoclk-updates-v1-2-2394dcf242a9@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-exynos-arm64.c | 32 +++++++++++++++++++++----- drivers/clk/samsung/clk.c | 19 ++++++++++----- drivers/clk/samsung/clk.h | 3 ++- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos-arm64.c b/drivers/clk/samsung/clk-exynos-arm64.c index 11e4d49f2390..35d4de233cc1 100644 --- a/drivers/clk/samsung/clk-exynos-arm64.c +++ b/drivers/clk/samsung/clk-exynos-arm64.c @@ -174,7 +174,7 @@ static int __init exynos_arm64_cmu_prepare_pm(struct device *dev, const struct samsung_cmu_info *cmu) { struct exynos_arm64_cmu_data *data = dev_get_drvdata(dev); - int i; + int i, ret; data->clk_save = samsung_clk_alloc_reg_dump(cmu->clk_regs, cmu->nr_clk_regs); @@ -182,8 +182,22 @@ static int __init exynos_arm64_cmu_prepare_pm(struct device *dev, return -ENOMEM; data->nr_clk_save = cmu->nr_clk_regs; + + if (cmu->nr_sysreg_clk_regs) { + data->clk_sysreg_save = + samsung_clk_alloc_reg_dump(cmu->sysreg_clk_regs, + cmu->nr_sysreg_clk_regs); + if (!data->clk_sysreg_save) { + ret = -ENOMEM; + goto free_clk_save; + } + + data->nr_clk_sysreg = cmu->nr_sysreg_clk_regs; + } + data->clk_suspend = cmu->suspend_regs; data->nr_clk_suspend = cmu->nr_suspend_regs; + data->nr_pclks = of_clk_get_parent_count(dev->of_node); if (!data->nr_pclks) return 0; @@ -191,23 +205,29 @@ static int __init exynos_arm64_cmu_prepare_pm(struct device *dev, data->pclks = devm_kcalloc(dev, sizeof(struct clk *), data->nr_pclks, GFP_KERNEL); if (!data->pclks) { - kfree(data->clk_save); - return -ENOMEM; + ret = -ENOMEM; + goto free_sysreg_save; } for (i = 0; i < data->nr_pclks; i++) { struct clk *clk = of_clk_get(dev->of_node, i); if (IS_ERR(clk)) { - kfree(data->clk_save); while (--i >= 0) clk_put(data->pclks[i]); - return PTR_ERR(clk); + ret = PTR_ERR(clk); + goto free_sysreg_save; } data->pclks[i] = clk; } return 0; + +free_sysreg_save: + kfree(data->clk_sysreg_save); +free_clk_save: + kfree(data->clk_save); + return ret; } /** @@ -305,7 +325,7 @@ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev, samsung_cmu_register_clocks(data->ctx, cmu, np); samsung_clk_of_add_provider(dev->of_node, data->ctx); /* sysreg DT nodes reference a clock in this CMU */ - samsung_en_dyn_root_clk_gating(np, data->ctx, cmu); + samsung_en_dyn_root_clk_gating(np, data->ctx, cmu, true); pm_runtime_put_sync(dev); return 0; diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 417ec1786b5e..9f68f079fd55 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -496,7 +496,8 @@ void __init samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, /* Enable Dynamic Root Clock Gating (DRCG) of bus components */ void samsung_en_dyn_root_clk_gating(struct device_node *np, struct samsung_clk_provider *ctx, - const struct samsung_cmu_info *cmu) + const struct samsung_cmu_info *cmu, + bool cmu_has_pm) { if (!ctx->auto_clock_gate) return; @@ -513,10 +514,16 @@ void samsung_en_dyn_root_clk_gating(struct device_node *np, regmap_write_bits(ctx->sysreg, ctx->memclk_offset, MEMCLK_EN, 0x0); - samsung_clk_extended_sleep_init(NULL, ctx->sysreg, - cmu->sysreg_clk_regs, - cmu->nr_sysreg_clk_regs, - NULL, 0); + if (!cmu_has_pm) + /* + * When a CMU has PM support, clocks are saved/restored + * via its PM handlers, so only register them with the + * syscore suspend / resume paths if PM is not in use. + */ + samsung_clk_extended_sleep_init(NULL, ctx->sysreg, + cmu->sysreg_clk_regs, + cmu->nr_sysreg_clk_regs, + NULL, 0); } } @@ -548,7 +555,7 @@ struct samsung_clk_provider * __init samsung_cmu_register_one( samsung_clk_of_add_provider(np, ctx); /* sysreg DT nodes reference a clock in this CMU */ - samsung_en_dyn_root_clk_gating(np, ctx, cmu); + samsung_en_dyn_root_clk_gating(np, ctx, cmu, false); return ctx; } diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index a56aa3be54d8..b1192ca03db5 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -476,7 +476,8 @@ struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( void samsung_en_dyn_root_clk_gating(struct device_node *np, struct samsung_clk_provider *ctx, - const struct samsung_cmu_info *cmu); + const struct samsung_cmu_info *cmu, + bool cmu_has_pm); struct clk_hw *samsung_register_auto_gate(struct device *dev, struct device_node *np, const char *name, From 1d8fae6617b6ebcaf3ef3040ee84cdde25d5d10f Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 13 Jan 2026 10:59:00 +0000 Subject: [PATCH 116/165] dt-bindings: samsung: exynos-sysreg: add gs101 dpu compatible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add dedicated compatibles for gs101 dpu sysreg controllers to the documentation. Reviewed-by: André Draszik Signed-off-by: Peter Griffin Acked-by: Rob Herring (Arm) Link: https://patch.msgid.link/20260113-dpu-clocks-v3-3-cb85424f2c72@linaro.org Signed-off-by: Krzysztof Kozlowski --- .../devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml index 5e1e155510b3..9c63dbcd4d77 100644 --- a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml @@ -15,6 +15,7 @@ properties: - items: - enum: - google,gs101-apm-sysreg + - google,gs101-dpu-sysreg - google,gs101-hsi0-sysreg - google,gs101-hsi2-sysreg - google,gs101-misc-sysreg @@ -92,6 +93,7 @@ allOf: compatible: contains: enum: + - google,gs101-dpu-sysreg - google,gs101-hsi0-sysreg - google,gs101-hsi2-sysreg - google,gs101-misc-sysreg From 4b18a3ef2230e38439c9c3a0e3fa4a2b5edcc5cd Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 13 Jan 2026 10:59:01 +0000 Subject: [PATCH 117/165] clk: samsung: gs101: add support for Display Process Unit (DPU) clocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cmu_dpu is the clock management unit used for the Display Process Unit block. It generates clocks for image scaler, compressor etc. Add support for the muxes, dividers and gates in cmu_dpu. Signed-off-by: Peter Griffin Reviewed-by: André Draszik Link: https://patch.msgid.link/20260113-dpu-clocks-v3-4-cb85424f2c72@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-gs101.c | 283 ++++++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+) diff --git a/drivers/clk/samsung/clk-gs101.c b/drivers/clk/samsung/clk-gs101.c index 8551289b46eb..44a8ecd332fd 100644 --- a/drivers/clk/samsung/clk-gs101.c +++ b/drivers/clk/samsung/clk-gs101.c @@ -20,6 +20,7 @@ /* NOTE: Must be equal to the last clock ID increased by one */ #define CLKS_NR_TOP (CLK_GOUT_CMU_TPU_UART + 1) #define CLKS_NR_APM (CLK_APM_PLL_DIV16_APM + 1) +#define CLKS_NR_DPU (CLK_GOUT_DPU_SYSREG_DPU_PCLK + 1) #define CLKS_NR_HSI0 (CLK_GOUT_HSI0_XIU_P_HSI0_ACLK + 1) #define CLKS_NR_HSI2 (CLK_GOUT_HSI2_XIU_P_HSI2_ACLK + 1) #define CLKS_NR_MISC (CLK_GOUT_MISC_XIU_D_MISC_ACLK + 1) @@ -1932,6 +1933,285 @@ static const struct samsung_cmu_info apm_cmu_info __initconst = { .memclk_offset = GS101_MEMCLK_OFFSET, }; +/* ---- CMU_DPU ------------------------------------------------------------- */ + +/* Register Offset definitions for CMU_DPU (0x1c000000) */ +#define PLL_CON0_MUX_CLKCMU_DPU_BUS_USER 0x0600 +#define PLL_CON1_MUX_CLKCMU_DPU_BUS_USER 0x0604 +#define DPU_CMU_DPU_CONTROLLER_OPTION 0x0800 +#define CLKOUT_CON_BLK_DPU_CMU_DPU_CLKOUT0 0x0810 +#define CLK_CON_DIV_DIV_CLK_DPU_BUSP 0x1800 +#define CLK_CON_GAT_CLK_BLK_DPU_UID_DPU_CMU_DPU_IPCLKPORT_PCLK 0x2000 +#define CLK_CON_GAT_CLK_BLK_DPU_UID_RSTNSYNC_CLK_DPU_OSCCLK_IPCLKPORT_CLK 0x2004 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_AD_APB_DPU_DMA_IPCLKPORT_PCLKM 0x2008 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DMA 0x200c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DPP 0x2010 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_D_TZPC_DPU_IPCLKPORT_PCLK 0x2014 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_GPC_DPU_IPCLKPORT_PCLK 0x2018 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHM_AXI_P_DPU_IPCLKPORT_I_CLK 0x201c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D0_DPU_IPCLKPORT_I_CLK 0x2020 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D1_DPU_IPCLKPORT_I_CLK 0x2024 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D2_DPU_IPCLKPORT_I_CLK 0x2028 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_ACLK 0x202c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_PCLK 0x2030 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_ACLK 0x2034 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_PCLK 0x2038 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_ACLK 0x203c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_PCLK 0x2040 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSD_IPCLKPORT_CLK 0x2044 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSP_IPCLKPORT_CLK 0x2048 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_ACLK 0x204c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_PCLK 0x2050 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_ACLK 0x2054 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_PCLK 0x2058 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_ACLK 0x205c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_PCLK 0x2060 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S1 0x2064 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S2 0x2068 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S1 0x206c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S2 0x2070 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S1 0x2074 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S2 0x2078 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSREG_DPU_IPCLKPORT_PCLK 0x207c +#define PCH_CON_LHM_AXI_P_DPU_PCH 0x3000 +#define PCH_CON_LHS_AXI_D0_DPU_PCH 0x3004 +#define PCH_CON_LHS_AXI_D1_DPU_PCH 0x3008 +#define PCH_CON_LHS_AXI_D2_DPU_PCH 0x300c +#define QCH_CON_DPUF_QCH_DPU_DMA 0x3010 +#define QCH_CON_DPUF_QCH_DPU_DPP 0x3014 +#define QCH_CON_DPU_CMU_DPU_QCH 0x301c +#define QCH_CON_D_TZPC_DPU_QCH 0x3020 +#define QCH_CON_GPC_DPU_QCH 0x3024 +#define QCH_CON_LHM_AXI_P_DPU_QCH 0x3028 +#define QCH_CON_LHS_AXI_D0_DPU_QCH 0x302c +#define QCH_CON_LHS_AXI_D1_DPU_QCH 0x3030 +#define QCH_CON_LHS_AXI_D2_DPU_QCH 0x3034 +#define QCH_CON_PPMU_DPUD0_QCH 0x3038 +#define QCH_CON_PPMU_DPUD1_QCH 0x303c +#define QCH_CON_PPMU_DPUD2_QCH 0x3040 +#define QCH_CON_SSMT_DPU0_QCH 0x3044 +#define QCH_CON_SSMT_DPU1_QCH 0x3048 +#define QCH_CON_SSMT_DPU2_QCH 0x304c +#define QCH_CON_SYSMMU_DPUD0_QCH_S1 0x3050 +#define QCH_CON_SYSMMU_DPUD0_QCH_S2 0x3054 +#define QCH_CON_SYSMMU_DPUD1_QCH_S1 0x3058 +#define QCH_CON_SYSMMU_DPUD1_QCH_S2 0x305c +#define QCH_CON_SYSMMU_DPUD2_QCH_S1 0x3060 +#define QCH_CON_SYSMMU_DPUD2_QCH_S2 0x3064 +#define QCH_CON_SYSREG_DPU_QCH 0x3068 +#define QUEUE_CTRL_REG_BLK_DPU_CMU_DPU 0x3c00 + +static const unsigned long dpu_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_DPU_BUS_USER, + PLL_CON1_MUX_CLKCMU_DPU_BUS_USER, + DPU_CMU_DPU_CONTROLLER_OPTION, + CLKOUT_CON_BLK_DPU_CMU_DPU_CLKOUT0, + CLK_CON_DIV_DIV_CLK_DPU_BUSP, + CLK_CON_GAT_CLK_BLK_DPU_UID_DPU_CMU_DPU_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_DPU_UID_RSTNSYNC_CLK_DPU_OSCCLK_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_AD_APB_DPU_DMA_IPCLKPORT_PCLKM, + CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DMA, + CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DPP, + CLK_CON_GAT_GOUT_BLK_DPU_UID_D_TZPC_DPU_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_GPC_DPU_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHM_AXI_P_DPU_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D0_DPU_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D1_DPU_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D2_DPU_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSD_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSP_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S1, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S2, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S1, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S2, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S1, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S2, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSREG_DPU_IPCLKPORT_PCLK, + PCH_CON_LHM_AXI_P_DPU_PCH, + PCH_CON_LHS_AXI_D0_DPU_PCH, + PCH_CON_LHS_AXI_D1_DPU_PCH, + PCH_CON_LHS_AXI_D2_DPU_PCH, + QCH_CON_DPUF_QCH_DPU_DMA, + QCH_CON_DPUF_QCH_DPU_DPP, + QCH_CON_DPU_CMU_DPU_QCH, + QCH_CON_D_TZPC_DPU_QCH, + QCH_CON_GPC_DPU_QCH, + QCH_CON_LHM_AXI_P_DPU_QCH, + QCH_CON_LHS_AXI_D0_DPU_QCH, + QCH_CON_LHS_AXI_D1_DPU_QCH, + QCH_CON_LHS_AXI_D2_DPU_QCH, + QCH_CON_PPMU_DPUD0_QCH, + QCH_CON_PPMU_DPUD1_QCH, + QCH_CON_PPMU_DPUD2_QCH, + QCH_CON_SSMT_DPU0_QCH, + QCH_CON_SSMT_DPU1_QCH, + QCH_CON_SSMT_DPU2_QCH, + QCH_CON_SYSMMU_DPUD0_QCH_S1, + QCH_CON_SYSMMU_DPUD0_QCH_S2, + QCH_CON_SYSMMU_DPUD1_QCH_S1, + QCH_CON_SYSMMU_DPUD1_QCH_S2, + QCH_CON_SYSMMU_DPUD2_QCH_S1, + QCH_CON_SYSMMU_DPUD2_QCH_S2, + QCH_CON_SYSREG_DPU_QCH, + QUEUE_CTRL_REG_BLK_DPU_CMU_DPU, +}; + +/* List of parent clocks for Muxes in CMU_DPU */ +PNAME(mout_dpu_bus_user_p) = { "oscclk", "dout_cmu_dpu_bus" }; + +static const struct samsung_mux_clock dpu_mux_clks[] __initconst = { + MUX(CLK_MOUT_DPU_BUS_USER, "mout_dpu_bus_user", + mout_dpu_bus_user_p, PLL_CON0_MUX_CLKCMU_DPU_BUS_USER, 4, 1), +}; + +static const struct samsung_div_clock dpu_div_clks[] __initconst = { + DIV(CLK_DOUT_DPU_BUSP, "dout_dpu_busp", "mout_dpu_bus_user", + CLK_CON_DIV_DIV_CLK_DPU_BUSP, 0, 3), +}; + +static const struct samsung_gate_clock dpu_gate_clks[] __initconst = { + GATE(CLK_GOUT_DPU_PCLK, "gout_dpu_dpu_pclk", + "dout_dpu_busp", + CLK_CON_GAT_CLK_BLK_DPU_UID_DPU_CMU_DPU_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_CLK_DPU_OSCCLK_CLK, "gout_dpu_clk_dpu_oscclk_clk", + "oscclk", + CLK_CON_GAT_CLK_BLK_DPU_UID_RSTNSYNC_CLK_DPU_OSCCLK_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_AD_APB_DPU_DMA_PCLKM, "gout_dpu_ad_apb_dpu_dma_pclkm", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_AD_APB_DPU_DMA_IPCLKPORT_PCLKM, + 21, 0, 0), + GATE(CLK_GOUT_DPU_DPUF_ACLK_DMA, "gout_dpu_dpuf_aclk_dma", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DMA, 21, 0, 0), + GATE(CLK_GOUT_DPU_DPUF_ACLK_DPP, "gout_dpu_dpuf_aclk_dpp", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DPP, 21, 0, 0), + GATE(CLK_GOUT_DPU_D_TZPC_DPU_PCLK, "gout_dpu_d_tzpc_dpu_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_D_TZPC_DPU_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_GPC_DPU_PCLK, "gout_dpu_gpc_dpu_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_GPC_DPU_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_LHM_AXI_P_DPU_I_CLK, "gout_dpu_lhm_axi_p_dpu_i_clk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHM_AXI_P_DPU_IPCLKPORT_I_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_LHS_AXI_D0_DPU_I_CLK, "gout_dpu_lhs_axi_d0_dpu_i_clk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D0_DPU_IPCLKPORT_I_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_LHS_AXI_D1_DPU_I_CLK, "gout_dpu_lhs_axi_d1_dpu_i_clk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D1_DPU_IPCLKPORT_I_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_LHS_AXI_D2_DPU_I_CLK, "gout_dpu_lhs_axi_d2_dpu_i_clk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D2_DPU_IPCLKPORT_I_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD0_ACLK, "gout_dpu_ppmu_dpud0_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD0_PCLK, "gout_dpu_ppmu_dpud0_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD1_ACLK, "gout_dpu_ppmu_dpud1_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD1_PCLK, "gout_dpu_ppmu_dpud1_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD2_ACLK, "gout_dpu_ppmu_dpud2_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD2_PCLK, "gout_dpu_ppmu_dpud2_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_CLK_DPU_BUSD_CLK, "gout_dpu_clk_dpu_busd_clk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSD_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_CLK_DPU_BUSP_CLK, "gout_dpu_clk_dpu_busp_clk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSP_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU0_ACLK, "gout_dpu_ssmt_dpu0_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU0_PCLK, "gout_dpu_ssmt_dpu0_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU1_ACLK, "gout_dpu_ssmt_dpu1_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU1_PCLK, "gout_dpu_ssmt_dpu1_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU2_ACLK, "gout_dpu_ssmt_dpu2_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU2_PCLK, "gout_dpu_ssmt_dpu2_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD0_CLK_S1, "gout_dpu_sysmmu_dpud0_clk_s1", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S1, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD0_CLK_S2, "gout_dpu_sysmmu_dpud0_clk_s2", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S2, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD1_CLK_S1, "gout_dpu_sysmmu_dpud1_clk_s1", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S1, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD1_CLK_S2, "gout_dpu_sysmmu_dpud1_clk_s2", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S2, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD2_CLK_S1, "gout_dpu_sysmmu_dpud2_clk_s1", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S1, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD2_CLK_S2, "gout_dpu_sysmmu_dpud2_clk_s2", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S2, 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSREG_DPU_PCLK, "gout_dpu_sysreg_dpu_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSREG_DPU_IPCLKPORT_PCLK, 21, 0, 0), +}; + +static const struct samsung_cmu_info dpu_cmu_info __initconst = { + .mux_clks = dpu_mux_clks, + .nr_mux_clks = ARRAY_SIZE(dpu_mux_clks), + .div_clks = dpu_div_clks, + .nr_div_clks = ARRAY_SIZE(dpu_div_clks), + .gate_clks = dpu_gate_clks, + .nr_gate_clks = ARRAY_SIZE(dpu_gate_clks), + .nr_clk_ids = CLKS_NR_DPU, + .clk_regs = dpu_clk_regs, + .nr_clk_regs = ARRAY_SIZE(dpu_clk_regs), + .sysreg_clk_regs = dcrg_memclk_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg), + .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = DPU_CMU_DPU_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, +}; + /* ---- CMU_HSI0 ------------------------------------------------------------ */ /* Register Offset definitions for CMU_HSI0 (0x11000000) */ @@ -4443,6 +4723,9 @@ static const struct of_device_id gs101_cmu_of_match[] = { { .compatible = "google,gs101-cmu-apm", .data = &apm_cmu_info, + }, { + .compatible = "google,gs101-cmu-dpu", + .data = &dpu_cmu_info, }, { .compatible = "google,gs101-cmu-hsi0", .data = &hsi0_cmu_info, From 9bb910b049402b7a3496250c9c6ab169aed83d15 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Tue, 13 Jan 2026 15:52:41 +0100 Subject: [PATCH 118/165] clk: imx: fracn-gppll: Add 332.60 MHz Support Some parallel panels have a pixelclk of 33.260 MHz. Add support for 332.60 MHz so a by 10 divider can be used to derive the exact pixelclk. Reviewed-by: Primoz Fiser Signed-off-by: Marco Felsch Reviewed-by: Abel Vesa Reviewed-by: Peng Fan Acked-by: Daniel Baluta Link: https://patch.msgid.link/20260113-v6-18-topic-clk-fracn-gppll-v3-1-45da70f43c98@pengutronix.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-fracn-gppll.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index 090d60867250..579f76494eb0 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -88,6 +88,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(332600000U, 138, 584, 1000, 0, 10), PLL_FRACN_GP(300000000U, 150, 0, 1, 0, 12) }; From 3e6b0227b93c708e93e33f6c3485bad077650766 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Tue, 13 Jan 2026 15:52:42 +0100 Subject: [PATCH 119/165] clk: imx: fracn-gppll: Add 241.90 MHz Support Some parallel panels have a pixelclk of 24.19 MHz. Add support for 241.90 MHz so a by 10 divider can be used to derive the exact pixelclk. Signed-off-by: Marco Felsch Reviewed-by: Abel Vesa Reviewed-by: Peng Fan Acked-by: Daniel Baluta Link: https://patch.msgid.link/20260113-v6-18-topic-clk-fracn-gppll-v3-2-45da70f43c98@pengutronix.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-fracn-gppll.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index 579f76494eb0..6de5349adf70 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -89,7 +89,8 @@ static const struct imx_fracn_gppll_rate_table fracn_tbl[] = { PLL_FRACN_GP(400000000U, 200, 0, 1, 0, 12), PLL_FRACN_GP(393216000U, 163, 84, 100, 0, 10), PLL_FRACN_GP(332600000U, 138, 584, 1000, 0, 10), - PLL_FRACN_GP(300000000U, 150, 0, 1, 0, 12) + PLL_FRACN_GP(300000000U, 150, 0, 1, 0, 12), + PLL_FRACN_GP(241900000U, 201, 584, 1000, 0, 20), }; struct imx_fracn_gppll_clk imx_fracn_gppll = { From a1d63493634e98360140027fef49d82b1ff0a267 Mon Sep 17 00:00:00 2001 From: Petr Hodina Date: Wed, 7 Jan 2026 12:44:43 +0100 Subject: [PATCH 120/165] clk: qcom: dispcc-sdm845: Enable parents for pixel clocks Add CLK_OPS_PARENT_ENABLE to MDSS pixel clock sources to ensure parent clocks are enabled during clock operations, preventing potential stability issues during display configuration. Fixes: 81351776c9fb ("clk: qcom: Add display clock controller driver for SDM845") Signed-off-by: Petr Hodina Reviewed-by: Dmitry Baryshkov Reviewed-by: David Heidelberg Link: https://lore.kernel.org/r/20260107-stability-discussion-v2-1-ef7717b435ff@protonmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/dispcc-sdm845.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c index 2f9e9665d7e9..78e43f6d7502 100644 --- a/drivers/clk/qcom/dispcc-sdm845.c +++ b/drivers/clk/qcom/dispcc-sdm845.c @@ -280,7 +280,7 @@ static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { .name = "disp_cc_mdss_pclk0_clk_src", .parent_data = disp_cc_parent_data_4, .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, .ops = &clk_pixel_ops, }, }; @@ -295,7 +295,7 @@ static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { .name = "disp_cc_mdss_pclk1_clk_src", .parent_data = disp_cc_parent_data_4, .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, .ops = &clk_pixel_ops, }, }; From fab13d738c9bd645965464b881335f580d38a54e Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Sat, 17 Jan 2026 19:18:28 +0100 Subject: [PATCH 121/165] clk: qcom: dispcc-sm7150: Fix dispcc_mdss_pclk1_clk_src Set CLK_OPS_PARENT_ENABLE to ensure the parent gets prepared and enabled when switching to it. Fixes: e3c13e0caa8c ("clk: qcom: dispcc-sm7150: Fix dispcc_mdss_pclk0_clk_src") Signed-off-by: David Heidelberg Link: https://lore.kernel.org/r/20260117-sm7150-dispcc-fix-v1-1-2f39966bcad2@ixit.cz Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/dispcc-sm7150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/dispcc-sm7150.c b/drivers/clk/qcom/dispcc-sm7150.c index 811d380a8e9f..ed8e34ffd69b 100644 --- a/drivers/clk/qcom/dispcc-sm7150.c +++ b/drivers/clk/qcom/dispcc-sm7150.c @@ -371,7 +371,7 @@ static struct clk_rcg2 dispcc_mdss_pclk1_clk_src = { .name = "dispcc_mdss_pclk1_clk_src", .parent_data = dispcc_parent_data_4, .num_parents = ARRAY_SIZE(dispcc_parent_data_4), - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, .ops = &clk_pixel_ops, }, }; From 2583cb925ca1ce450aa5d74a05a67448db970193 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 17 Jan 2026 05:54:47 +0200 Subject: [PATCH 122/165] clk: qcom: gfx3d: add parent to parent request map After commit d228ece36345 ("clk: divider: remove round_rate() in favor of determine_rate()") determining GFX3D clock rate crashes, because the passed parent map doesn't provide the expected best_parent_hw clock (with the roundd_rate path before the offending commit the best_parent_hw was ignored). Set the field in parent_req in addition to setting it in the req, fixing the crash. clk_hw_round_rate (drivers/clk/clk.c:1764) (P) clk_divider_bestdiv (drivers/clk/clk-divider.c:336) divider_determine_rate (drivers/clk/clk-divider.c:358) clk_alpha_pll_postdiv_determine_rate (drivers/clk/qcom/clk-alpha-pll.c:1275) clk_core_determine_round_nolock (drivers/clk/clk.c:1606) clk_core_round_rate_nolock (drivers/clk/clk.c:1701) __clk_determine_rate (drivers/clk/clk.c:1741) clk_gfx3d_determine_rate (drivers/clk/qcom/clk-rcg2.c:1268) clk_core_determine_round_nolock (drivers/clk/clk.c:1606) clk_core_round_rate_nolock (drivers/clk/clk.c:1701) clk_core_round_rate_nolock (drivers/clk/clk.c:1710) clk_round_rate (drivers/clk/clk.c:1804) dev_pm_opp_set_rate (drivers/opp/core.c:1440 (discriminator 1)) msm_devfreq_target (drivers/gpu/drm/msm/msm_gpu_devfreq.c:51) devfreq_set_target (drivers/devfreq/devfreq.c:360) devfreq_update_target (drivers/devfreq/devfreq.c:426) devfreq_monitor (drivers/devfreq/devfreq.c:458) process_one_work (arch/arm64/include/asm/jump_label.h:36 include/trace/events/workqueue.h:110 kernel/workqueue.c:3284) worker_thread (kernel/workqueue.c:3356 (discriminator 2) kernel/workqueue.c:3443 (discriminator 2)) kthread (kernel/kthread.c:467) ret_from_fork (arch/arm64/kernel/entry.S:861) Fixes: 55213e1acec9 ("clk: qcom: Add gfx3d ping-pong PLL frequency switching") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abel Vesa Reviewed-by: Konrad Dybcio Reviewed-by: Brian Masney Link: https://lore.kernel.org/r/20260117-db820-fix-gfx3d-v1-1-0f8894d71d63@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rcg2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 2838d4cb2d58..d0a5847f9111 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -1264,6 +1264,7 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw, if (req->max_rate < parent_req.max_rate) parent_req.max_rate = req->max_rate; + parent_req.best_parent_hw = req->best_parent_hw; ret = __clk_determine_rate(req->best_parent_hw, &parent_req); if (ret) return ret; From a641384bb03bc2c85bd51dc60d40e9f15aeaa446 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:19 -0500 Subject: [PATCH 123/165] clk: sophgo: cv18xx-ip: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Also go ahead and convert all of the driver from round rate type to determine rate that accepts a 'struct clk_rate_request' to simplify the overall driver code. Signed-off-by: Brian Masney --- drivers/clk/sophgo/clk-cv18xx-ip.c | 154 ++++++++++++++++------------- 1 file changed, 85 insertions(+), 69 deletions(-) diff --git a/drivers/clk/sophgo/clk-cv18xx-ip.c b/drivers/clk/sophgo/clk-cv18xx-ip.c index c2b58faf0938..e936e3154003 100644 --- a/drivers/clk/sophgo/clk-cv18xx-ip.c +++ b/drivers/clk/sophgo/clk-cv18xx-ip.c @@ -152,28 +152,27 @@ static u32 div_helper_get_clockdiv(struct cv1800_clk_common *common, return clockdiv; } -static u32 div_helper_round_rate(struct cv1800_clk_regfield *div, - struct clk_hw *hw, struct clk_hw *parent, - unsigned long rate, unsigned long *prate) +static int div_helper_determine_rate(struct cv1800_clk_regfield *div, + struct clk_hw *hw, + struct clk_rate_request *req) { if (div->width == 0) { if (div->initval <= 0) - return DIV_ROUND_UP_ULL(*prate, 1); + req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, 1); else - return DIV_ROUND_UP_ULL(*prate, div->initval); + req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, div->initval); + + return 0; } - return divider_round_rate_parent(hw, parent, rate, prate, NULL, - div->width, div->flags); + return divider_determine_rate(hw, req, NULL, div->width, div->flags); } -static long div_round_rate(struct clk_hw *parent, unsigned long *parent_rate, - unsigned long rate, int id, void *data) +static int do_div_determine_rate(struct clk_rate_request *req, int id, void *data) { struct cv1800_clk_div *div = data; - return div_helper_round_rate(&div->div, &div->common.hw, parent, - rate, parent_rate); + return div_helper_determine_rate(&div->div, &div->common.hw, req); } static bool div_is_better_rate(struct cv1800_clk_common *common, @@ -188,53 +187,60 @@ static bool div_is_better_rate(struct cv1800_clk_common *common, static int mux_helper_determine_rate(struct cv1800_clk_common *common, struct clk_rate_request *req, - long (*round)(struct clk_hw *, - unsigned long *, - unsigned long, - int, - void *), + int (*round)(struct clk_rate_request *, + int, + void *), void *data) { unsigned long best_parent_rate = 0, best_rate = 0; struct clk_hw *best_parent, *hw = &common->hw; unsigned int i; + int ret; if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) { - unsigned long adj_parent_rate; + struct clk_rate_request tmp_req = *req; best_parent = clk_hw_get_parent(hw); - best_parent_rate = clk_hw_get_rate(best_parent); + tmp_req.best_parent_hw = best_parent; + tmp_req.best_parent_rate = clk_hw_get_rate(best_parent); - best_rate = round(best_parent, &adj_parent_rate, - req->rate, -1, data); + ret = round(&tmp_req, -1, data); + if (ret) + return ret; + + best_parent_rate = tmp_req.best_parent_rate; + best_rate = tmp_req.rate; goto find; } for (i = 0; i < clk_hw_get_num_parents(hw); i++) { - unsigned long tmp_rate, parent_rate; + struct clk_rate_request tmp_req = *req; struct clk_hw *parent; parent = clk_hw_get_parent_by_index(hw, i); if (!parent) continue; - parent_rate = clk_hw_get_rate(parent); + tmp_req.best_parent_hw = parent; + tmp_req.best_parent_rate = clk_hw_get_rate(parent); - tmp_rate = round(parent, &parent_rate, req->rate, i, data); + ret = round(&tmp_req, i, data); + if (ret) + continue; - if (tmp_rate == req->rate) { + if (tmp_req.rate == req->rate) { best_parent = parent; - best_parent_rate = parent_rate; - best_rate = tmp_rate; + best_parent_rate = tmp_req.best_parent_rate; + best_rate = tmp_req.rate; goto find; } if (div_is_better_rate(common, req->rate, - tmp_rate, best_rate)) { + tmp_req.rate, best_rate)) { best_parent = parent; - best_parent_rate = parent_rate; - best_rate = tmp_rate; + best_parent_rate = tmp_req.best_parent_rate; + best_rate = tmp_req.rate; } } @@ -254,7 +260,7 @@ static int div_determine_rate(struct clk_hw *hw, struct cv1800_clk_div *div = hw_to_cv1800_clk_div(hw); return mux_helper_determine_rate(&div->common, req, - div_round_rate, div); + do_div_determine_rate, div); } static unsigned long div_recalc_rate(struct clk_hw *hw, @@ -301,24 +307,28 @@ hw_to_cv1800_clk_bypass_div(struct clk_hw *hw) return container_of(div, struct cv1800_clk_bypass_div, div); } -static long bypass_div_round_rate(struct clk_hw *parent, - unsigned long *parent_rate, - unsigned long rate, int id, void *data) +static int do_bypass_div_determine_rate(struct clk_rate_request *req, int id, + void *data) { struct cv1800_clk_bypass_div *div = data; if (id == -1) { - if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) - return *parent_rate; - else - return div_round_rate(parent, parent_rate, rate, - -1, &div->div); + if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) { + req->rate = req->best_parent_rate; + + return 0; + } + + return do_div_determine_rate(req, -1, &div->div); } - if (id == 0) - return *parent_rate; + if (id == 0) { + req->rate = req->best_parent_rate; - return div_round_rate(parent, parent_rate, rate, id - 1, &div->div); + return 0; + } + + return do_div_determine_rate(req, id - 1, &div->div); } static int bypass_div_determine_rate(struct clk_hw *hw, @@ -327,7 +337,7 @@ static int bypass_div_determine_rate(struct clk_hw *hw, struct cv1800_clk_bypass_div *div = hw_to_cv1800_clk_bypass_div(hw); return mux_helper_determine_rate(&div->div.common, req, - bypass_div_round_rate, div); + do_bypass_div_determine_rate, div); } static unsigned long bypass_div_recalc_rate(struct clk_hw *hw, @@ -414,13 +424,11 @@ static int mux_is_enabled(struct clk_hw *hw) return cv1800_clk_checkbit(&mux->common, &mux->gate); } -static long mux_round_rate(struct clk_hw *parent, unsigned long *parent_rate, - unsigned long rate, int id, void *data) +static int do_mux_determine_rate(struct clk_rate_request *req, int id, void *data) { struct cv1800_clk_mux *mux = data; - return div_helper_round_rate(&mux->div, &mux->common.hw, parent, - rate, parent_rate); + return div_helper_determine_rate(&mux->div, &mux->common.hw, req); } static int mux_determine_rate(struct clk_hw *hw, @@ -429,7 +437,7 @@ static int mux_determine_rate(struct clk_hw *hw, struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); return mux_helper_determine_rate(&mux->common, req, - mux_round_rate, mux); + do_mux_determine_rate, mux); } static unsigned long mux_recalc_rate(struct clk_hw *hw, @@ -512,24 +520,28 @@ hw_to_cv1800_clk_bypass_mux(struct clk_hw *hw) return container_of(mux, struct cv1800_clk_bypass_mux, mux); } -static long bypass_mux_round_rate(struct clk_hw *parent, - unsigned long *parent_rate, - unsigned long rate, int id, void *data) +static int do_bypass_mux_determine_rate(struct clk_rate_request *req, int id, + void *data) { struct cv1800_clk_bypass_mux *mux = data; if (id == -1) { - if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) - return *parent_rate; - else - return mux_round_rate(parent, parent_rate, rate, - -1, &mux->mux); + if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) { + req->rate = req->best_parent_rate; + + return 0; + } + + return do_mux_determine_rate(req, -1, &mux->mux); } - if (id == 0) - return *parent_rate; + if (id == 0) { + req->rate = req->best_parent_rate; - return mux_round_rate(parent, parent_rate, rate, id - 1, &mux->mux); + return 0; + } + + return do_mux_determine_rate(req, id - 1, &mux->mux); } static int bypass_mux_determine_rate(struct clk_hw *hw, @@ -538,7 +550,7 @@ static int bypass_mux_determine_rate(struct clk_hw *hw, struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); return mux_helper_determine_rate(&mux->mux.common, req, - bypass_mux_round_rate, mux); + do_bypass_mux_determine_rate, mux); } static unsigned long bypass_mux_recalc_rate(struct clk_hw *hw, @@ -639,27 +651,31 @@ static int mmux_is_enabled(struct clk_hw *hw) return cv1800_clk_checkbit(&mmux->common, &mmux->gate); } -static long mmux_round_rate(struct clk_hw *parent, unsigned long *parent_rate, - unsigned long rate, int id, void *data) +static int do_mmux_determine_rate(struct clk_rate_request *req, int id, void *data) { struct cv1800_clk_mmux *mmux = data; s8 div_id; if (id == -1) { - if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) - return *parent_rate; + if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) { + req->rate = req->best_parent_rate; + + return 0; + } id = mmux_get_parent_id(mmux); } div_id = mmux->parent2sel[id]; - if (div_id < 0) - return *parent_rate; + if (div_id < 0) { + req->rate = req->best_parent_rate; - return div_helper_round_rate(&mmux->div[div_id], - &mmux->common.hw, parent, - rate, parent_rate); + return 0; + } + + return div_helper_determine_rate(&mmux->div[div_id], &mmux->common.hw, + req); } static int mmux_determine_rate(struct clk_hw *hw, @@ -668,7 +684,7 @@ static int mmux_determine_rate(struct clk_hw *hw, struct cv1800_clk_mmux *mmux = hw_to_cv1800_clk_mmux(hw); return mux_helper_determine_rate(&mmux->common, req, - mmux_round_rate, mmux); + do_mmux_determine_rate, mmux); } static unsigned long mmux_recalc_rate(struct clk_hw *hw, From 1c8d7af61b37db526393a46224417f36420e97f8 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:20 -0500 Subject: [PATCH 124/165] clk: sunxi-ng: convert from divider_round_rate_parent() to divider_determine_rate() The divider_round_rate_parent() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Also go ahead and convert all of the driver from round rate type to determine rate that accepts a 'struct clk_rate_request' to simplify the overall driver code. Acked-by: Chen-Yu Tsai Signed-off-by: Brian Masney --- drivers/clk/sunxi-ng/ccu_div.c | 25 ++++++++--------- drivers/clk/sunxi-ng/ccu_mp.c | 26 ++++++++--------- drivers/clk/sunxi-ng/ccu_mult.c | 16 +++++------ drivers/clk/sunxi-ng/ccu_mux.c | 49 ++++++++++++++++++++------------- drivers/clk/sunxi-ng/ccu_mux.h | 8 ++---- drivers/clk/sunxi-ng/ccu_nkm.c | 25 +++++++++-------- 6 files changed, 79 insertions(+), 70 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c index 916d6da6d8a3..62d680ccb524 100644 --- a/drivers/clk/sunxi-ng/ccu_div.c +++ b/drivers/clk/sunxi-ng/ccu_div.c @@ -10,26 +10,25 @@ #include "ccu_gate.h" #include "ccu_div.h" -static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux, - struct clk_hw *parent, - unsigned long *parent_rate, - unsigned long rate, - void *data) +static int ccu_div_determine_rate_helper(struct ccu_mux_internal *mux, + struct clk_rate_request *req, + void *data) { struct ccu_div *cd = data; + int ret; if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate *= cd->fixed_post_div; + req->rate *= cd->fixed_post_div; - rate = divider_round_rate_parent(&cd->common.hw, parent, - rate, parent_rate, - cd->div.table, cd->div.width, - cd->div.flags); + ret = divider_determine_rate(&cd->common.hw, req, cd->div.table, + cd->div.width, cd->div.flags); + if (ret) + return ret; if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= cd->fixed_post_div; + req->rate /= cd->fixed_post_div; - return rate; + return 0; } static void ccu_div_disable(struct clk_hw *hw) @@ -82,7 +81,7 @@ static int ccu_div_determine_rate(struct clk_hw *hw, struct ccu_div *cd = hw_to_ccu_div(hw); return ccu_mux_helper_determine_rate(&cd->common, &cd->mux, - req, ccu_div_round_rate, cd); + req, ccu_div_determine_rate_helper, cd); } static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index 4221b1888b38..7cdb0eedc69b 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c @@ -103,11 +103,9 @@ static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw, return best_rate; } -static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, - struct clk_hw *hw, - unsigned long *parent_rate, - unsigned long rate, - void *data) +static int ccu_mp_determine_rate_helper(struct ccu_mux_internal *mux, + struct clk_rate_request *req, + void *data) { struct ccu_mp *cmp = data; unsigned int max_m, max_p; @@ -115,7 +113,7 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, bool shift = true; if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate *= cmp->fixed_post_div; + req->rate *= cmp->fixed_post_div; if (cmp->common.features & CCU_FEATURE_DUAL_DIV) shift = false; @@ -127,17 +125,19 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, max_p = cmp->p.max ?: 1 << cmp->p.width; if (!clk_hw_can_set_rate_parent(&cmp->common.hw)) { - rate = ccu_mp_find_best(*parent_rate, rate, max_m, max_p, shift, - &m, &p); + req->rate = ccu_mp_find_best(req->best_parent_rate, req->rate, + max_m, max_p, shift, &m, &p); } else { - rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate, - max_m, max_p, shift); + req->rate = ccu_mp_find_best_with_parent_adj(req->best_parent_hw, + &req->best_parent_rate, + req->rate, max_m, max_p, + shift); } if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= cmp->fixed_post_div; + req->rate /= cmp->fixed_post_div; - return rate; + return 0; } static void ccu_mp_disable(struct clk_hw *hw) @@ -201,7 +201,7 @@ static int ccu_mp_determine_rate(struct clk_hw *hw, struct ccu_mp *cmp = hw_to_ccu_mp(hw); return ccu_mux_helper_determine_rate(&cmp->common, &cmp->mux, - req, ccu_mp_round_rate, cmp); + req, ccu_mp_determine_rate_helper, cmp); } static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c index 8d5720f3dec1..3fc81e7de6e9 100644 --- a/drivers/clk/sunxi-ng/ccu_mult.c +++ b/drivers/clk/sunxi-ng/ccu_mult.c @@ -29,11 +29,9 @@ static void ccu_mult_find_best(unsigned long parent, unsigned long rate, mult->mult = _mult; } -static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux, - struct clk_hw *parent, - unsigned long *parent_rate, - unsigned long rate, - void *data) +static int ccu_mult_determine_rate_helper(struct ccu_mux_internal *mux, + struct clk_rate_request *req, + void *data) { struct ccu_mult *cm = data; struct _ccu_mult _cm; @@ -45,9 +43,11 @@ static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux, else _cm.max = (1 << cm->mult.width) + cm->mult.offset - 1; - ccu_mult_find_best(*parent_rate, rate, &_cm); + ccu_mult_find_best(req->best_parent_rate, req->rate, &_cm); - return *parent_rate * _cm.mult; + req->rate = req->best_parent_rate * _cm.mult; + + return 0; } static void ccu_mult_disable(struct clk_hw *hw) @@ -97,7 +97,7 @@ static int ccu_mult_determine_rate(struct clk_hw *hw, struct ccu_mult *cm = hw_to_ccu_mult(hw); return ccu_mux_helper_determine_rate(&cm->common, &cm->mux, - req, ccu_mult_round_rate, cm); + req, ccu_mult_determine_rate_helper, cm); } static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c index 74f9e98a5d35..766f27cff748 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.c +++ b/drivers/clk/sunxi-ng/ccu_mux.c @@ -79,41 +79,46 @@ static unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common, int ccu_mux_helper_determine_rate(struct ccu_common *common, struct ccu_mux_internal *cm, struct clk_rate_request *req, - unsigned long (*round)(struct ccu_mux_internal *, - struct clk_hw *, - unsigned long *, - unsigned long, - void *), + int (*round)(struct ccu_mux_internal *, + struct clk_rate_request *, + void *), void *data) { unsigned long best_parent_rate = 0, best_rate = 0; struct clk_hw *best_parent, *hw = &common->hw; unsigned int i; + int ret; if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) { - unsigned long adj_parent_rate; + struct clk_rate_request adj_req = *req; best_parent = clk_hw_get_parent(hw); best_parent_rate = clk_hw_get_rate(best_parent); - adj_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1, - best_parent_rate); - best_rate = round(cm, best_parent, &adj_parent_rate, - req->rate, data); + adj_req.best_parent_hw = best_parent; + adj_req.best_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1, + best_parent_rate); + + ret = round(cm, &adj_req, data); + if (ret) + return ret; + + best_rate = adj_req.rate; /* - * adj_parent_rate might have been modified by our clock. + * best_parent_rate might have been modified by our clock. * Unapply the pre-divider if there's one, and give * the actual frequency the parent needs to run at. */ best_parent_rate = ccu_mux_helper_unapply_prediv(common, cm, -1, - adj_parent_rate); + adj_req.best_parent_rate); goto out; } for (i = 0; i < clk_hw_get_num_parents(hw); i++) { - unsigned long tmp_rate, parent_rate; + struct clk_rate_request tmp_req = *req; + unsigned long parent_rate; struct clk_hw *parent; parent = clk_hw_get_parent_by_index(hw, i); @@ -123,7 +128,12 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common, parent_rate = ccu_mux_helper_apply_prediv(common, cm, i, clk_hw_get_rate(parent)); - tmp_rate = round(cm, parent, &parent_rate, req->rate, data); + tmp_req.best_parent_hw = parent; + tmp_req.best_parent_rate = parent_rate; + + ret = round(cm, &tmp_req, data); + if (ret) + continue; /* * parent_rate might have been modified by our clock. @@ -131,16 +141,17 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common, * the actual frequency the parent needs to run at. */ parent_rate = ccu_mux_helper_unapply_prediv(common, cm, i, - parent_rate); - if (tmp_rate == req->rate) { + tmp_req.best_parent_rate); + + if (tmp_req.rate == req->rate) { best_parent = parent; best_parent_rate = parent_rate; - best_rate = tmp_rate; + best_rate = tmp_req.rate; goto out; } - if (ccu_is_better_rate(common, req->rate, tmp_rate, best_rate)) { - best_rate = tmp_rate; + if (ccu_is_better_rate(common, req->rate, tmp_req.rate, best_rate)) { + best_rate = tmp_req.rate; best_parent_rate = parent_rate; best_parent = parent; } diff --git a/drivers/clk/sunxi-ng/ccu_mux.h b/drivers/clk/sunxi-ng/ccu_mux.h index eb1172ebbd94..c94a4bde5d01 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.h +++ b/drivers/clk/sunxi-ng/ccu_mux.h @@ -137,11 +137,9 @@ unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common, int ccu_mux_helper_determine_rate(struct ccu_common *common, struct ccu_mux_internal *cm, struct clk_rate_request *req, - unsigned long (*round)(struct ccu_mux_internal *, - struct clk_hw *, - unsigned long *, - unsigned long, - void *), + int (*round)(struct ccu_mux_internal *, + struct clk_rate_request *, + void *), void *data); u8 ccu_mux_helper_get_parent(struct ccu_common *common, struct ccu_mux_internal *cm); diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c index 784eec9ac997..401fbb752479 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.c +++ b/drivers/clk/sunxi-ng/ccu_nkm.c @@ -162,11 +162,9 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw, return rate; } -static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, - struct clk_hw *parent_hw, - unsigned long *parent_rate, - unsigned long rate, - void *data) +static int ccu_nkm_determine_rate_helper(struct ccu_mux_internal *mux, + struct clk_rate_request *req, + void *data) { struct ccu_nkm *nkm = data; struct _ccu_nkm _nkm; @@ -179,18 +177,21 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate *= nkm->fixed_post_div; + req->rate *= nkm->fixed_post_div; if (!clk_hw_can_set_rate_parent(&nkm->common.hw)) - rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, &nkm->common); + req->rate = ccu_nkm_find_best(req->best_parent_rate, req->rate, + &_nkm, &nkm->common); else - rate = ccu_nkm_find_best_with_parent_adj(&nkm->common, parent_hw, parent_rate, rate, - &_nkm); + req->rate = ccu_nkm_find_best_with_parent_adj(&nkm->common, + req->best_parent_hw, + &req->best_parent_rate, + req->rate, &_nkm); if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= nkm->fixed_post_div; + req->rate /= nkm->fixed_post_div; - return rate; + return 0; } static int ccu_nkm_determine_rate(struct clk_hw *hw, @@ -199,7 +200,7 @@ static int ccu_nkm_determine_rate(struct clk_hw *hw, struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); return ccu_mux_helper_determine_rate(&nkm->common, &nkm->mux, - req, ccu_nkm_round_rate, nkm); + req, ccu_nkm_determine_rate_helper, nkm); } static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate, From d0b7c5bf6c5520c35fecff34da83d390405d3eaf Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:22 -0500 Subject: [PATCH 125/165] clk: actions: owl-composite: convert from owl_divider_helper_round_rate() to divider_determine_rate() owl_divider_helper_round_rate() is just a wrapper for divider_round_rate(), which is deprecated. Let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Acked-by: Manivannan Sadhasivam Signed-off-by: Brian Masney --- drivers/clk/actions/owl-composite.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/clk/actions/owl-composite.c b/drivers/clk/actions/owl-composite.c index 00b74f8bc437..9540444307d6 100644 --- a/drivers/clk/actions/owl-composite.c +++ b/drivers/clk/actions/owl-composite.c @@ -57,15 +57,10 @@ static int owl_comp_div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct owl_composite *comp = hw_to_owl_comp(hw); - long rate; + struct owl_divider_hw *div = &comp->rate.div_hw; - rate = owl_divider_helper_round_rate(&comp->common, &comp->rate.div_hw, - req->rate, &req->best_parent_rate); - if (rate < 0) - return rate; - - req->rate = rate; - return 0; + return divider_determine_rate(&comp->common.hw, req, div->table, + div->width, div->div_flags); } static unsigned long owl_comp_div_recalc_rate(struct clk_hw *hw, From 3ff3360440fa8cc7ef5a4da628d3b770b46a4f73 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:23 -0500 Subject: [PATCH 126/165] clk: actions: owl-divider: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Additionally, owl_divider_helper_round_rate() is no longer used, so let's drop that from the header file as well. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: 1b04e12a8bcc ("clk: actions: owl-divider: convert from round_rate() to determine_rate()") Acked-by: Manivannan Sadhasivam Signed-off-by: Brian Masney --- drivers/clk/actions/owl-divider.c | 17 ++--------------- drivers/clk/actions/owl-divider.h | 5 ----- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/drivers/clk/actions/owl-divider.c b/drivers/clk/actions/owl-divider.c index 118f1393c678..316ace80e87e 100644 --- a/drivers/clk/actions/owl-divider.c +++ b/drivers/clk/actions/owl-divider.c @@ -13,26 +13,13 @@ #include "owl-divider.h" -long owl_divider_helper_round_rate(struct owl_clk_common *common, - const struct owl_divider_hw *div_hw, - unsigned long rate, - unsigned long *parent_rate) -{ - return divider_round_rate(&common->hw, rate, parent_rate, - div_hw->table, div_hw->width, - div_hw->div_flags); -} - static int owl_divider_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct owl_divider *div = hw_to_owl_divider(hw); - req->rate = owl_divider_helper_round_rate(&div->common, &div->div_hw, - req->rate, - &req->best_parent_rate); - - return 0; + return divider_determine_rate(hw, req, div->div_hw.table, + div->div_hw.width, div->div_hw.div_flags); } unsigned long owl_divider_helper_recalc_rate(struct owl_clk_common *common, diff --git a/drivers/clk/actions/owl-divider.h b/drivers/clk/actions/owl-divider.h index d76f58782c52..1d3bb4e5898a 100644 --- a/drivers/clk/actions/owl-divider.h +++ b/drivers/clk/actions/owl-divider.h @@ -56,11 +56,6 @@ static inline struct owl_divider *hw_to_owl_divider(struct clk_hw *hw) return container_of(common, struct owl_divider, common); } -long owl_divider_helper_round_rate(struct owl_clk_common *common, - const struct owl_divider_hw *div_hw, - unsigned long rate, - unsigned long *parent_rate); - unsigned long owl_divider_helper_recalc_rate(struct owl_clk_common *common, const struct owl_divider_hw *div_hw, unsigned long parent_rate); From 7468ac0ce262640e928c71a5da6f6b42a89d453e Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:24 -0500 Subject: [PATCH 127/165] clk: bm1880: convert from divider_ro_round_rate() to divider_ro_determine_rate() The divider_ro_round_rate() function is now deprecated, so let's migrate to divider_ro_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: cf1d95fa0c64 ("clk: bm1880: convert from divider_round_rate() to divider_determine_rate()") Acked-by: Manivannan Sadhasivam Signed-off-by: Brian Masney --- drivers/clk/clk-bm1880.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c index dac190bc6e19..536df8e828ea 100644 --- a/drivers/clk/clk-bm1880.c +++ b/drivers/clk/clk-bm1880.c @@ -621,12 +621,8 @@ static int bm1880_clk_div_determine_rate(struct clk_hw *hw, val = readl(reg_addr) >> div->shift; val &= clk_div_mask(div->width); - req->rate = divider_ro_round_rate(hw, req->rate, - &req->best_parent_rate, - div->table, - div->width, div->flags, val); - - return 0; + return divider_ro_determine_rate(hw, req, div->table, + div->width, div->flags, val); } req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, From 463b97bef0c9fb02b743d6b9f0d698cae81a1d9f Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:25 -0500 Subject: [PATCH 128/165] clk: bm1880: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: 64613d7fb42f ("clk: bm1880: convert from round_rate() to determine_rate()") Acked-by: Manivannan Sadhasivam Signed-off-by: Brian Masney --- drivers/clk/clk-bm1880.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c index 536df8e828ea..1bdceb36fa87 100644 --- a/drivers/clk/clk-bm1880.c +++ b/drivers/clk/clk-bm1880.c @@ -625,10 +625,7 @@ static int bm1880_clk_div_determine_rate(struct clk_hw *hw, div->width, div->flags, val); } - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - div->table, div->width, div->flags); - - return 0; + return divider_determine_rate(hw, req, div->table, div->width, div->flags); } static int bm1880_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, From e3a5249c140a1ded55937ba04247d530a85f0edc Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:26 -0500 Subject: [PATCH 129/165] clk: hisilicon: clkdivider-hi6220: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: 619a6210f398 ("clk: hisilicon: clkdivider-hi6220: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney --- drivers/clk/hisilicon/clkdivider-hi6220.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/hisilicon/clkdivider-hi6220.c b/drivers/clk/hisilicon/clkdivider-hi6220.c index 6bae18a84cb6..fd7ceb92d651 100644 --- a/drivers/clk/hisilicon/clkdivider-hi6220.c +++ b/drivers/clk/hisilicon/clkdivider-hi6220.c @@ -60,10 +60,8 @@ static int hi6220_clkdiv_determine_rate(struct clk_hw *hw, { struct hi6220_clk_divider *dclk = to_hi6220_clk_divider(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, dclk->table, - dclk->width, CLK_DIVIDER_ROUND_CLOSEST); - - return 0; + return divider_determine_rate(hw, req, dclk->table, dclk->width, + CLK_DIVIDER_ROUND_CLOSEST); } static int hi6220_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate, From 11d3c676e7e0f00e3398199f85e47a0e22369866 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:27 -0500 Subject: [PATCH 130/165] clk: loongson1: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: bb40a2ef4fc9 ("clk: loongson1: convert from round_rate() to determine_rate()") Reviewed-by: Keguang Zhang Tested-by: Keguang Zhang # on LS1B & LS1C Signed-off-by: Brian Masney --- drivers/clk/clk-loongson1.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/clk/clk-loongson1.c b/drivers/clk/clk-loongson1.c index f9f060d08a5f..1674181a1107 100644 --- a/drivers/clk/clk-loongson1.c +++ b/drivers/clk/clk-loongson1.c @@ -99,10 +99,7 @@ static int ls1x_divider_determine_rate(struct clk_hw *hw, struct ls1x_clk *ls1x_clk = to_ls1x_clk(hw); const struct ls1x_clk_div_data *d = ls1x_clk->data; - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - d->table, d->width, d->flags); - - return 0; + return divider_determine_rate(hw, req, d->table, d->width, d->flags); } static int ls1x_divider_set_rate(struct clk_hw *hw, unsigned long rate, From fc5d7e7ee681238035466ce60a6892ee8f637e9d Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:28 -0500 Subject: [PATCH 131/165] clk: milbeaut: convert from divider_ro_round_rate() to divider_ro_determine_rate() The divider_ro_round_rate() function is now deprecated, so let's migrate to divider_ro_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: fe67c682f91c ("clk: milbeaut: convert from divider_round_rate() to divider_determine_rate()") Signed-off-by: Brian Masney --- drivers/clk/clk-milbeaut.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/clk/clk-milbeaut.c b/drivers/clk/clk-milbeaut.c index b4f9b7143eaa..4e3790b7fc90 100644 --- a/drivers/clk/clk-milbeaut.c +++ b/drivers/clk/clk-milbeaut.c @@ -398,13 +398,9 @@ static int m10v_clk_divider_determine_rate(struct clk_hw *hw, val = readl(divider->reg) >> divider->shift; val &= clk_div_mask(divider->width); - req->rate = divider_ro_round_rate(hw, req->rate, - &req->best_parent_rate, - divider->table, - divider->width, - divider->flags, val); - - return 0; + return divider_ro_determine_rate(hw, req, divider->table, + divider->width, divider->flags, + val); } req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, From 865e63b038c446d38593ddbcc362ebb62e6ff007 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:29 -0500 Subject: [PATCH 132/165] clk: milbeaut: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: 7b45988fcf78 ("clk: milbeaut: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney --- drivers/clk/clk-milbeaut.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/clk/clk-milbeaut.c b/drivers/clk/clk-milbeaut.c index 4e3790b7fc90..45389db652e0 100644 --- a/drivers/clk/clk-milbeaut.c +++ b/drivers/clk/clk-milbeaut.c @@ -403,10 +403,7 @@ static int m10v_clk_divider_determine_rate(struct clk_hw *hw, val); } - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - divider->table, divider->width, divider->flags); - - return 0; + return divider_determine_rate(hw, req, divider->table, divider->width, divider->flags); } static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, From 9329d784ca9aad03b12508128797d40fd1f2e0c1 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:30 -0500 Subject: [PATCH 133/165] clk: nuvoton: ma35d1-divider: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: 215f8aa095a1 ("clk: nuvoton: ma35d1-divider: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney --- drivers/clk/nuvoton/clk-ma35d1-divider.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/clk/nuvoton/clk-ma35d1-divider.c b/drivers/clk/nuvoton/clk-ma35d1-divider.c index e39f53d5bf45..e992e7c30341 100644 --- a/drivers/clk/nuvoton/clk-ma35d1-divider.c +++ b/drivers/clk/nuvoton/clk-ma35d1-divider.c @@ -44,11 +44,8 @@ static int ma35d1_clkdiv_determine_rate(struct clk_hw *hw, { struct ma35d1_adc_clk_div *dclk = to_ma35d1_adc_clk_div(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - dclk->table, dclk->width, - CLK_DIVIDER_ROUND_CLOSEST); - - return 0; + return divider_determine_rate(hw, req, dclk->table, dclk->width, + CLK_DIVIDER_ROUND_CLOSEST); } static int ma35d1_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) From af943663ccc266e6346e5645b13c0fca71d24395 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:31 -0500 Subject: [PATCH 134/165] clk: nxp: lpc32xx: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: 0879768df240 ("clk: nxp: lpc32xx: convert from round_rate() to determine_rate()") Tested-by: Vladimir Zapolskiy Reviewed-by: Vladimir Zapolskiy Signed-off-by: Brian Masney --- drivers/clk/nxp/clk-lpc32xx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c index 23f980cf6a2b..ae2fa5341a2e 100644 --- a/drivers/clk/nxp/clk-lpc32xx.c +++ b/drivers/clk/nxp/clk-lpc32xx.c @@ -975,10 +975,8 @@ static int clk_divider_determine_rate(struct clk_hw *hw, return 0; } - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - divider->table, divider->width, divider->flags); - - return 0; + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); } static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, From 77b04dc19693510ce8ed1c6eda5f5b833e208816 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:35 -0500 Subject: [PATCH 135/165] clk: sophgo: sg2042-clkgen: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Note that this commit also removes a debugging message that's not really needed. Fixes: 9a3b6993613d ("clk: sophgo: sg2042-clkgen: convert from round_rate() to determine_rate()") Tested-by: Chen Wang Reviewed-by: Chen Wang Signed-off-by: Brian Masney --- drivers/clk/sophgo/clk-sg2042-clkgen.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/clk/sophgo/clk-sg2042-clkgen.c b/drivers/clk/sophgo/clk-sg2042-clkgen.c index 683661b71787..9725ac4e050a 100644 --- a/drivers/clk/sophgo/clk-sg2042-clkgen.c +++ b/drivers/clk/sophgo/clk-sg2042-clkgen.c @@ -180,7 +180,6 @@ static int sg2042_clk_divider_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct sg2042_divider_clock *divider = to_sg2042_clk_divider(hw); - unsigned long ret_rate; u32 bestdiv; /* if read only, just return current value */ @@ -191,17 +190,13 @@ static int sg2042_clk_divider_determine_rate(struct clk_hw *hw, bestdiv = readl(divider->reg) >> divider->shift; bestdiv &= clk_div_mask(divider->width); } - ret_rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, bestdiv); - } else { - ret_rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, NULL, - divider->width, divider->div_flags); + req->rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, bestdiv); + + return 0; } - pr_debug("--> %s: divider_round_rate: val = %ld\n", - clk_hw_get_name(hw), ret_rate); - req->rate = ret_rate; - - return 0; + return divider_determine_rate(hw, req, NULL, divider->width, + divider->div_flags); } static int sg2042_clk_divider_set_rate(struct clk_hw *hw, From f78fb9422980ceeb340fa3a2e370ae8845798ec7 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:36 -0500 Subject: [PATCH 136/165] clk: sprd: div: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: deb4740a5ff8 ("clk: sprd: div: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney --- drivers/clk/sprd/div.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/clk/sprd/div.c b/drivers/clk/sprd/div.c index 013423881968..cd57163a7204 100644 --- a/drivers/clk/sprd/div.c +++ b/drivers/clk/sprd/div.c @@ -14,11 +14,7 @@ static int sprd_div_determine_rate(struct clk_hw *hw, { struct sprd_div *cd = hw_to_sprd_div(hw); - req->rate = divider_round_rate(&cd->common.hw, req->rate, - &req->best_parent_rate, - NULL, cd->div.width, 0); - - return 0; + return divider_determine_rate(&cd->common.hw, req, NULL, cd->div.width, 0); } unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common, From 6587c9dacc89ad7014bf601fe851955429f13230 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:37 -0500 Subject: [PATCH 137/165] clk: stm32: stm32-core: convert from divider_ro_round_rate() to divider_ro_determine_rate() The divider_ro_round_rate() function is now deprecated, so let's migrate to divider_ro_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: cd1cb38836c0 ("clk: stm32: stm32-core: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney --- drivers/clk/stm32/clk-stm32-core.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/clk/stm32/clk-stm32-core.c b/drivers/clk/stm32/clk-stm32-core.c index 72825b9c36a4..b95b9c591fda 100644 --- a/drivers/clk/stm32/clk-stm32-core.c +++ b/drivers/clk/stm32/clk-stm32-core.c @@ -369,13 +369,10 @@ static int clk_stm32_divider_determine_rate(struct clk_hw *hw, val = readl(div->base + divider->offset) >> divider->shift; val &= clk_div_mask(divider->width); - req->rate = divider_ro_round_rate(hw, req->rate, - &req->best_parent_rate, - divider->table, - divider->width, - divider->flags, val); - - return 0; + return divider_ro_determine_rate(hw, req, + divider->table, + divider->width, + divider->flags, val); } req->rate = divider_round_rate_parent(hw, clk_hw_get_parent(hw), @@ -455,14 +452,9 @@ static int clk_stm32_composite_determine_rate(struct clk_hw *hw, val = readl(composite->base + divider->offset) >> divider->shift; val &= clk_div_mask(divider->width); - rate = divider_ro_round_rate(hw, req->rate, &req->best_parent_rate, - divider->table, divider->width, divider->flags, - val); - if (rate < 0) - return rate; - - req->rate = rate; - return 0; + return divider_ro_determine_rate(hw, req, divider->table, + divider->width, divider->flags, + val); } rate = divider_round_rate_parent(hw, clk_hw_get_parent(hw), From 2532795a6d6bb9791d713ffa9d9433f293b45b14 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:38 -0500 Subject: [PATCH 138/165] clk: stm32: stm32-core: convert from divider_round_rate_parent() to divider_determine_rate() The divider_round_rate_parent() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: cd1cb38836c0 ("clk: stm32: stm32-core: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney --- drivers/clk/stm32/clk-stm32-core.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/clk/stm32/clk-stm32-core.c b/drivers/clk/stm32/clk-stm32-core.c index b95b9c591fda..e921c25a929c 100644 --- a/drivers/clk/stm32/clk-stm32-core.c +++ b/drivers/clk/stm32/clk-stm32-core.c @@ -375,13 +375,8 @@ static int clk_stm32_divider_determine_rate(struct clk_hw *hw, divider->flags, val); } - req->rate = divider_round_rate_parent(hw, clk_hw_get_parent(hw), - req->rate, - &req->best_parent_rate, - divider->table, - divider->width, divider->flags); - - return 0; + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); } static unsigned long clk_stm32_divider_recalc_rate(struct clk_hw *hw, @@ -438,7 +433,6 @@ static int clk_stm32_composite_determine_rate(struct clk_hw *hw, { struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); const struct stm32_div_cfg *divider; - long rate; if (composite->div_id == NO_STM32_DIV) return 0; @@ -457,14 +451,8 @@ static int clk_stm32_composite_determine_rate(struct clk_hw *hw, val); } - rate = divider_round_rate_parent(hw, clk_hw_get_parent(hw), - req->rate, &req->best_parent_rate, - divider->table, divider->width, divider->flags); - if (rate < 0) - return rate; - - req->rate = rate; - return 0; + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); } static u8 clk_stm32_composite_get_parent(struct clk_hw *hw) From 56c1cfb488cc17944c200edad96191a70a3783ba Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:39 -0500 Subject: [PATCH 139/165] clk: versaclock3: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: 9e3372b2ebac ("clk: versaclock3: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney --- drivers/clk/clk-versaclock3.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/clk/clk-versaclock3.c b/drivers/clk/clk-versaclock3.c index 1849863dbd67..27b6cf70f3ae 100644 --- a/drivers/clk/clk-versaclock3.c +++ b/drivers/clk/clk-versaclock3.c @@ -523,11 +523,8 @@ static int vc3_div_determine_rate(struct clk_hw *hw, return 0; } - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - div_data->table, - div_data->width, div_data->flags); - - return 0; + return divider_determine_rate(hw, req, div_data->table, div_data->width, + div_data->flags); } static int vc3_div_set_rate(struct clk_hw *hw, unsigned long rate, From bb1b0e63dbbd7150324cb4d6aef7854dbe26a617 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:40 -0500 Subject: [PATCH 140/165] clk: x86: cgu: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: f7a6bed91a19 ("clk: x86: cgu: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney --- drivers/clk/x86/clk-cgu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/x86/clk-cgu.c b/drivers/clk/x86/clk-cgu.c index d099667355f8..92ee05d75af2 100644 --- a/drivers/clk/x86/clk-cgu.c +++ b/drivers/clk/x86/clk-cgu.c @@ -137,10 +137,8 @@ static int lgm_clk_divider_determine_rate(struct clk_hw *hw, { struct lgm_clk_divider *divider = to_lgm_clk_divider(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, divider->table, - divider->width, divider->flags); - - return 0; + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); } static int From 30a807808c69a1907001ffb79289237a2ee97cfa Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 8 Jan 2026 16:16:41 -0500 Subject: [PATCH 141/165] clk: zynqmp: divider: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Note that when the main function itself was migrated to use determine_rate, this was mistakenly converted to: req->rate = divider_round_rate(...) This is invalid in the case when an error occurs since it can set the rate to a negative value. Fixes: 0f9cf96a01fd ("clk: zynqmp: divider: convert from round_rate() to determine_rate()") Signed-off-by: Brian Masney --- drivers/clk/zynqmp/divider.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c index c824eeacd8eb..de6f478d527d 100644 --- a/drivers/clk/zynqmp/divider.c +++ b/drivers/clk/zynqmp/divider.c @@ -151,8 +151,9 @@ static int zynqmp_clk_divider_determine_rate(struct clk_hw *hw, width = fls(divider->max_div); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - NULL, width, divider->flags); + ret = divider_determine_rate(hw, req, NULL, width, divider->flags); + if (ret != 0) + return ret; if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && (req->rate % req->best_parent_rate)) From ed806240b8975f951c88ccb4bb75813f5fb949df Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 22 Jan 2026 07:47:16 -0500 Subject: [PATCH 142/165] rtc: ac100: convert from divider_round_rate() to divider_determine_rate() The divider_round_rate() function is now deprecated, so let's migrate to divider_determine_rate() instead so that this deprecated API can be removed. Acked-by: Alexandre Belloni Signed-off-by: Brian Masney --- drivers/rtc/rtc-ac100.c | 73 +++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c index 33626311fa78..bba7115ff3ad 100644 --- a/drivers/rtc/rtc-ac100.c +++ b/drivers/rtc/rtc-ac100.c @@ -140,42 +140,16 @@ static unsigned long ac100_clkout_recalc_rate(struct clk_hw *hw, AC100_CLKOUT_DIV_WIDTH); } -static long ac100_clkout_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long prate) -{ - unsigned long best_rate = 0, tmp_rate, tmp_prate; - int i; - - if (prate == AC100_RTC_32K_RATE) - return divider_round_rate(hw, rate, &prate, NULL, - AC100_CLKOUT_DIV_WIDTH, - CLK_DIVIDER_POWER_OF_TWO); - - for (i = 0; ac100_clkout_prediv[i].div; i++) { - tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[i].val); - tmp_rate = divider_round_rate(hw, rate, &tmp_prate, NULL, - AC100_CLKOUT_DIV_WIDTH, - CLK_DIVIDER_POWER_OF_TWO); - - if (tmp_rate > rate) - continue; - if (rate - tmp_rate < best_rate - tmp_rate) - best_rate = tmp_rate; - } - - return best_rate; -} - static int ac100_clkout_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { - struct clk_hw *best_parent; + int i, ret, num_parents = clk_hw_get_num_parents(hw); + struct clk_hw *best_parent = NULL; unsigned long best = 0; - int i, num_parents = clk_hw_get_num_parents(hw); for (i = 0; i < num_parents; i++) { struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i); - unsigned long tmp, prate; + unsigned long prate; /* * The clock has two parents, one is a fixed clock which is @@ -199,13 +173,40 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw, prate = clk_hw_get_rate(parent); - tmp = ac100_clkout_round_rate(hw, req->rate, prate); + if (prate == AC100_RTC_32K_RATE) { + struct clk_rate_request div_req = *req; - if (tmp > req->rate) - continue; - if (req->rate - tmp < req->rate - best) { - best = tmp; - best_parent = parent; + div_req.best_parent_rate = prate; + + ret = divider_determine_rate(hw, &div_req, NULL, + AC100_CLKOUT_DIV_WIDTH, + CLK_DIVIDER_POWER_OF_TWO); + if (ret != 0 || div_req.rate > req->rate) { + continue; + } else if (req->rate - div_req.rate < req->rate - best) { + best = div_req.rate; + best_parent = parent; + } + } else { + int j; + + for (j = 0; ac100_clkout_prediv[j].div; j++) { + struct clk_rate_request div_req = *req; + unsigned long tmp_prate; + + tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[j].div); + div_req.best_parent_rate = tmp_prate; + + ret = divider_determine_rate(hw, &div_req, NULL, + AC100_CLKOUT_DIV_WIDTH, + CLK_DIVIDER_POWER_OF_TWO); + if (ret != 0 || div_req.rate > req->rate) { + continue; + } else if (req->rate - div_req.rate < req->rate - best) { + best = div_req.rate; + best_parent = parent; + } + } } } @@ -213,7 +214,7 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw, return -EINVAL; req->best_parent_hw = best_parent; - req->best_parent_rate = best; + req->best_parent_rate = clk_hw_get_rate(best_parent); req->rate = best; return 0; From da61439c63d34ae6503d080a847f144d587e3a48 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 21 Nov 2025 17:40:03 +0100 Subject: [PATCH 143/165] clk: tegra: tegra124-emc: fix device leak on set_rate() Make sure to drop the reference taken when looking up the EMC device and its driver data on first set_rate(). Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference. Fixes: 2db04f16b589 ("clk: tegra: Add EMC clock driver") Fixes: 6d6ef58c2470 ("clk: tegra: tegra124-emc: Fix missing put_device() call in emc_ensure_emc_driver") Cc: stable@vger.kernel.org # 4.2: 6d6ef58c2470 Cc: Mikko Perttunen Cc: Miaoqian Lin Signed-off-by: Johan Hovold Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-tegra124-emc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c index 2a6db0434281..2777e70da8b9 100644 --- a/drivers/clk/tegra/clk-tegra124-emc.c +++ b/drivers/clk/tegra/clk-tegra124-emc.c @@ -197,8 +197,8 @@ static struct tegra_emc *emc_ensure_emc_driver(struct tegra_clk_emc *tegra) tegra->emc_node = NULL; tegra->emc = platform_get_drvdata(pdev); + put_device(&pdev->dev); if (!tegra->emc) { - put_device(&pdev->dev); pr_err("%s: cannot find EMC driver\n", __func__); return NULL; } From 871afb43e41ad4e8246438de495a939cd0f8113c Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Tue, 23 Dec 2025 12:05:17 +0100 Subject: [PATCH 144/165] clk: mediatek: Drop __initconst from gates Since commit 8ceff24a754a ("clk: mediatek: clk-gate: Refactor mtk_clk_register_gate to use mtk_gate struct") the mtk_gate structs are no longer just used for initialization/registration, but also at runtime. So drop __initconst annotations. Fixes: 8ceff24a754a ("clk: mediatek: clk-gate: Refactor mtk_clk_register_gate to use mtk_gate struct") Signed-off-by: Sjoerd Simons Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Laura Nao Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt7981-eth.c | 6 +++--- drivers/clk/mediatek/clk-mt8516.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt7981-eth.c b/drivers/clk/mediatek/clk-mt7981-eth.c index 906aec9ddff5..0655ebb6c561 100644 --- a/drivers/clk/mediatek/clk-mt7981-eth.c +++ b/drivers/clk/mediatek/clk-mt7981-eth.c @@ -31,7 +31,7 @@ static const struct mtk_gate_regs sgmii0_cg_regs = { .ops = &mtk_clk_gate_ops_no_setclr_inv, \ } -static const struct mtk_gate sgmii0_clks[] __initconst = { +static const struct mtk_gate sgmii0_clks[] = { GATE_SGMII0(CLK_SGM0_TX_EN, "sgm0_tx_en", "usb_tx250m", 2), GATE_SGMII0(CLK_SGM0_RX_EN, "sgm0_rx_en", "usb_eq_rx250m", 3), GATE_SGMII0(CLK_SGM0_CK0_EN, "sgm0_ck0_en", "usb_ln0", 4), @@ -53,7 +53,7 @@ static const struct mtk_gate_regs sgmii1_cg_regs = { .ops = &mtk_clk_gate_ops_no_setclr_inv, \ } -static const struct mtk_gate sgmii1_clks[] __initconst = { +static const struct mtk_gate sgmii1_clks[] = { GATE_SGMII1(CLK_SGM1_TX_EN, "sgm1_tx_en", "usb_tx250m", 2), GATE_SGMII1(CLK_SGM1_RX_EN, "sgm1_rx_en", "usb_eq_rx250m", 3), GATE_SGMII1(CLK_SGM1_CK1_EN, "sgm1_ck1_en", "usb_ln0", 4), @@ -75,7 +75,7 @@ static const struct mtk_gate_regs eth_cg_regs = { .ops = &mtk_clk_gate_ops_no_setclr_inv, \ } -static const struct mtk_gate eth_clks[] __initconst = { +static const struct mtk_gate eth_clks[] = { GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x", 6), GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "sgm_325m", 7), GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "sgm_325m", 8), diff --git a/drivers/clk/mediatek/clk-mt8516.c b/drivers/clk/mediatek/clk-mt8516.c index 21eb052b0a53..342a59019fea 100644 --- a/drivers/clk/mediatek/clk-mt8516.c +++ b/drivers/clk/mediatek/clk-mt8516.c @@ -544,7 +544,7 @@ static const struct mtk_gate_regs top5_cg_regs = { #define GATE_TOP5(_id, _name, _parent, _shift) \ GATE_MTK(_id, _name, _parent, &top5_cg_regs, _shift, &mtk_clk_gate_ops_setclr) -static const struct mtk_gate top_clks[] __initconst = { +static const struct mtk_gate top_clks[] = { /* TOP1 */ GATE_TOP1(CLK_TOP_THEM, "them", "ahb_infra_sel", 1), GATE_TOP1(CLK_TOP_APDMA, "apdma", "ahb_infra_sel", 2), From a2ed1aed687a21738a6c8bd4043149c443298e88 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Tue, 13 Jan 2026 12:00:08 +0100 Subject: [PATCH 145/165] dt-bindings: clock: mediatek,mt7622-pciesys: Remove syscon compatible The PCIESYS register space contains a pure clock controller, which has no system controller register, so this definitely doesn't need any "syscon" compatible. As a side note, luckily no devicetree ever added the syscon string to PCIESYS clock controller node compatibles, so this also resolves a dtbs_check warning for mt7622. Signed-off-by: AngeloGioacchino Del Regno Acked-by: Rob Herring (Arm) Reviewed-by: Matthias Brugger Signed-off-by: Stephen Boyd --- .../bindings/clock/mediatek,mt7622-pciesys.yaml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml index 9c3913f9092c..c77111d10f90 100644 --- a/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml +++ b/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml @@ -14,11 +14,9 @@ maintainers: properties: compatible: - oneOf: - - items: - - const: mediatek,mt7622-pciesys - - const: syscon - - const: mediatek,mt7629-pciesys + enum: + - mediatek,mt7622-pciesys + - mediatek,mt7629-pciesys reg: maxItems: 1 @@ -40,7 +38,7 @@ additionalProperties: false examples: - | clock-controller@1a100800 { - compatible = "mediatek,mt7622-pciesys", "syscon"; + compatible = "mediatek,mt7622-pciesys"; reg = <0x1a100800 0x1000>; #clock-cells = <1>; #reset-cells = <1>; From 669917676e93fca5ea3c66fc9539830312bec58e Mon Sep 17 00:00:00 2001 From: Nicolas Frattaroli Date: Mon, 15 Dec 2025 11:23:58 +0100 Subject: [PATCH 146/165] clk: Respect CLK_OPS_PARENT_ENABLE during recalc When CLK_OPS_PARENT_ENABLE was introduced, it guarded various clock operations, such as setting the rate or switching parents. However, another operation that can and often does touch actual hardware state is recalc_rate, which may also be affected by such a dependency. Add parent enables/disables where the recalc_rate op is called directly. Fixes: fc8726a2c021 ("clk: core: support clocks which requires parents enable (part 2)") Fixes: a4b3518d146f ("clk: core: support clocks which requires parents enable (part 1)") Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Chen-Yu Tsai Signed-off-by: Nicolas Frattaroli Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 85d2f2481acf..1b0f9d567f48 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1921,7 +1921,14 @@ static unsigned long clk_recalc(struct clk_core *core, unsigned long rate = parent_rate; if (core->ops->recalc_rate && !clk_pm_runtime_get(core)) { + if (core->flags & CLK_OPS_PARENT_ENABLE) + clk_core_prepare_enable(core->parent); + rate = core->ops->recalc_rate(core->hw, parent_rate); + + if (core->flags & CLK_OPS_PARENT_ENABLE) + clk_core_disable_unprepare(core->parent); + clk_pm_runtime_put(core); } return rate; @@ -4031,6 +4038,9 @@ static int __clk_core_init(struct clk_core *core) */ clk_core_update_duty_cycle_nolock(core); + if (core->flags & CLK_OPS_PARENT_ENABLE) + clk_core_prepare_enable(core->parent); + /* * Set clk's rate. The preferred method is to use .recalc_rate. For * simple clocks and lazy developers the default fallback is to use the @@ -4046,6 +4056,9 @@ static int __clk_core_init(struct clk_core *core) rate = 0; core->rate = core->req_rate = rate; + if (core->flags & CLK_OPS_PARENT_ENABLE) + clk_core_disable_unprepare(core->parent); + /* * Enable CLK_IS_CRITICAL clocks so newly added critical clocks * don't get accidentally disabled when walking the orphan tree and From c9ced38af56fe6411118c6bc6522eab80849326d Mon Sep 17 00:00:00 2001 From: Nicolas Frattaroli Date: Mon, 15 Dec 2025 11:23:59 +0100 Subject: [PATCH 147/165] clk: mediatek: Refactor pll registration to pass device As it stands, mtk_clk_register_plls takes a struct device_node pointer as its first argument. This is a tragic happenstance, as it's trivial to get the device_node from a struct device, but the opposite not so much. The struct device is a much more useful thing to have passed down. Refactor mtk_clk_register_plls to take a struct device pointer instead of a struct device_node pointer, and fix up all users of this function. Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Chen-Yu Tsai Signed-off-by: Nicolas Frattaroli Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt2701.c | 2 +- drivers/clk/mediatek/clk-mt2712-apmixedsys.c | 2 +- drivers/clk/mediatek/clk-mt6735-apmixedsys.c | 4 ++-- drivers/clk/mediatek/clk-mt6765.c | 2 +- drivers/clk/mediatek/clk-mt6779.c | 2 +- drivers/clk/mediatek/clk-mt6797.c | 2 +- drivers/clk/mediatek/clk-mt7622-apmixedsys.c | 2 +- drivers/clk/mediatek/clk-mt7629.c | 2 +- drivers/clk/mediatek/clk-mt7981-apmixed.c | 2 +- drivers/clk/mediatek/clk-mt7986-apmixed.c | 2 +- drivers/clk/mediatek/clk-mt7988-apmixed.c | 2 +- drivers/clk/mediatek/clk-mt8135-apmixedsys.c | 3 ++- drivers/clk/mediatek/clk-mt8167-apmixedsys.c | 2 +- drivers/clk/mediatek/clk-mt8183-apmixedsys.c | 2 +- drivers/clk/mediatek/clk-mt8188-apmixedsys.c | 2 +- drivers/clk/mediatek/clk-mt8195-apusys_pll.c | 3 ++- drivers/clk/mediatek/clk-mt8196-apmixedsys.c | 3 ++- drivers/clk/mediatek/clk-mt8196-mcu.c | 2 +- drivers/clk/mediatek/clk-mt8196-mfg.c | 2 +- drivers/clk/mediatek/clk-mt8196-vlpckgen.c | 2 +- drivers/clk/mediatek/clk-mt8365-apmixedsys.c | 2 +- drivers/clk/mediatek/clk-mt8516-apmixedsys.c | 2 +- drivers/clk/mediatek/clk-pll.c | 7 ++++--- drivers/clk/mediatek/clk-pll.h | 10 ++++------ 24 files changed, 34 insertions(+), 32 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c index 1e88ad8b93f4..d9f40fda73d1 100644 --- a/drivers/clk/mediatek/clk-mt2701.c +++ b/drivers/clk/mediatek/clk-mt2701.c @@ -978,7 +978,7 @@ static int mtk_apmixedsys_init(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, apmixed_plls, ARRAY_SIZE(apmixed_plls), + mtk_clk_register_plls(&pdev->dev, apmixed_plls, ARRAY_SIZE(apmixed_plls), clk_data); mtk_clk_register_factors(apmixed_fixed_divs, ARRAY_SIZE(apmixed_fixed_divs), clk_data); diff --git a/drivers/clk/mediatek/clk-mt2712-apmixedsys.c b/drivers/clk/mediatek/clk-mt2712-apmixedsys.c index a60622d251ff..54b18e9f83f8 100644 --- a/drivers/clk/mediatek/clk-mt2712-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt2712-apmixedsys.c @@ -119,7 +119,7 @@ static int clk_mt2712_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + r = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); if (r) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt6735-apmixedsys.c b/drivers/clk/mediatek/clk-mt6735-apmixedsys.c index e0949911e8f7..9e30c089a209 100644 --- a/drivers/clk/mediatek/clk-mt6735-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt6735-apmixedsys.c @@ -93,8 +93,8 @@ static int clk_mt6735_apmixed_probe(struct platform_device *pdev) return -ENOMEM; platform_set_drvdata(pdev, clk_data); - ret = mtk_clk_register_plls(pdev->dev.of_node, apmixedsys_plls, - ARRAY_SIZE(apmixedsys_plls), clk_data); + ret = mtk_clk_register_plls(&pdev->dev, apmixedsys_plls, + ARRAY_SIZE(apmixedsys_plls), clk_data); if (ret) { dev_err(&pdev->dev, "Failed to register PLLs: %d\n", ret); return ret; diff --git a/drivers/clk/mediatek/clk-mt6765.c b/drivers/clk/mediatek/clk-mt6765.c index d53731e7933f..60f6f9fa7dcf 100644 --- a/drivers/clk/mediatek/clk-mt6765.c +++ b/drivers/clk/mediatek/clk-mt6765.c @@ -740,7 +740,7 @@ static int clk_mt6765_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); mtk_clk_register_gates(&pdev->dev, node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data); diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c index 86732f5acf93..4b9dcb910b03 100644 --- a/drivers/clk/mediatek/clk-mt6779.c +++ b/drivers/clk/mediatek/clk-mt6779.c @@ -1220,7 +1220,7 @@ static int clk_mt6779_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); mtk_clk_register_gates(&pdev->dev, node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data); diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c index fb59e71af58e..ebf850ac57f5 100644 --- a/drivers/clk/mediatek/clk-mt6797.c +++ b/drivers/clk/mediatek/clk-mt6797.c @@ -655,7 +655,7 @@ static int mtk_apmixedsys_init(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); } diff --git a/drivers/clk/mediatek/clk-mt7622-apmixedsys.c b/drivers/clk/mediatek/clk-mt7622-apmixedsys.c index 2350592d9a93..8a29eaab0cfc 100644 --- a/drivers/clk/mediatek/clk-mt7622-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt7622-apmixedsys.c @@ -96,7 +96,7 @@ static int clk_mt7622_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data); if (ret) return ret; diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c index baf94e7bea37..e154771b1b8b 100644 --- a/drivers/clk/mediatek/clk-mt7629.c +++ b/drivers/clk/mediatek/clk-mt7629.c @@ -634,7 +634,7 @@ static int mtk_apmixedsys_init(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); mtk_clk_register_gates(&pdev->dev, node, apmixed_clks, diff --git a/drivers/clk/mediatek/clk-mt7981-apmixed.c b/drivers/clk/mediatek/clk-mt7981-apmixed.c index e8211eb4e09e..6606b54fb376 100644 --- a/drivers/clk/mediatek/clk-mt7981-apmixed.c +++ b/drivers/clk/mediatek/clk-mt7981-apmixed.c @@ -76,7 +76,7 @@ static int clk_mt7981_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); if (r) { diff --git a/drivers/clk/mediatek/clk-mt7986-apmixed.c b/drivers/clk/mediatek/clk-mt7986-apmixed.c index 93751abe6be8..1c79418d08a7 100644 --- a/drivers/clk/mediatek/clk-mt7986-apmixed.c +++ b/drivers/clk/mediatek/clk-mt7986-apmixed.c @@ -74,7 +74,7 @@ static int clk_mt7986_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); if (r) { diff --git a/drivers/clk/mediatek/clk-mt7988-apmixed.c b/drivers/clk/mediatek/clk-mt7988-apmixed.c index 63d33a78cb48..416a4b88d100 100644 --- a/drivers/clk/mediatek/clk-mt7988-apmixed.c +++ b/drivers/clk/mediatek/clk-mt7988-apmixed.c @@ -86,7 +86,7 @@ static int clk_mt7988_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + r = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); if (r) goto free_apmixed_data; diff --git a/drivers/clk/mediatek/clk-mt8135-apmixedsys.c b/drivers/clk/mediatek/clk-mt8135-apmixedsys.c index bdadc35c64cb..19e4ee489ec3 100644 --- a/drivers/clk/mediatek/clk-mt8135-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8135-apmixedsys.c @@ -57,7 +57,8 @@ static int clk_mt8135_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), + clk_data); if (ret) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt8167-apmixedsys.c b/drivers/clk/mediatek/clk-mt8167-apmixedsys.c index adf576786696..fb6c21bbeef8 100644 --- a/drivers/clk/mediatek/clk-mt8167-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8167-apmixedsys.c @@ -105,7 +105,7 @@ static int clk_mt8167_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data); if (ret) return ret; diff --git a/drivers/clk/mediatek/clk-mt8183-apmixedsys.c b/drivers/clk/mediatek/clk-mt8183-apmixedsys.c index 551adbfd7ac9..6242d4f5376e 100644 --- a/drivers/clk/mediatek/clk-mt8183-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8183-apmixedsys.c @@ -155,7 +155,7 @@ static int clk_mt8183_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data); if (ret) return ret; diff --git a/drivers/clk/mediatek/clk-mt8188-apmixedsys.c b/drivers/clk/mediatek/clk-mt8188-apmixedsys.c index 21d7a9a2ab1a..a1de596bff99 100644 --- a/drivers/clk/mediatek/clk-mt8188-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8188-apmixedsys.c @@ -106,7 +106,7 @@ static int clk_mt8188_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + r = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); if (r) goto free_apmixed_data; diff --git a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c index 8b45a3fad02f..a2d98ed58e34 100644 --- a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c +++ b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c @@ -66,7 +66,8 @@ static int clk_mt8195_apusys_pll_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, apusys_plls, ARRAY_SIZE(apusys_plls), clk_data); + r = mtk_clk_register_plls(&pdev->dev, apusys_plls, + ARRAY_SIZE(apusys_plls), clk_data); if (r) goto free_apusys_pll_data; diff --git a/drivers/clk/mediatek/clk-mt8196-apmixedsys.c b/drivers/clk/mediatek/clk-mt8196-apmixedsys.c index 617f5449b88b..c4ebb0170b82 100644 --- a/drivers/clk/mediatek/clk-mt8196-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8196-apmixedsys.c @@ -152,7 +152,8 @@ static int clk_mt8196_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, mcd->clks, mcd->num_clks, clk_data); + r = mtk_clk_register_plls(&pdev->dev, mcd->clks, mcd->num_clks, + clk_data); if (r) goto free_apmixed_data; diff --git a/drivers/clk/mediatek/clk-mt8196-mcu.c b/drivers/clk/mediatek/clk-mt8196-mcu.c index 5cbcc411ae73..13642fc673c2 100644 --- a/drivers/clk/mediatek/clk-mt8196-mcu.c +++ b/drivers/clk/mediatek/clk-mt8196-mcu.c @@ -122,7 +122,7 @@ static int clk_mt8196_mcu_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, plls, num_plls, clk_data); + r = mtk_clk_register_plls(&pdev->dev, plls, num_plls, clk_data); if (r) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt8196-mfg.c b/drivers/clk/mediatek/clk-mt8196-mfg.c index ae1eb9de79ae..8e09c0f7b754 100644 --- a/drivers/clk/mediatek/clk-mt8196-mfg.c +++ b/drivers/clk/mediatek/clk-mt8196-mfg.c @@ -105,7 +105,7 @@ static int clk_mt8196_mfg_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, plls, num_plls, clk_data); + r = mtk_clk_register_plls(&pdev->dev, plls, num_plls, clk_data); if (r) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt8196-vlpckgen.c b/drivers/clk/mediatek/clk-mt8196-vlpckgen.c index d59a8a9d9855..7dcc164627c5 100644 --- a/drivers/clk/mediatek/clk-mt8196-vlpckgen.c +++ b/drivers/clk/mediatek/clk-mt8196-vlpckgen.c @@ -664,7 +664,7 @@ static int clk_mt8196_vlp_probe(struct platform_device *pdev) if (r) goto unregister_factors; - r = mtk_clk_register_plls(node, vlp_plls, ARRAY_SIZE(vlp_plls), + r = mtk_clk_register_plls(dev, vlp_plls, ARRAY_SIZE(vlp_plls), clk_data); if (r) goto unregister_muxes; diff --git a/drivers/clk/mediatek/clk-mt8365-apmixedsys.c b/drivers/clk/mediatek/clk-mt8365-apmixedsys.c index f41b991a0178..e331aa28a4bd 100644 --- a/drivers/clk/mediatek/clk-mt8365-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8365-apmixedsys.c @@ -133,7 +133,7 @@ static int clk_mt8365_apmixed_probe(struct platform_device *pdev) return PTR_ERR(hw); clk_data->hws[CLK_APMIXED_USB20_EN] = hw; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data); if (ret) return ret; diff --git a/drivers/clk/mediatek/clk-mt8516-apmixedsys.c b/drivers/clk/mediatek/clk-mt8516-apmixedsys.c index edd9174d2f2f..2a6206cae2f0 100644 --- a/drivers/clk/mediatek/clk-mt8516-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8516-apmixedsys.c @@ -87,7 +87,7 @@ static int clk_mt8516_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data); if (ret) return ret; diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index cd2b6ce551c6..5caf91ae9ddb 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "clk-pll.h" @@ -404,7 +405,7 @@ void mtk_clk_unregister_pll(struct clk_hw *hw) kfree(pll); } -int mtk_clk_register_plls(struct device_node *node, +int mtk_clk_register_plls(struct device *dev, const struct mtk_pll_data *plls, int num_plls, struct clk_hw_onecell_data *clk_data) { @@ -412,7 +413,7 @@ int mtk_clk_register_plls(struct device_node *node, int i; struct clk_hw *hw; - base = of_iomap(node, 0); + base = of_iomap(dev->of_node, 0); if (!base) { pr_err("%s(): ioremap failed\n", __func__); return -EINVAL; @@ -423,7 +424,7 @@ int mtk_clk_register_plls(struct device_node *node, if (!IS_ERR_OR_NULL(clk_data->hws[pll->id])) { pr_warn("%pOF: Trying to register duplicate clock ID: %d\n", - node, pll->id); + dev->of_node, pll->id); continue; } diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h index d71c150ce83e..38fde1a273bf 100644 --- a/drivers/clk/mediatek/clk-pll.h +++ b/drivers/clk/mediatek/clk-pll.h @@ -10,9 +10,7 @@ #include #include -struct clk_ops; -struct clk_hw_onecell_data; -struct device_node; +struct device; struct mtk_pll_div_table { u32 div; @@ -78,9 +76,9 @@ struct mtk_clk_pll { const struct mtk_pll_data *data; }; -int mtk_clk_register_plls(struct device_node *node, - const struct mtk_pll_data *plls, int num_plls, - struct clk_hw_onecell_data *clk_data); +int mtk_clk_register_plls(struct device *dev, const struct mtk_pll_data *plls, + int num_plls, struct clk_hw_onecell_data *clk_data); + void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls, struct clk_hw_onecell_data *clk_data); From ecffd05839b32f17bde1f3701b68ab182a837b07 Mon Sep 17 00:00:00 2001 From: Nicolas Frattaroli Date: Mon, 15 Dec 2025 11:24:00 +0100 Subject: [PATCH 148/165] clk: mediatek: Pass device to clk_hw_register for PLLs Passing the struct device pointer to clk_hw_register allows for runtime power management to work for the registered clock controllers. However, the mediatek PLL clocks do not do this. Change this by adding a struct device pointer argument to mtk_clk_register_pll, and fix up the only other user of it. Also add a new member to the struct mtk_clk_pll for the struct device pointer, which is set by mtk_clk_register_pll and is used by mtk_clk_register_pll_ops. If mtk_clk_register_pll is called with a NULL struct device pointer, then everything still works as expected; the clock core will simply treat them as previously, i.e. without runtime power management. Reviewed-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Nicolas Frattaroli Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-pll.c | 9 ++++++--- drivers/clk/mediatek/clk-pll.h | 4 +++- drivers/clk/mediatek/clk-pllfh.c | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index 5caf91ae9ddb..c4f9c06e5133 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c @@ -366,7 +366,7 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, init.parent_names = &parent_name; init.num_parents = 1; - ret = clk_hw_register(NULL, &pll->hw); + ret = clk_hw_register(pll->dev, &pll->hw); if (ret) return ERR_PTR(ret); @@ -374,7 +374,8 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, return &pll->hw; } -struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data, +struct clk_hw *mtk_clk_register_pll(struct device *dev, + const struct mtk_pll_data *data, void __iomem *base) { struct mtk_clk_pll *pll; @@ -385,6 +386,8 @@ struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data, if (!pll) return ERR_PTR(-ENOMEM); + pll->dev = dev; + hw = mtk_clk_register_pll_ops(pll, data, base, pll_ops); if (IS_ERR(hw)) kfree(pll); @@ -428,7 +431,7 @@ int mtk_clk_register_plls(struct device *dev, continue; } - hw = mtk_clk_register_pll(pll, base); + hw = mtk_clk_register_pll(dev, pll, base); if (IS_ERR(hw)) { pr_err("Failed to register clk %s: %pe\n", pll->name, diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h index 38fde1a273bf..f6493699c4e3 100644 --- a/drivers/clk/mediatek/clk-pll.h +++ b/drivers/clk/mediatek/clk-pll.h @@ -61,6 +61,7 @@ struct mtk_pll_data { */ struct mtk_clk_pll { + struct device *dev; struct clk_hw hw; void __iomem *base_addr; void __iomem *pd_addr; @@ -108,7 +109,8 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, const struct mtk_pll_data *data, void __iomem *base, const struct clk_ops *pll_ops); -struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data, +struct clk_hw *mtk_clk_register_pll(struct device *dev, + const struct mtk_pll_data *data, void __iomem *base); void mtk_clk_unregister_pll(struct clk_hw *hw); diff --git a/drivers/clk/mediatek/clk-pllfh.c b/drivers/clk/mediatek/clk-pllfh.c index 83630ee07ee9..62bfe4a480f1 100644 --- a/drivers/clk/mediatek/clk-pllfh.c +++ b/drivers/clk/mediatek/clk-pllfh.c @@ -220,7 +220,7 @@ int mtk_clk_register_pllfhs(struct device_node *node, if (use_fhctl) hw = mtk_clk_register_pllfh(pll, pllfh, base); else - hw = mtk_clk_register_pll(pll, base); + hw = mtk_clk_register_pll(NULL, pll, base); if (IS_ERR(hw)) { pr_err("Failed to register %s clk %s: %ld\n", From 483f364bb0014495da19c1ccb1a6e2423fc37d95 Mon Sep 17 00:00:00 2001 From: Nicolas Frattaroli Date: Mon, 15 Dec 2025 11:24:01 +0100 Subject: [PATCH 149/165] clk: mediatek: Refactor pllfh registration to pass device After refactoring all of PLL to pass the device, it's now fairly easy to refactor pllfh and its users, as pllfh registration wraps PLL registration. Do this refactor and move all of the pllfh users to pass the device as well. Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Nicolas Frattaroli Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt6795-apmixedsys.c | 2 +- drivers/clk/mediatek/clk-mt8173-apmixedsys.c | 14 +++++++------- drivers/clk/mediatek/clk-mt8186-apmixedsys.c | 2 +- drivers/clk/mediatek/clk-mt8192-apmixedsys.c | 2 +- drivers/clk/mediatek/clk-mt8195-apmixedsys.c | 2 +- drivers/clk/mediatek/clk-pllfh.c | 13 ++++++++----- drivers/clk/mediatek/clk-pllfh.h | 2 +- 7 files changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt6795-apmixedsys.c b/drivers/clk/mediatek/clk-mt6795-apmixedsys.c index 91665d7f125e..123d5d7fea85 100644 --- a/drivers/clk/mediatek/clk-mt6795-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt6795-apmixedsys.c @@ -152,7 +152,7 @@ static int clk_mt6795_apmixed_probe(struct platform_device *pdev) return -ENOMEM; fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs)); - ret = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls), + ret = mtk_clk_register_pllfhs(dev, plls, ARRAY_SIZE(plls), pllfhs, ARRAY_SIZE(pllfhs), clk_data); if (ret) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c index 95385bb67d55..d7d416172ab3 100644 --- a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c @@ -140,13 +140,13 @@ MODULE_DEVICE_TABLE(of, of_match_clk_mt8173_apmixed); static int clk_mt8173_apmixed_probe(struct platform_device *pdev) { const u8 *fhctl_node = "mediatek,mt8173-fhctl"; - struct device_node *node = pdev->dev.of_node; struct clk_hw_onecell_data *clk_data; + struct device *dev = &pdev->dev; void __iomem *base; struct clk_hw *hw; int r; - base = of_iomap(node, 0); + base = of_iomap(dev->of_node, 0); if (!base) return -ENOMEM; @@ -157,25 +157,25 @@ static int clk_mt8173_apmixed_probe(struct platform_device *pdev) } fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs)); - r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls), - pllfhs, ARRAY_SIZE(pllfhs), clk_data); + r = mtk_clk_register_pllfhs(dev, plls, ARRAY_SIZE(plls), pllfhs, + ARRAY_SIZE(pllfhs), clk_data); if (r) goto free_clk_data; hw = mtk_clk_register_ref2usb_tx("ref2usb_tx", "clk26m", base + REGOFF_REF2USB); if (IS_ERR(hw)) { r = PTR_ERR(hw); - dev_err(&pdev->dev, "Failed to register ref2usb_tx: %d\n", r); + dev_err(dev, "Failed to register ref2usb_tx: %d\n", r); goto unregister_plls; } clk_data->hws[CLK_APMIXED_REF2USB_TX] = hw; - hw = devm_clk_hw_register_divider(&pdev->dev, "hdmi_ref", "tvdpll_594m", 0, + hw = devm_clk_hw_register_divider(dev, "hdmi_ref", "tvdpll_594m", 0, base + REGOFF_HDMI_REF, 16, 3, CLK_DIVIDER_POWER_OF_TWO, NULL); clk_data->hws[CLK_APMIXED_HDMI_REF] = hw; - r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + r = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, clk_data); if (r) goto unregister_ref2usb; diff --git a/drivers/clk/mediatek/clk-mt8186-apmixedsys.c b/drivers/clk/mediatek/clk-mt8186-apmixedsys.c index 4b2b16578232..d35dd2632e43 100644 --- a/drivers/clk/mediatek/clk-mt8186-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8186-apmixedsys.c @@ -151,7 +151,7 @@ static int clk_mt8186_apmixed_probe(struct platform_device *pdev) fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs)); - r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls), + r = mtk_clk_register_pllfhs(&pdev->dev, plls, ARRAY_SIZE(plls), pllfhs, ARRAY_SIZE(pllfhs), clk_data); if (r) goto free_apmixed_data; diff --git a/drivers/clk/mediatek/clk-mt8192-apmixedsys.c b/drivers/clk/mediatek/clk-mt8192-apmixedsys.c index 0b66a27e4d5a..b0563a285bd6 100644 --- a/drivers/clk/mediatek/clk-mt8192-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8192-apmixedsys.c @@ -162,7 +162,7 @@ static int clk_mt8192_apmixed_probe(struct platform_device *pdev) fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs)); - r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls), + r = mtk_clk_register_pllfhs(&pdev->dev, plls, ARRAY_SIZE(plls), pllfhs, ARRAY_SIZE(pllfhs), clk_data); if (r) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c index 282a3137dc89..44917ab034c5 100644 --- a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c @@ -181,7 +181,7 @@ static int clk_mt8195_apmixed_probe(struct platform_device *pdev) fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs)); - r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls), + r = mtk_clk_register_pllfhs(&pdev->dev, plls, ARRAY_SIZE(plls), pllfhs, ARRAY_SIZE(pllfhs), clk_data); if (r) goto free_apmixed_data; diff --git a/drivers/clk/mediatek/clk-pllfh.c b/drivers/clk/mediatek/clk-pllfh.c index 62bfe4a480f1..8ad11023d911 100644 --- a/drivers/clk/mediatek/clk-pllfh.c +++ b/drivers/clk/mediatek/clk-pllfh.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "clk-mtk.h" #include "clk-pllfh.h" @@ -149,7 +150,7 @@ static bool fhctl_is_supported_and_enabled(const struct mtk_pllfh_data *pllfh) } static struct clk_hw * -mtk_clk_register_pllfh(const struct mtk_pll_data *pll_data, +mtk_clk_register_pllfh(struct device *dev, const struct mtk_pll_data *pll_data, struct mtk_pllfh_data *pllfh_data, void __iomem *base) { struct clk_hw *hw; @@ -166,6 +167,8 @@ mtk_clk_register_pllfh(const struct mtk_pll_data *pll_data, goto out; } + fh->clk_pll.dev = dev; + hw = mtk_clk_register_pll_ops(&fh->clk_pll, pll_data, base, &mtk_pllfh_ops); @@ -194,7 +197,7 @@ static void mtk_clk_unregister_pllfh(struct clk_hw *hw) kfree(fh); } -int mtk_clk_register_pllfhs(struct device_node *node, +int mtk_clk_register_pllfhs(struct device *dev, const struct mtk_pll_data *plls, int num_plls, struct mtk_pllfh_data *pllfhs, int num_fhs, struct clk_hw_onecell_data *clk_data) @@ -203,7 +206,7 @@ int mtk_clk_register_pllfhs(struct device_node *node, int i; struct clk_hw *hw; - base = of_iomap(node, 0); + base = of_iomap(dev->of_node, 0); if (!base) { pr_err("%s(): ioremap failed\n", __func__); return -EINVAL; @@ -218,9 +221,9 @@ int mtk_clk_register_pllfhs(struct device_node *node, use_fhctl = fhctl_is_supported_and_enabled(pllfh); if (use_fhctl) - hw = mtk_clk_register_pllfh(pll, pllfh, base); + hw = mtk_clk_register_pllfh(dev, pll, pllfh, base); else - hw = mtk_clk_register_pll(NULL, pll, base); + hw = mtk_clk_register_pll(dev, pll, base); if (IS_ERR(hw)) { pr_err("Failed to register %s clk %s: %ld\n", diff --git a/drivers/clk/mediatek/clk-pllfh.h b/drivers/clk/mediatek/clk-pllfh.h index 5f419c2ec01f..a4f337acad71 100644 --- a/drivers/clk/mediatek/clk-pllfh.h +++ b/drivers/clk/mediatek/clk-pllfh.h @@ -68,7 +68,7 @@ struct fh_operation { int (*ssc_enable)(struct mtk_fh *fh, u32 rate); }; -int mtk_clk_register_pllfhs(struct device_node *node, +int mtk_clk_register_pllfhs(struct device *dev, const struct mtk_pll_data *plls, int num_plls, struct mtk_pllfh_data *pllfhs, int num_pllfhs, struct clk_hw_onecell_data *clk_data); From 19024c9980c331908de0680283d572b80308654e Mon Sep 17 00:00:00 2001 From: Nicolas Frattaroli Date: Mon, 15 Dec 2025 11:24:02 +0100 Subject: [PATCH 150/165] clk: mediatek: Add mfg_eb as parent to mt8196 mfgpll clocks All the MFGPLL require MFG_EB to be on for any operation on them, and they only tick when MFG_EB is on as well, therefore making this a parent-child relationship. This dependency wasn't clear during the initial upstreaming of these clock controllers, as it only made itself known when I could observe the effects of the clock by bringing up a different piece of hardware. Add a new PLL_PARENT_EN flag to mediatek's clk-pll.h, and check for it when initialising the pll to then translate it into the actual CLK_OPS_PARENT_ENABLE flag. Then add the mfg_eb parent to the mfgpll clocks, and set the new PLL_PARENT_EN flag. Fixes: 03dc02f8c7dc ("clk: mediatek: Add MT8196 mfg clock support") Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Nicolas Frattaroli Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt8196-mfg.c | 13 +++++++------ drivers/clk/mediatek/clk-pll.c | 3 +++ drivers/clk/mediatek/clk-pll.h | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt8196-mfg.c b/drivers/clk/mediatek/clk-mt8196-mfg.c index 8e09c0f7b754..a317183f1681 100644 --- a/drivers/clk/mediatek/clk-mt8196-mfg.c +++ b/drivers/clk/mediatek/clk-mt8196-mfg.c @@ -58,24 +58,25 @@ .pcw_shift = _pcw_shift, \ .pcwbits = _pcwbits, \ .pcwibits = MT8196_INTEGER_BITS, \ + .parent_name = "mfg_eb", \ } static const struct mtk_pll_data mfg_ao_plls[] = { - PLL(CLK_MFG_AO_MFGPLL, "mfgpll", MFGPLL_CON0, MFGPLL_CON0, 0, 0, 0, - BIT(0), MFGPLL_CON1, 24, 0, 0, 0, + PLL(CLK_MFG_AO_MFGPLL, "mfgpll", MFGPLL_CON0, MFGPLL_CON0, 0, 0, + PLL_PARENT_EN, BIT(0), MFGPLL_CON1, 24, 0, 0, 0, MFGPLL_CON1, 0, 22), }; static const struct mtk_pll_data mfgsc0_ao_plls[] = { PLL(CLK_MFGSC0_AO_MFGPLL_SC0, "mfgpll-sc0", MFGPLL_SC0_CON0, - MFGPLL_SC0_CON0, 0, 0, 0, BIT(0), MFGPLL_SC0_CON1, 24, 0, 0, 0, - MFGPLL_SC0_CON1, 0, 22), + MFGPLL_SC0_CON0, 0, 0, PLL_PARENT_EN, BIT(0), MFGPLL_SC0_CON1, 24, + 0, 0, 0, MFGPLL_SC0_CON1, 0, 22), }; static const struct mtk_pll_data mfgsc1_ao_plls[] = { PLL(CLK_MFGSC1_AO_MFGPLL_SC1, "mfgpll-sc1", MFGPLL_SC1_CON0, - MFGPLL_SC1_CON0, 0, 0, 0, BIT(0), MFGPLL_SC1_CON1, 24, 0, 0, 0, - MFGPLL_SC1_CON1, 0, 22), + MFGPLL_SC1_CON0, 0, 0, PLL_PARENT_EN, BIT(0), MFGPLL_SC1_CON1, 24, + 0, 0, 0, MFGPLL_SC1_CON1, 0, 22), }; static const struct of_device_id of_match_clk_mt8196_mfg[] = { diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index c4f9c06e5133..0f3759fcd9d0 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c @@ -359,6 +359,9 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, init.name = data->name; init.flags = (data->flags & PLL_AO) ? CLK_IS_CRITICAL : 0; + if (data->flags & PLL_PARENT_EN) + init.flags |= CLK_OPS_PARENT_ENABLE; + init.ops = pll_ops; if (data->parent_name) init.parent_names = &data->parent_name; diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h index f6493699c4e3..f49dc2732ffe 100644 --- a/drivers/clk/mediatek/clk-pll.h +++ b/drivers/clk/mediatek/clk-pll.h @@ -19,6 +19,7 @@ struct mtk_pll_div_table { #define HAVE_RST_BAR BIT(0) #define PLL_AO BIT(1) +#define PLL_PARENT_EN BIT(2) #define POSTDIV_MASK GENMASK(2, 0) struct mtk_pll_data { From 963bb1866c2cf3f599dcf6d57bde35fb6fb42ec4 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 22 Dec 2025 16:02:35 +0100 Subject: [PATCH 151/165] clk: mediatek: don't select clk-mt8192 for all ARM64 builds This option defaults to y for ARCH64 meaning it's built even if we don't want anything related to mediatek. Make the default condition stricter and only build it if ARCH_MEDIATEK is selected. Signed-off-by: Bartosz Golaszewski Reviewed-by: Brian Masney Reviewed-by: Chen-Yu Tsai Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 0e8dd82aa84e..2c09fd729bab 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -820,7 +820,7 @@ config COMMON_CLK_MT8192 depends on ARM64 || COMPILE_TEST select COMMON_CLK_MEDIATEK select COMMON_CLK_MEDIATEK_FHCTL - default ARM64 + default ARM64 && ARCH_MEDIATEK help This driver supports MediaTek MT8192 basic clocks. From aa2ad19210a6a444111bce55e8b69579f29318fb Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Sun, 23 Nov 2025 23:43:15 +0800 Subject: [PATCH 152/165] clk: mediatek: Fix error handling in runtime PM setup devm_pm_runtime_enable() can fail due to memory allocation. The current code ignores its return value, and when pm_runtime_resume_and_get() fails, it returns directly without unmapping the shared_io region. Add error handling for devm_pm_runtime_enable(). Reorder cleanup labels to properly unmap shared_io on pm_runtime_resume_and_get() failure. Fixes: 2f7b1d8b5505 ("clk: mediatek: Do a runtime PM get on controllers during probe") Signed-off-by: Haotian Zhang Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mtk.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 19cd27941747..deafe55a96cb 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -497,14 +497,16 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev, if (mcd->need_runtime_pm) { - devm_pm_runtime_enable(&pdev->dev); + r = devm_pm_runtime_enable(&pdev->dev); + if (r) + goto unmap_io; /* * Do a pm_runtime_resume_and_get() to workaround a possible * deadlock between clk_register() and the genpd framework. */ r = pm_runtime_resume_and_get(&pdev->dev); if (r) - return r; + goto unmap_io; } /* Calculate how many clk_hw_onecell_data entries to allocate */ @@ -618,11 +620,11 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev, free_data: mtk_free_clk_data(clk_data); free_base: - if (mcd->shared_io && base) - iounmap(base); - if (mcd->need_runtime_pm) pm_runtime_put(&pdev->dev); +unmap_io: + if (mcd->shared_io && base) + iounmap(base); return r; } From 1b8773864904c7a25e45f1b12ab505bdb7e06568 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 24 Dec 2025 12:42:11 +0100 Subject: [PATCH 153/165] clk: zynqmp: divider: Fix zynqmp_clk_divider_determine_rate kerneldoc After renaming round_rate->determine, kerneldoc does not match anymore, causing W=1 warnings: Warning: drivers/clk/zynqmp/divider.c:122 function parameter 'req' not described in 'zynqmp_clk_divider_determine_rate' Warning: drivers/clk/zynqmp/divider.c:122 expecting prototype for zynqmp_clk_divider_round_rate(). Prototype was for zynqmp_clk_divider_determine_rate() instead Fixes: 0f9cf96a01fd ("clk: zynqmp: divider: convert from round_rate() to determine_rate()") Signed-off-by: Krzysztof Kozlowski Reviewed-by: Brian Masney Signed-off-by: Stephen Boyd --- drivers/clk/zynqmp/divider.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c index c824eeacd8eb..5baa967aa7c9 100644 --- a/drivers/clk/zynqmp/divider.c +++ b/drivers/clk/zynqmp/divider.c @@ -111,10 +111,9 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, } /** - * zynqmp_clk_divider_round_rate() - Round rate of divider clock + * zynqmp_clk_divider_determine_rate() - Determine rate of divider clock * @hw: handle between common and hardware-specific interfaces - * @rate: rate of clock to be set - * @prate: rate of parent clock + * @req: rate of clock to be set * * Return: 0 on success else error+reason */ From 750e0e0a1652530618d2c07697618e705bc5061b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 24 Dec 2025 12:42:12 +0100 Subject: [PATCH 154/165] clk: zynqmp: pll: Fix zynqmp_clk_divider_determine_rate kerneldoc After renaming round_rate->determine, kerneldoc does not match anymore, causing W=1 warnings: pll.c:102 function parameter 'req' not described in 'zynqmp_pll_determine_rate' pll.c:102 expecting prototype for zynqmp_pll_round_rate(). Prototype was for zynqmp_pll_determine_rate() instead Fixes: 193650c7a873 ("clk: zynqmp: pll: convert from round_rate() to determine_rate()") Signed-off-by: Krzysztof Kozlowski Reviewed-by: Brian Masney Signed-off-by: Stephen Boyd --- drivers/clk/zynqmp/pll.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c index 630a3936c97c..6bc2c3934f56 100644 --- a/drivers/clk/zynqmp/pll.c +++ b/drivers/clk/zynqmp/pll.c @@ -91,10 +91,9 @@ static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on) } /** - * zynqmp_pll_round_rate() - Round a clock frequency + * zynqmp_pll_determine_rate() - Round a clock frequency * @hw: Handle between common and hardware-specific interfaces - * @rate: Desired clock frequency - * @prate: Clock frequency of parent clock + * @req: Desired clock frequency * * Return: Frequency closest to @rate the hardware can generate */ From 012e012e4917da06b512a3074980c3091949befa Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 28 Jan 2026 16:43:07 +0100 Subject: [PATCH 155/165] clk: qcom: sm8750: Constify 'qcom_cc_desc' in SM8750 camcc 'struct qcom_cc_desc' is passed to qcom_cc_map() and qcom_cc_really_probe() only as pointer to const, so make the memory const for safety. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Taniya Das Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20260128154306.133047-2-krzysztof.kozlowski@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/cambistmclkcc-sm8750.c | 2 +- drivers/clk/qcom/camcc-sm8750.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/cambistmclkcc-sm8750.c b/drivers/clk/qcom/cambistmclkcc-sm8750.c index 952581f86db5..d889a8f6561d 100644 --- a/drivers/clk/qcom/cambistmclkcc-sm8750.c +++ b/drivers/clk/qcom/cambistmclkcc-sm8750.c @@ -421,7 +421,7 @@ static struct qcom_cc_driver_data cam_bist_mclk_cc_sm8750_driver_data = { .num_clk_cbcrs = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_critical_cbcrs), }; -static struct qcom_cc_desc cam_bist_mclk_cc_sm8750_desc = { +static const struct qcom_cc_desc cam_bist_mclk_cc_sm8750_desc = { .config = &cam_bist_mclk_cc_sm8750_regmap_config, .clks = cam_bist_mclk_cc_sm8750_clocks, .num_clks = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_clocks), diff --git a/drivers/clk/qcom/camcc-sm8750.c b/drivers/clk/qcom/camcc-sm8750.c index c09fa75be457..a797b783d4a9 100644 --- a/drivers/clk/qcom/camcc-sm8750.c +++ b/drivers/clk/qcom/camcc-sm8750.c @@ -2673,7 +2673,7 @@ static struct qcom_cc_driver_data cam_cc_sm8750_driver_data = { .num_clk_cbcrs = ARRAY_SIZE(cam_cc_sm8750_critical_cbcrs), }; -static struct qcom_cc_desc cam_cc_sm8750_desc = { +static const struct qcom_cc_desc cam_cc_sm8750_desc = { .config = &cam_cc_sm8750_regmap_config, .clks = cam_cc_sm8750_clocks, .num_clks = ARRAY_SIZE(cam_cc_sm8750_clocks), From 5ec820fc28d0b8a0f3890d476b1976f20e8343cc Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 22 Jan 2026 00:26:38 +0100 Subject: [PATCH 156/165] clk: rs9: Reserve 8 struct clk_hw slots for for 9FGV0841 The 9FGV0841 has 8 outputs and registers 8 struct clk_hw, make sure there are 8 slots for those newly registered clk_hw pointers, else there is going to be out of bounds write when pointers 4..7 are set into struct rs9_driver_data .clk_dif[4..7] field. Since there are other structure members past this struct clk_hw pointer array, writing to .clk_dif[4..7] fields corrupts both the struct rs9_driver_data content and data around it, sometimes without crashing the kernel. However, the kernel does surely crash when the driver is unbound or during suspend. Fix this, increase the struct clk_hw pointer array size to the maximum output count of 9FGV0841, which is the biggest chip that is supported by this driver. Cc: stable@vger.kernel.org Fixes: f0e5e1800204 ("clk: rs9: Add support for 9FGV0841") Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Reported-by: Geert Uytterhoeven Closes: https://lore.kernel.org/CAMuHMdVyQpOBT+Ho+mXY07fndFN9bKJdaaWGn91WOFnnYErLyg@mail.gmail.com Signed-off-by: Marek Vasut Signed-off-by: Stephen Boyd --- drivers/clk/clk-renesas-pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c index 4c3a5e4eb77a..f94a9c4d0b67 100644 --- a/drivers/clk/clk-renesas-pcie.c +++ b/drivers/clk/clk-renesas-pcie.c @@ -64,7 +64,7 @@ struct rs9_driver_data { struct i2c_client *client; struct regmap *regmap; const struct rs9_chip_info *chip_info; - struct clk_hw *clk_dif[4]; + struct clk_hw *clk_dif[8]; u8 pll_amplitude; u8 pll_ssc; u8 clk_dif_sr; From 37eb3349a34f98fc22dd6f6be0b28c24cfa66aa6 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 21 Jan 2026 12:03:11 +0100 Subject: [PATCH 157/165] clk: rs9: Convert to DEFINE_SIMPLE_DEV_PM_OPS() Convert the Renesas 9-series PCIe clock generator driver from SIMPLE_DEV_PM_OPS() to DEFINE_SIMPLE_DEV_PM_OPS() and pm_sleep_ptr(). This lets us drop the __maybe_unused annotations from its suspend and resume callbacks, and reduces kernel size in case CONFIG_PM or CONFIG_PM_SLEEP is disabled. Signed-off-by: Geert Uytterhoeven Reviewed-by: Brian Masney Signed-off-by: Stephen Boyd --- drivers/clk/clk-renesas-pcie.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c index f94a9c4d0b67..aa108df12e44 100644 --- a/drivers/clk/clk-renesas-pcie.c +++ b/drivers/clk/clk-renesas-pcie.c @@ -354,7 +354,7 @@ static int rs9_probe(struct i2c_client *client) return ret; } -static int __maybe_unused rs9_suspend(struct device *dev) +static int rs9_suspend(struct device *dev) { struct rs9_driver_data *rs9 = dev_get_drvdata(dev); @@ -364,7 +364,7 @@ static int __maybe_unused rs9_suspend(struct device *dev) return 0; } -static int __maybe_unused rs9_resume(struct device *dev) +static int rs9_resume(struct device *dev) { struct rs9_driver_data *rs9 = dev_get_drvdata(dev); int ret; @@ -410,12 +410,12 @@ static const struct of_device_id clk_rs9_of_match[] = { }; MODULE_DEVICE_TABLE(of, clk_rs9_of_match); -static SIMPLE_DEV_PM_OPS(rs9_pm_ops, rs9_suspend, rs9_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(rs9_pm_ops, rs9_suspend, rs9_resume); static struct i2c_driver rs9_driver = { .driver = { .name = "clk-renesas-pcie-9series", - .pm = &rs9_pm_ops, + .pm = pm_sleep_ptr(&rs9_pm_ops), .of_match_table = clk_rs9_of_match, }, .probe = rs9_probe, From 341d72ebc2303670936713f5004a2825edc4e7ea Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 14 Oct 2025 12:46:03 +0200 Subject: [PATCH 158/165] dt-bindings: clk: rs9: Fix DIF pattern match The pattern match [0-19] is incorrect and does not cover range of 0..19, use pattern 1?[0-9] to cover range 0..19 instead. Update the example to validate all parts of the pattern match and prevent such failures in the future. Fixes: 26c1bc67aa2f ("dt-bindings: clk: rs9: Add Renesas 9-series I2C PCIe clock generator") Signed-off-by: Marek Vasut Reviewed-by: Conor Dooley Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/renesas,9series.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/renesas,9series.yaml b/Documentation/devicetree/bindings/clock/renesas,9series.yaml index af6319697b1c..a85f78ce2970 100644 --- a/Documentation/devicetree/bindings/clock/renesas,9series.yaml +++ b/Documentation/devicetree/bindings/clock/renesas,9series.yaml @@ -62,7 +62,7 @@ properties: description: Output clock down spread in pcm (1/1000 of percent) patternProperties: - "^DIF[0-19]$": + "^DIF1?[0-9]$": type: object description: Description of one of the outputs (DIF0..DIF19). @@ -107,6 +107,15 @@ examples: DIF0 { renesas,slew-rate = <3000000>; }; + + /* Not present on 9FGV0241, used for DT validation only */ + DIF2 { + renesas,slew-rate = <2000000>; + }; + + DIF19 { + renesas,slew-rate = <3000000>; + }; }; }; From b079e4e628c8866340cafedca9f7451dfc8fa263 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 22 Dec 2025 15:06:33 +0800 Subject: [PATCH 159/165] clk: Disable KUNIT_UML_PCI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 031cdd3bc3f3 ("kunit: Enable PCI on UML without triggering WARN()") enables KUNIT_UML_PCI, but clk driver could not work with it. Deselect KUNIT_UML_PCI to avoid the failure. Dump as below: WARNING: CPU: 0 PID: 227 at lib/logic_iomem.c:141 __raw_readl+0xac/0xe0 CPU: 0 UID: 0 PID: 227 Comm: kunit_try_catch Tainted: G Tainted: [N]=TEST Stack: a0883d00 00000001 00000000 ffffff00 603ef142 60044832 6002598b 00000000 00000000 600211b3 00000001 00000000 Call Trace: [<6032534c>] ? __raw_readl+0xac/0xe0 [<60044832>] ? dump_stack_lvl+0x57/0x73 [<6002598b>] ? _printk+0x0/0x61 [<600211b3>] ? __warn.cold+0x61/0xeb [<600212cc>] ? warn_slowpath_fmt+0x8f/0x9c [<6002123d>] ? warn_slowpath_fmt+0x0/0x9c [<6032534c>] ? __raw_readl+0xac/0xe0 [<6002123d>] ? warn_slowpath_fmt+0x0/0x9c [<6029e2ad>] ? clk_gate_endisable+0xcd/0x110 [<6029e315>] ? clk_gate_enable+0x15/0x20 [<6028795e>] ? clk_core_enable+0x6e/0xf0 [<60289f1f>] ? clk_enable+0x4f/0xa0 [<602a06af>] ? clk_gate_test_enable+0xbf/0x360 [<60053df9>] ? os_nsecs+0x29/0x40 [<600cd300>] ? ktime_get_ts64+0x0/0x130 [<600816c0>] ? to_kthread+0x0/0x50 [<602507bb>] ? kunit_try_run_case+0x7b/0x100 [<600816c0>] ? to_kthread+0x0/0x50 [<60252aa0>] ? kunit_generic_run_threadfn_adapter+0x0/0x30 [<60252ab2>] ? kunit_generic_run_threadfn_adapter+0x12/0x30 [<60082091>] ? kthread+0xf1/0x270 [<60047591>] ? new_thread_handler+0x41/0x60 ---[ end trace 0000000000000000 ]--- Reviewed-by: Thomas Weißschuh Signed-off-by: Peng Fan Signed-off-by: Stephen Boyd --- drivers/clk/.kunitconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/.kunitconfig b/drivers/clk/.kunitconfig index 08e26137f3d9..8a0ea41934a2 100644 --- a/drivers/clk/.kunitconfig +++ b/drivers/clk/.kunitconfig @@ -1,4 +1,5 @@ CONFIG_KUNIT=y +CONFIG_KUNIT_UML_PCI=n CONFIG_OF=y CONFIG_OF_OVERLAY=y CONFIG_COMMON_CLK=y @@ -6,4 +7,3 @@ CONFIG_CLK_KUNIT_TEST=y CONFIG_CLK_FIXED_RATE_KUNIT_TEST=y CONFIG_CLK_GATE_KUNIT_TEST=y CONFIG_CLK_FD_KUNIT_TEST=y -CONFIG_UML_PCI_OVER_VIRTIO=n From 448b50b5cf12b7df254cae1d7ba3746e1acfc683 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 28 Jan 2026 11:01:34 -0800 Subject: [PATCH 160/165] Revert "clk: Respect CLK_OPS_PARENT_ENABLE during recalc" This reverts commit 669917676e93fca5ea3c66fc9539830312bec58e. It's been shown to cause problems on i.MX and STM32 platforms where the board doesn't boot. In one case, a clk with CLK_IS_CRITICAL and CLK_OPS_PARENT_ENABLE is being registered causing the parent to be enabled, the rate recalculated, and then the parent is disabled causing the critical clk being registered to stop clocking. A fix for that would be to calculate the rate of the clk after enabling the critical clk itself, but that wouldn't fix another problem where a clk with CLK_OPS_PARENT_ENABLE is registered before the parent is registered. In this case the hardware access in the clk_ops::recalc_rate() function would fail if the parent is disabled. There are even more problems exposed by this patch because it introduces logic that disables clks earlier in system boot than has existed previously. Historically we've not disabled clks until late init (clk_disable_unused) under the assumption that clks have been registered enough to have a consistent view of the clk tree. The clk_disable_unused logic doesn't work very well though, leading to quite a few devices booting with clk_ignore_unused on the kernel command line. Long story short, disabling clks during clk registration is full of pitfalls. Revert this commit until a proper solution can be found. Reported-by: Alexander Stein Closes: https://lore.kernel.org/r/6239343.lOV4Wx5bFT@steina-w Reported-by: Mark Brown Closes: https://lore.kernel.org/r/036da7ce-6487-4a6e-9b15-97c6d3bcdcec@sirena.org.uk Cc: Nicolas Frattaroli Cc: Brian Masney Cc: AngeloGioacchino Del Regno Cc: Chen-Yu Tsai Tested-by: Peng Fan Tested-by: Alexander Stein Reviewed-by: Brian Masney Tested-by: Mark Brown Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 1b0f9d567f48..85d2f2481acf 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1921,14 +1921,7 @@ static unsigned long clk_recalc(struct clk_core *core, unsigned long rate = parent_rate; if (core->ops->recalc_rate && !clk_pm_runtime_get(core)) { - if (core->flags & CLK_OPS_PARENT_ENABLE) - clk_core_prepare_enable(core->parent); - rate = core->ops->recalc_rate(core->hw, parent_rate); - - if (core->flags & CLK_OPS_PARENT_ENABLE) - clk_core_disable_unprepare(core->parent); - clk_pm_runtime_put(core); } return rate; @@ -4038,9 +4031,6 @@ static int __clk_core_init(struct clk_core *core) */ clk_core_update_duty_cycle_nolock(core); - if (core->flags & CLK_OPS_PARENT_ENABLE) - clk_core_prepare_enable(core->parent); - /* * Set clk's rate. The preferred method is to use .recalc_rate. For * simple clocks and lazy developers the default fallback is to use the @@ -4056,9 +4046,6 @@ static int __clk_core_init(struct clk_core *core) rate = 0; core->rate = core->req_rate = rate; - if (core->flags & CLK_OPS_PARENT_ENABLE) - clk_core_disable_unprepare(core->parent); - /* * Enable CLK_IS_CRITICAL clocks so newly added critical clocks * don't get accidentally disabled when walking the orphan tree and From 03b3faa12c25140d00f9dca4ed44a6184600d9d8 Mon Sep 17 00:00:00 2001 From: Ryan Chen Date: Wed, 24 Dec 2025 13:37:22 +0800 Subject: [PATCH 161/165] clk: aspeed: Move the existing ASPEED clk drivers into aspeed subdirectory. Prepare for long-term maintenance and future additions by introducing a dedicated drivers/clk/aspeed/ subdirectory for ASPEED clock drivers. Move the existing ASPEED clock drivers into the new drivers/clk/aspeed/ subdirectory. No functional change, file move only. Signed-off-by: Ryan Chen Reviewed-by: Brian Masney Signed-off-by: Stephen Boyd --- drivers/clk/Kconfig | 13 +------------ drivers/clk/Makefile | 3 +-- drivers/clk/aspeed/Kconfig | 13 +++++++++++++ drivers/clk/aspeed/Makefile | 3 +++ drivers/clk/{ => aspeed}/clk-aspeed.c | 0 drivers/clk/{ => aspeed}/clk-aspeed.h | 0 drivers/clk/{ => aspeed}/clk-ast2600.c | 0 7 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 drivers/clk/aspeed/Kconfig create mode 100644 drivers/clk/aspeed/Makefile rename drivers/clk/{ => aspeed}/clk-aspeed.c (100%) rename drivers/clk/{ => aspeed}/clk-aspeed.h (100%) rename drivers/clk/{ => aspeed}/clk-ast2600.c (100%) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 3a1611008e48..c46920649c97 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -284,18 +284,6 @@ config COMMON_CLK_LAN966X LAN966X SoC. GCK generates and supplies clock to various peripherals within the SoC. -config COMMON_CLK_ASPEED - bool "Clock driver for Aspeed BMC SoCs" - depends on ARCH_ASPEED || COMPILE_TEST - default ARCH_ASPEED - select MFD_SYSCON - select RESET_CONTROLLER - help - This driver supports the SoC clocks on the Aspeed BMC platforms. - - The G4 and G5 series, including the ast2400 and ast2500, are supported - by this driver. - config COMMON_CLK_S2MPS11 tristate "Clock driver for S2MPS1X/S5M8767 MFD" depends on MFD_SEC_CORE || COMPILE_TEST @@ -513,6 +501,7 @@ config COMMON_CLK_RPMI source "drivers/clk/actions/Kconfig" source "drivers/clk/analogbits/Kconfig" +source "drivers/clk/aspeed/Kconfig" source "drivers/clk/baikal-t1/Kconfig" source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 61ec08404442..f7bce3951a30 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -62,8 +62,6 @@ obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o obj-$(CONFIG_COMMON_CLK_FSL_FLEXSPI) += clk-fsl-flexspi.o obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o -obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o -obj-$(CONFIG_MACH_ASPEED_G6) += clk-ast2600.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o obj-$(CONFIG_COMMON_CLK_K210) += clk-k210.o @@ -114,6 +112,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 += aspeed/ obj-$(CONFIG_COMMON_CLK_AT91) += at91/ obj-$(CONFIG_ARCH_ARTPEC) += axis/ obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/ diff --git a/drivers/clk/aspeed/Kconfig b/drivers/clk/aspeed/Kconfig new file mode 100644 index 000000000000..c59b0a1f581c --- /dev/null +++ b/drivers/clk/aspeed/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config COMMON_CLK_ASPEED + bool "Clock driver for Aspeed BMC SoCs" + depends on ARCH_ASPEED || COMPILE_TEST + default ARCH_ASPEED + select MFD_SYSCON + select RESET_CONTROLLER + help + This driver supports the SoC clocks on the Aspeed BMC platforms. + + The G4 and G5 series, including the ast2400 and ast2500, are supported + by this driver. diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile new file mode 100644 index 000000000000..7db136b89b1e --- /dev/null +++ b/drivers/clk/aspeed/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o +obj-$(CONFIG_MACH_ASPEED_G6) += clk-ast2600.o diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/aspeed/clk-aspeed.c similarity index 100% rename from drivers/clk/clk-aspeed.c rename to drivers/clk/aspeed/clk-aspeed.c diff --git a/drivers/clk/clk-aspeed.h b/drivers/clk/aspeed/clk-aspeed.h similarity index 100% rename from drivers/clk/clk-aspeed.h rename to drivers/clk/aspeed/clk-aspeed.h diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/aspeed/clk-ast2600.c similarity index 100% rename from drivers/clk/clk-ast2600.c rename to drivers/clk/aspeed/clk-ast2600.c From 122c157c4808f79bfe2d1786b59479fead43ad92 Mon Sep 17 00:00:00 2001 From: Ryan Chen Date: Wed, 24 Dec 2025 13:37:23 +0800 Subject: [PATCH 162/165] MAINTAINERS: Add entry for ASPEED clock drivers. Add support entry for ASPEED clock drivers. Signed-off-by: Ryan Chen Reviewed-by: Brian Masney Signed-off-by: Stephen Boyd --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 5b11839cba9d..201ff5d5c31c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3836,6 +3836,15 @@ L: rust-for-linux@vger.kernel.org S: Maintained F: drivers/net/phy/ax88796b_rust.rs +ARM/ASPEED CLOCK SUPPORT +M: Ryan Chen +R: Joel Stanley +L: linux-clk@vger.kernel.org +L: linux-aspeed@lists.ozlabs.org +S: Maintained +F: Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml +F: drivers/clk/aspeed/ + ASPEED CRYPTO DRIVER M: Neal Liu L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) From fdc1eb624ddc2876079ce30218eed971b7953280 Mon Sep 17 00:00:00 2001 From: Ryan Chen Date: Wed, 24 Dec 2025 13:37:24 +0800 Subject: [PATCH 163/165] clk: aspeed: add AST2700 clock driver Add AST2700 clock controller driver and also use axiliary device framework register the reset controller driver. Due to clock and reset using the same register region. Signed-off-by: Ryan Chen Reviewed-by: Brian Masney Signed-off-by: Stephen Boyd --- drivers/clk/aspeed/Kconfig | 8 + drivers/clk/aspeed/Makefile | 1 + drivers/clk/aspeed/clk-ast2700.c | 1055 ++++++++++++++++++++++++++++++ 3 files changed, 1064 insertions(+) create mode 100644 drivers/clk/aspeed/clk-ast2700.c diff --git a/drivers/clk/aspeed/Kconfig b/drivers/clk/aspeed/Kconfig index c59b0a1f581c..ef50481c31ff 100644 --- a/drivers/clk/aspeed/Kconfig +++ b/drivers/clk/aspeed/Kconfig @@ -11,3 +11,11 @@ config COMMON_CLK_ASPEED The G4 and G5 series, including the ast2400 and ast2500, are supported by this driver. + +config COMMON_CLK_AST2700 + bool "Clock driver for AST2700 SoC" + depends on ARCH_ASPEED || COMPILE_TEST + help + This driver provides support for clock on AST2700 SoC. + The driver is responsible for managing the various clocks required + by the peripherals and cores within the AST2700. diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile index 7db136b89b1e..eb5d219f738d 100644 --- a/drivers/clk/aspeed/Makefile +++ b/drivers/clk/aspeed/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o obj-$(CONFIG_MACH_ASPEED_G6) += clk-ast2600.o +obj-$(CONFIG_COMMON_CLK_AST2700) += clk-ast2700.o diff --git a/drivers/clk/aspeed/clk-ast2700.c b/drivers/clk/aspeed/clk-ast2700.c new file mode 100644 index 000000000000..bbb2b571eb72 --- /dev/null +++ b/drivers/clk/aspeed/clk-ast2700.c @@ -0,0 +1,1055 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 ASPEED Technology Inc. + * Author: Ryan Chen + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* SOC0 */ +#define SCU0_HWSTRAP1 0x010 +#define SCU0_CLK_STOP 0x240 +#define SCU0_CLK_SEL1 0x280 +#define SCU0_CLK_SEL2 0x284 +#define GET_USB_REFCLK_DIV(x) ((GENMASK(23, 20) & (x)) >> 20) +#define UART_DIV13_EN BIT(30) +#define SCU0_HPLL_PARAM 0x300 +#define SCU0_DPLL_PARAM 0x308 +#define SCU0_MPLL_PARAM 0x310 +#define SCU0_D0CLK_PARAM 0x320 +#define SCU0_D1CLK_PARAM 0x330 +#define SCU0_CRT0CLK_PARAM 0x340 +#define SCU0_CRT1CLK_PARAM 0x350 +#define SCU0_MPHYCLK_PARAM 0x360 + +/* SOC1 */ +#define SCU1_REVISION_ID 0x0 +#define REVISION_ID GENMASK(23, 16) +#define SCU1_CLK_STOP 0x240 +#define SCU1_CLK_STOP2 0x260 +#define SCU1_CLK_SEL1 0x280 +#define SCU1_CLK_SEL2 0x284 +#define SCU1_CLK_I3C_DIV_MASK GENMASK(25, 23) +#define SCU1_CLK_I3C_DIV(n) ((n) - 1) +#define UXCLK_MASK GENMASK(1, 0) +#define HUXCLK_MASK GENMASK(4, 3) +#define SCU1_HPLL_PARAM 0x300 +#define SCU1_APLL_PARAM 0x310 +#define SCU1_DPLL_PARAM 0x320 +#define SCU1_UXCLK_CTRL 0x330 +#define SCU1_HUXCLK_CTRL 0x334 +#define SCU1_MAC12_CLK_DLY 0x390 +#define SCU1_MAC12_CLK_DLY_100M 0x394 +#define SCU1_MAC12_CLK_DLY_10M 0x398 + +enum ast2700_clk_type { + CLK_MUX, + CLK_PLL, + CLK_HPLL, + CLK_GATE, + CLK_MISC, + CLK_FIXED, + CLK_DIVIDER, + CLK_UART_PLL, + CLK_GATE_ASPEED, + CLK_FIXED_FACTOR, + CLK_FIXED_DISPLAY, +}; + +struct ast2700_clk_fixed_factor_data { + unsigned int mult; + unsigned int div; + int parent_id; +}; + +struct ast2700_clk_gate_data { + int parent_id; + u32 flags; + u32 reg; + u8 bit; +}; + +struct ast2700_clk_mux_data { + const struct clk_hw **parent_hws; + const unsigned int *parent_ids; + unsigned int num_parents; + u8 bit_shift; + u8 bit_width; + u32 reg; +}; + +struct ast2700_clk_div_data { + const struct clk_div_table *div_table; + unsigned int parent_id; + u8 bit_shift; + u8 bit_width; + u32 reg; +}; + +struct ast2700_clk_pll_data { + unsigned int parent_id; + u32 reg; +}; + +struct ast2700_clk_fixed_rate_data { + unsigned long fixed_rate; +}; + +struct ast2700_clk_display_fixed_data { + u32 reg; +}; + +struct ast2700_clk_info { + const char *name; + u32 id; + u32 reg; + u32 type; + union { + struct ast2700_clk_fixed_factor_data factor; + struct ast2700_clk_fixed_rate_data rate; + struct ast2700_clk_display_fixed_data display_rate; + struct ast2700_clk_gate_data gate; + struct ast2700_clk_div_data div; + struct ast2700_clk_pll_data pll; + struct ast2700_clk_mux_data mux; + } data; +}; + +struct ast2700_clk_data { + const struct ast2700_clk_info *clk_info; + unsigned int nr_clks; + const int scu; +}; + +struct ast2700_clk_ctrl { + const struct ast2700_clk_data *clk_data; + struct device *dev; + void __iomem *base; + spinlock_t lock; /* clk lock */ +}; + +static const struct clk_div_table ast2700_rgmii_div_table[] = { + { 0x0, 4 }, + { 0x1, 4 }, + { 0x2, 6 }, + { 0x3, 8 }, + { 0x4, 10 }, + { 0x5, 12 }, + { 0x6, 14 }, + { 0x7, 16 }, + { 0 } +}; + +static const struct clk_div_table ast2700_rmii_div_table[] = { + { 0x0, 8 }, + { 0x1, 8 }, + { 0x2, 12 }, + { 0x3, 16 }, + { 0x4, 20 }, + { 0x5, 24 }, + { 0x6, 28 }, + { 0x7, 32 }, + { 0 } +}; + +static const struct clk_div_table ast2700_clk_div_table[] = { + { 0x0, 2 }, + { 0x1, 2 }, + { 0x2, 3 }, + { 0x3, 4 }, + { 0x4, 5 }, + { 0x5, 6 }, + { 0x6, 7 }, + { 0x7, 8 }, + { 0 } +}; + +static const struct clk_div_table ast2700_clk_div_table2[] = { + { 0x0, 2 }, + { 0x1, 4 }, + { 0x2, 6 }, + { 0x3, 8 }, + { 0x4, 10 }, + { 0x5, 12 }, + { 0x6, 14 }, + { 0x7, 16 }, + { 0 } +}; + +static const struct clk_div_table ast2700_hclk_div_table[] = { + { 0x0, 6 }, + { 0x1, 5 }, + { 0x2, 4 }, + { 0x3, 7 }, + { 0 } +}; + +static const struct clk_div_table ast2700_clk_uart_div_table[] = { + { 0x0, 1 }, + { 0x1, 13 }, + { 0 } +}; + +/* soc 0 */ +static const unsigned int psp_parent_ids[] = { + SCU0_CLK_MPLL, + SCU0_CLK_HPLL, + SCU0_CLK_HPLL, + SCU0_CLK_HPLL, + SCU0_CLK_MPLL_DIV2, + SCU0_CLK_HPLL_DIV2, + SCU0_CLK_HPLL, + SCU0_CLK_HPLL +}; + +static const struct clk_hw *psp_parent_hws[ARRAY_SIZE(psp_parent_ids)]; + +static const unsigned int hclk_parent_ids[] = { + SCU0_CLK_HPLL, + SCU0_CLK_MPLL +}; + +static const struct clk_hw *hclk_parent_hws[ARRAY_SIZE(hclk_parent_ids)]; + +static const unsigned int emmc_parent_ids[] = { + SCU0_CLK_MPLL_DIV4, + SCU0_CLK_HPLL_DIV4 +}; + +static const struct clk_hw *emmc_parent_hws[ARRAY_SIZE(emmc_parent_ids)]; + +static const unsigned int mphy_parent_ids[] = { + SCU0_CLK_MPLL, + SCU0_CLK_HPLL, + SCU0_CLK_DPLL, + SCU0_CLK_192M +}; + +static const struct clk_hw *mphy_parent_hws[ARRAY_SIZE(mphy_parent_ids)]; + +static const unsigned int u2phy_parent_ids[] = { + SCU0_CLK_MPLL, + SCU0_CLK_HPLL +}; + +static const struct clk_hw *u2phy_parent_hws[ARRAY_SIZE(u2phy_parent_ids)]; + +static const unsigned int uart_parent_ids[] = { + SCU0_CLK_24M, + SCU0_CLK_192M +}; + +static const struct clk_hw *uart_parent_hws[ARRAY_SIZE(uart_parent_ids)]; + +/* soc 1 */ +static const unsigned int uartx_parent_ids[] = { + SCU1_CLK_UARTX, + SCU1_CLK_HUARTX +}; + +static const struct clk_hw *uartx_parent_hws[ARRAY_SIZE(uartx_parent_ids)]; + +static const unsigned int uxclk_parent_ids[] = { + SCU1_CLK_APLL_DIV4, + SCU1_CLK_APLL_DIV2, + SCU1_CLK_APLL, + SCU1_CLK_HPLL +}; + +static const struct clk_hw *uxclk_parent_hws[ARRAY_SIZE(uxclk_parent_ids)]; + +static const unsigned int sdclk_parent_ids[] = { + SCU1_CLK_HPLL, + SCU1_CLK_APLL +}; + +static const struct clk_hw *sdclk_parent_hws[ARRAY_SIZE(sdclk_parent_ids)]; + +#define FIXED_CLK(_id, _name, _rate) \ + { \ + .id = _id, \ + .type = CLK_FIXED, \ + .name = _name, \ + .data = { .rate = { .fixed_rate = _rate, } }, \ + } + +#define FIXED_DISPLAY_CLK(_id, _name, _reg) \ + { \ + .id = _id, \ + .type = CLK_FIXED_DISPLAY, \ + .name = _name, \ + .data = { .display_rate = { .reg = _reg } }, \ + } + +#define PLL_CLK(_id, _type, _name, _parent_id, _reg) \ + { \ + .id = _id, \ + .type = _type, \ + .name = _name, \ + .data = { .pll = { \ + .parent_id = _parent_id, \ + .reg = _reg, \ + } }, \ + } + +#define MUX_CLK(_id, _name, _parent_ids, _num_parents, _parent_hws, _reg, _shift, _width) \ + { \ + .id = _id, \ + .type = CLK_MUX, \ + .name = _name, \ + .data = { \ + .mux = { \ + .parent_ids = _parent_ids, \ + .parent_hws = _parent_hws, \ + .num_parents = _num_parents, \ + .reg = (_reg), \ + .bit_shift = _shift, \ + .bit_width = _width, \ + }, \ + }, \ + } + +#define DIVIDER_CLK(_id, _name, _parent_id, _reg, _shift, _width, _div_table) \ + { \ + .id = _id, \ + .type = CLK_DIVIDER, \ + .name = _name, \ + .data = { \ + .div = { \ + .parent_id = _parent_id, \ + .reg = _reg, \ + .bit_shift = _shift, \ + .bit_width = _width, \ + .div_table = _div_table, \ + }, \ + }, \ + } + +#define FIXED_FACTOR_CLK(_id, _name, _parent_id, _mult, _div) \ + { \ + .id = _id, \ + .type = CLK_FIXED_FACTOR, \ + .name = _name, \ + .data = { .factor = { .parent_id = _parent_id, .mult = _mult, .div = _div, } }, \ + } + +#define GATE_CLK(_id, _type, _name, _parent_id, _reg, _bit, _flags) \ + { \ + .id = _id, \ + .type = _type, \ + .name = _name, \ + .data = { \ + .gate = { \ + .parent_id = _parent_id, \ + .reg = _reg, \ + .bit = _bit, \ + .flags = _flags, \ + }, \ + }, \ + } + +static const struct ast2700_clk_info ast2700_scu0_clk_info[] __initconst = { + FIXED_CLK(SCU0_CLKIN, "soc0-clkin", 25 * HZ_PER_MHZ), + FIXED_CLK(SCU0_CLK_24M, "soc0-clk24Mhz", 24 * HZ_PER_MHZ), + FIXED_CLK(SCU0_CLK_192M, "soc0-clk192Mhz", 192 * HZ_PER_MHZ), + FIXED_CLK(SCU0_CLK_U2PHY_CLK12M, "u2phy_clk12m", 12 * HZ_PER_MHZ), + FIXED_DISPLAY_CLK(SCU0_CLK_D0, "d0clk", SCU0_D0CLK_PARAM), + FIXED_DISPLAY_CLK(SCU0_CLK_D1, "d1clk", SCU0_D1CLK_PARAM), + FIXED_DISPLAY_CLK(SCU0_CLK_CRT0, "crt0clk", SCU0_CRT0CLK_PARAM), + FIXED_DISPLAY_CLK(SCU0_CLK_CRT1, "crt1clk", SCU0_CRT1CLK_PARAM), + PLL_CLK(SCU0_CLK_HPLL, CLK_HPLL, "soc0-hpll", SCU0_CLKIN, SCU0_HPLL_PARAM), + PLL_CLK(SCU0_CLK_DPLL, CLK_PLL, "soc0-dpll", SCU0_CLKIN, SCU0_DPLL_PARAM), + PLL_CLK(SCU0_CLK_MPLL, CLK_PLL, "soc0-mpll", SCU0_CLKIN, SCU0_MPLL_PARAM), + FIXED_FACTOR_CLK(SCU0_CLK_HPLL_DIV2, "soc0-hpll_div2", SCU0_CLK_HPLL, 1, 2), + FIXED_FACTOR_CLK(SCU0_CLK_HPLL_DIV4, "soc0-hpll_div4", SCU0_CLK_HPLL, 1, 4), + FIXED_FACTOR_CLK(SCU0_CLK_MPLL_DIV2, "soc0-mpll_div2", SCU0_CLK_MPLL, 1, 2), + FIXED_FACTOR_CLK(SCU0_CLK_MPLL_DIV4, "soc0-mpll_div4", SCU0_CLK_MPLL, 1, 4), + FIXED_FACTOR_CLK(SCU0_CLK_MPLL_DIV8, "soc0-mpll_div8", SCU0_CLK_MPLL, 1, 8), + FIXED_FACTOR_CLK(SCU0_CLK_AXI1, "axi1clk", SCU0_CLK_MPLL, 1, 4), + MUX_CLK(SCU0_CLK_PSP, "pspclk", psp_parent_ids, ARRAY_SIZE(psp_parent_ids), + psp_parent_hws, SCU0_HWSTRAP1, 2, 3), + FIXED_FACTOR_CLK(SCU0_CLK_AXI0, "axi0clk", SCU0_CLK_PSP, 1, 2), + MUX_CLK(SCU0_CLK_AHBMUX, "soc0-ahbmux", hclk_parent_ids, ARRAY_SIZE(hclk_parent_ids), + hclk_parent_hws, SCU0_HWSTRAP1, 7, 1), + MUX_CLK(SCU0_CLK_EMMCMUX, "emmcsrc-mux", emmc_parent_ids, ARRAY_SIZE(emmc_parent_ids), + emmc_parent_hws, SCU0_CLK_SEL1, 11, 1), + MUX_CLK(SCU0_CLK_MPHYSRC, "mphysrc", mphy_parent_ids, ARRAY_SIZE(mphy_parent_ids), + mphy_parent_hws, SCU0_CLK_SEL2, 18, 2), + MUX_CLK(SCU0_CLK_U2PHY_REFCLKSRC, "u2phy_refclksrc", u2phy_parent_ids, + ARRAY_SIZE(u2phy_parent_ids), u2phy_parent_hws, SCU0_CLK_SEL2, 23, 1), + MUX_CLK(SCU0_CLK_UART, "soc0-uartclk", uart_parent_ids, ARRAY_SIZE(uart_parent_ids), + uart_parent_hws, SCU0_CLK_SEL2, 14, 1), + PLL_CLK(SCU0_CLK_MPHY, CLK_MISC, "mphyclk", SCU0_CLK_MPHYSRC, SCU0_MPHYCLK_PARAM), + PLL_CLK(SCU0_CLK_U2PHY_REFCLK, CLK_MISC, "u2phy_refclk", SCU0_CLK_U2PHY_REFCLKSRC, + SCU0_CLK_SEL2), + DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", SCU0_CLK_AHBMUX, + SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table), + DIVIDER_CLK(SCU0_CLK_EMMC, "emmcclk", SCU0_CLK_EMMCMUX, + SCU0_CLK_SEL1, 12, 3, ast2700_clk_div_table2), + DIVIDER_CLK(SCU0_CLK_APB, "soc0-apb", SCU0_CLK_AXI0, + SCU0_CLK_SEL1, 23, 3, ast2700_clk_div_table2), + DIVIDER_CLK(SCU0_CLK_HPLL_DIV_AHB, "soc0-hpll-ahb", SCU0_CLK_HPLL, + SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table), + DIVIDER_CLK(SCU0_CLK_MPLL_DIV_AHB, "soc0-mpll-ahb", SCU0_CLK_MPLL, + SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table), + DIVIDER_CLK(SCU0_CLK_UART4, "uart4clk", SCU0_CLK_UART, + SCU0_CLK_SEL2, 30, 1, ast2700_clk_uart_div_table), + GATE_CLK(SCU0_CLK_GATE_MCLK, CLK_GATE_ASPEED, "mclk-gate", SCU0_CLK_MPLL, + SCU0_CLK_STOP, 0, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_ECLK, CLK_GATE_ASPEED, "eclk-gate", -1, SCU0_CLK_STOP, 1, 0), + GATE_CLK(SCU0_CLK_GATE_2DCLK, CLK_GATE_ASPEED, "gclk-gate", -1, SCU0_CLK_STOP, 2, 0), + GATE_CLK(SCU0_CLK_GATE_VCLK, CLK_GATE_ASPEED, "vclk-gate", -1, SCU0_CLK_STOP, 3, 0), + GATE_CLK(SCU0_CLK_GATE_BCLK, CLK_GATE_ASPEED, "bclk-gate", -1, + SCU0_CLK_STOP, 4, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_VGA0CLK, CLK_GATE_ASPEED, "vga0clk-gate", -1, + SCU0_CLK_STOP, 5, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_REFCLK, CLK_GATE_ASPEED, "soc0-refclk-gate", SCU0_CLKIN, + SCU0_CLK_STOP, 6, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_PORTBUSB2CLK, CLK_GATE_ASPEED, "portb-usb2clk-gate", -1, + SCU0_CLK_STOP, 7, 0), + GATE_CLK(SCU0_CLK_GATE_UHCICLK, CLK_GATE_ASPEED, "uhciclk-gate", -1, SCU0_CLK_STOP, 9, 0), + GATE_CLK(SCU0_CLK_GATE_VGA1CLK, CLK_GATE_ASPEED, "vga1clk-gate", -1, + SCU0_CLK_STOP, 10, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_DDRPHYCLK, CLK_GATE_ASPEED, "ddrphy-gate", -1, + SCU0_CLK_STOP, 11, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_E2M0CLK, CLK_GATE_ASPEED, "e2m0clk-gate", -1, + SCU0_CLK_STOP, 12, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_HACCLK, CLK_GATE_ASPEED, "hacclk-gate", -1, SCU0_CLK_STOP, 13, 0), + GATE_CLK(SCU0_CLK_GATE_PORTAUSB2CLK, CLK_GATE_ASPEED, "porta-usb2clk-gate", -1, + SCU0_CLK_STOP, 14, 0), + GATE_CLK(SCU0_CLK_GATE_UART4CLK, CLK_GATE_ASPEED, "uart4clk-gate", SCU0_CLK_UART4, + SCU0_CLK_STOP, 15, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_SLICLK, CLK_GATE_ASPEED, "soc0-sliclk-gate", -1, + SCU0_CLK_STOP, 16, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_DACCLK, CLK_GATE_ASPEED, "dacclk-gate", -1, + SCU0_CLK_STOP, 17, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_DP, CLK_GATE_ASPEED, "dpclk-gate", -1, + SCU0_CLK_STOP, 18, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_E2M1CLK, CLK_GATE_ASPEED, "e2m1clk-gate", -1, + SCU0_CLK_STOP, 19, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_CRT0CLK, CLK_GATE_ASPEED, "crt0clk-gate", -1, + SCU0_CLK_STOP, 20, 0), + GATE_CLK(SCU0_CLK_GATE_CRT1CLK, CLK_GATE_ASPEED, "crt1clk-gate", -1, + SCU0_CLK_STOP, 21, 0), + GATE_CLK(SCU0_CLK_GATE_ECDSACLK, CLK_GATE_ASPEED, "eccclk-gate", -1, + SCU0_CLK_STOP, 23, 0), + GATE_CLK(SCU0_CLK_GATE_RSACLK, CLK_GATE_ASPEED, "rsaclk-gate", -1, + SCU0_CLK_STOP, 24, 0), + GATE_CLK(SCU0_CLK_GATE_RVAS0CLK, CLK_GATE_ASPEED, "rvas0clk-gate", -1, + SCU0_CLK_STOP, 25, 0), + GATE_CLK(SCU0_CLK_GATE_UFSCLK, CLK_GATE_ASPEED, "ufsclk-gate", -1, + SCU0_CLK_STOP, 26, 0), + GATE_CLK(SCU0_CLK_GATE_EMMCCLK, CLK_GATE_ASPEED, "emmcclk-gate", SCU0_CLK_EMMC, + SCU0_CLK_STOP, 27, 0), + GATE_CLK(SCU0_CLK_GATE_RVAS1CLK, CLK_GATE_ASPEED, "rvas1clk-gate", -1, + SCU0_CLK_STOP, 28, 0), +}; + +static const struct ast2700_clk_info ast2700_scu1_clk_info[] __initconst = { + FIXED_CLK(SCU1_CLKIN, "soc1-clkin", 25 * HZ_PER_MHZ), + PLL_CLK(SCU1_CLK_HPLL, CLK_PLL, "soc1-hpll", SCU1_CLKIN, SCU1_HPLL_PARAM), + PLL_CLK(SCU1_CLK_APLL, CLK_PLL, "soc1-apll", SCU1_CLKIN, SCU1_APLL_PARAM), + PLL_CLK(SCU1_CLK_DPLL, CLK_PLL, "soc1-dpll", SCU1_CLKIN, SCU1_DPLL_PARAM), + FIXED_FACTOR_CLK(SCU1_CLK_APLL_DIV2, "soc1-apll_div2", SCU1_CLK_APLL, 1, 2), + FIXED_FACTOR_CLK(SCU1_CLK_APLL_DIV4, "soc1-apll_div4", SCU1_CLK_APLL, 1, 4), + FIXED_FACTOR_CLK(SCU1_CLK_CAN, "canclk", SCU1_CLK_APLL, 1, 10), + DIVIDER_CLK(SCU1_CLK_APB, "soc1-apb", SCU1_CLK_HPLL, + SCU1_CLK_SEL1, 18, 3, ast2700_clk_div_table2), + DIVIDER_CLK(SCU1_CLK_RMII, "rmii", SCU1_CLK_HPLL, + SCU1_CLK_SEL1, 21, 3, ast2700_rmii_div_table), + DIVIDER_CLK(SCU1_CLK_RGMII, "rgmii", SCU1_CLK_HPLL, + SCU1_CLK_SEL1, 25, 3, ast2700_rgmii_div_table), + DIVIDER_CLK(SCU1_CLK_MACHCLK, "machclk", SCU1_CLK_HPLL, + SCU1_CLK_SEL1, 29, 3, ast2700_clk_div_table), + DIVIDER_CLK(SCU1_CLK_APLL_DIVN, "soc1-apll_divn", + SCU1_CLK_APLL, SCU1_CLK_SEL2, 8, 3, ast2700_clk_div_table), + DIVIDER_CLK(SCU1_CLK_AHB, "soc1-ahb", SCU1_CLK_HPLL, + SCU1_CLK_SEL2, 20, 3, ast2700_clk_div_table), + DIVIDER_CLK(SCU1_CLK_I3C, "soc1-i3c", SCU1_CLK_HPLL, + SCU1_CLK_SEL2, 23, 3, ast2700_clk_div_table), + MUX_CLK(SCU1_CLK_SDMUX, "sdclk-mux", sdclk_parent_ids, ARRAY_SIZE(sdclk_parent_ids), + sdclk_parent_hws, SCU1_CLK_SEL1, 13, 1), + MUX_CLK(SCU1_CLK_UXCLK, "uxclk", uxclk_parent_ids, ARRAY_SIZE(uxclk_parent_ids), + uxclk_parent_hws, SCU1_CLK_SEL2, 0, 2), + MUX_CLK(SCU1_CLK_HUXCLK, "huxclk", uxclk_parent_ids, ARRAY_SIZE(uxclk_parent_ids), + uxclk_parent_hws, SCU1_CLK_SEL2, 3, 2), + DIVIDER_CLK(SCU1_CLK_SDCLK, "sdclk", SCU1_CLK_SDMUX, + SCU1_CLK_SEL1, 14, 3, ast2700_clk_div_table), + PLL_CLK(SCU1_CLK_UARTX, CLK_UART_PLL, "uartxclk", SCU1_CLK_UXCLK, SCU1_UXCLK_CTRL), + PLL_CLK(SCU1_CLK_HUARTX, CLK_UART_PLL, "huartxclk", SCU1_CLK_HUXCLK, SCU1_HUXCLK_CTRL), + MUX_CLK(SCU1_CLK_UART0, "uart0clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 0, 1), + MUX_CLK(SCU1_CLK_UART1, "uart1clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 1, 1), + MUX_CLK(SCU1_CLK_UART2, "uart2clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 2, 1), + MUX_CLK(SCU1_CLK_UART3, "uart3clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 3, 1), + MUX_CLK(SCU1_CLK_UART5, "uart5clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 5, 1), + MUX_CLK(SCU1_CLK_UART6, "uart6clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 6, 1), + MUX_CLK(SCU1_CLK_UART7, "uart7clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 7, 1), + MUX_CLK(SCU1_CLK_UART8, "uart8clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 8, 1), + MUX_CLK(SCU1_CLK_UART9, "uart9clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 9, 1), + MUX_CLK(SCU1_CLK_UART10, "uart10clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 10, 1), + MUX_CLK(SCU1_CLK_UART11, "uart11clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 11, 1), + MUX_CLK(SCU1_CLK_UART12, "uart12clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 12, 1), + FIXED_FACTOR_CLK(SCU1_CLK_UART13, "uart13clk", SCU1_CLK_HUARTX, 1, 1), + FIXED_FACTOR_CLK(SCU1_CLK_UART14, "uart14clk", SCU1_CLK_HUARTX, 1, 1), + GATE_CLK(SCU1_CLK_MAC0RCLK, CLK_GATE, "mac0rclk-gate", SCU1_CLK_RMII, + SCU1_MAC12_CLK_DLY, 29, 0), + GATE_CLK(SCU1_CLK_MAC1RCLK, CLK_GATE, "mac1rclk-gate", SCU1_CLK_RMII, + SCU1_MAC12_CLK_DLY, 30, 0), + GATE_CLK(SCU1_CLK_GATE_LCLK0, CLK_GATE_ASPEED, "lclk0-gate", -1, + SCU1_CLK_STOP, 0, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_LCLK1, CLK_GATE_ASPEED, "lclk1-gate", -1, + SCU1_CLK_STOP, 1, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_ESPI0CLK, CLK_GATE_ASPEED, "espi0clk-gate", -1, + SCU1_CLK_STOP, 2, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_ESPI1CLK, CLK_GATE_ASPEED, "espi1clk-gate", -1, + SCU1_CLK_STOP, 3, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_SDCLK, CLK_GATE_ASPEED, "sdclk-gate", SCU1_CLK_SDCLK, + SCU1_CLK_STOP, 4, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_IPEREFCLK, CLK_GATE_ASPEED, "soc1-iperefclk-gate", -1, + SCU1_CLK_STOP, 5, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_REFCLK, CLK_GATE_ASPEED, "soc1-refclk-gate", -1, + SCU1_CLK_STOP, 6, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_LPCHCLK, CLK_GATE_ASPEED, "lpchclk-gate", -1, + SCU1_CLK_STOP, 7, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_MAC0CLK, CLK_GATE_ASPEED, "mac0clk-gate", -1, + SCU1_CLK_STOP, 8, 0), + GATE_CLK(SCU1_CLK_GATE_MAC1CLK, CLK_GATE_ASPEED, "mac1clk-gate", -1, + SCU1_CLK_STOP, 9, 0), + GATE_CLK(SCU1_CLK_GATE_MAC2CLK, CLK_GATE_ASPEED, "mac2clk-gate", -1, + SCU1_CLK_STOP, 10, 0), + GATE_CLK(SCU1_CLK_GATE_UART0CLK, CLK_GATE_ASPEED, "uart0clk-gate", SCU1_CLK_UART0, + SCU1_CLK_STOP, 11, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART1CLK, CLK_GATE_ASPEED, "uart1clk-gate", SCU1_CLK_UART1, + SCU1_CLK_STOP, 12, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART2CLK, CLK_GATE_ASPEED, "uart2clk-gate", SCU1_CLK_UART2, + SCU1_CLK_STOP, 13, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART3CLK, CLK_GATE_ASPEED, "uart3clk-gate", SCU1_CLK_UART3, + SCU1_CLK_STOP, 14, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_I2CCLK, CLK_GATE_ASPEED, "i2cclk-gate", -1, SCU1_CLK_STOP, 15, 0), + GATE_CLK(SCU1_CLK_GATE_I3C0CLK, CLK_GATE_ASPEED, "i3c0clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 16, 0), + GATE_CLK(SCU1_CLK_GATE_I3C1CLK, CLK_GATE_ASPEED, "i3c1clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 17, 0), + GATE_CLK(SCU1_CLK_GATE_I3C2CLK, CLK_GATE_ASPEED, "i3c2clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 18, 0), + GATE_CLK(SCU1_CLK_GATE_I3C3CLK, CLK_GATE_ASPEED, "i3c3clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 19, 0), + GATE_CLK(SCU1_CLK_GATE_I3C4CLK, CLK_GATE_ASPEED, "i3c4clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 20, 0), + GATE_CLK(SCU1_CLK_GATE_I3C5CLK, CLK_GATE_ASPEED, "i3c5clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 21, 0), + GATE_CLK(SCU1_CLK_GATE_I3C6CLK, CLK_GATE_ASPEED, "i3c6clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 22, 0), + GATE_CLK(SCU1_CLK_GATE_I3C7CLK, CLK_GATE_ASPEED, "i3c7clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 23, 0), + GATE_CLK(SCU1_CLK_GATE_I3C8CLK, CLK_GATE_ASPEED, "i3c8clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 24, 0), + GATE_CLK(SCU1_CLK_GATE_I3C9CLK, CLK_GATE_ASPEED, "i3c9clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 25, 0), + GATE_CLK(SCU1_CLK_GATE_I3C10CLK, CLK_GATE_ASPEED, "i3c10clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 26, 0), + GATE_CLK(SCU1_CLK_GATE_I3C11CLK, CLK_GATE_ASPEED, "i3c11clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 27, 0), + GATE_CLK(SCU1_CLK_GATE_I3C12CLK, CLK_GATE_ASPEED, "i3c12clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 28, 0), + GATE_CLK(SCU1_CLK_GATE_I3C13CLK, CLK_GATE_ASPEED, "i3c13clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 29, 0), + GATE_CLK(SCU1_CLK_GATE_I3C14CLK, CLK_GATE_ASPEED, "i3c14clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 30, 0), + GATE_CLK(SCU1_CLK_GATE_I3C15CLK, CLK_GATE_ASPEED, "i3c15clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 31, 0), + GATE_CLK(SCU1_CLK_GATE_UART5CLK, CLK_GATE_ASPEED, "uart5clk-gate", SCU1_CLK_UART5, + SCU1_CLK_STOP2, 0, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART6CLK, CLK_GATE_ASPEED, "uart6clk-gate", SCU1_CLK_UART6, + SCU1_CLK_STOP2, 1, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART7CLK, CLK_GATE_ASPEED, "uart7clk-gate", SCU1_CLK_UART7, + SCU1_CLK_STOP2, 2, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART8CLK, CLK_GATE_ASPEED, "uart8clk-gate", SCU1_CLK_UART8, + SCU1_CLK_STOP2, 3, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART9CLK, CLK_GATE_ASPEED, "uart9clk-gate", SCU1_CLK_UART9, + SCU1_CLK_STOP2, 4, 0), + GATE_CLK(SCU1_CLK_GATE_UART10CLK, CLK_GATE_ASPEED, "uart10clk-gate", SCU1_CLK_UART10, + SCU1_CLK_STOP2, 5, 0), + GATE_CLK(SCU1_CLK_GATE_UART11CLK, CLK_GATE_ASPEED, "uart11clk-gate", SCU1_CLK_UART11, + SCU1_CLK_STOP2, 6, 0), + GATE_CLK(SCU1_CLK_GATE_UART12CLK, CLK_GATE_ASPEED, "uart12clk-gate", SCU1_CLK_UART12, + SCU1_CLK_STOP2, 7, 0), + GATE_CLK(SCU1_CLK_GATE_FSICLK, CLK_GATE_ASPEED, "fsiclk-gate", -1, SCU1_CLK_STOP2, 8, 0), + GATE_CLK(SCU1_CLK_GATE_LTPIPHYCLK, CLK_GATE_ASPEED, "ltpiphyclk-gate", -1, + SCU1_CLK_STOP2, 9, 0), + GATE_CLK(SCU1_CLK_GATE_LTPICLK, CLK_GATE_ASPEED, "ltpiclk-gate", -1, + SCU1_CLK_STOP2, 10, 0), + GATE_CLK(SCU1_CLK_GATE_VGALCLK, CLK_GATE_ASPEED, "vgalclk-gate", -1, + SCU1_CLK_STOP2, 11, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UHCICLK, CLK_GATE_ASPEED, "usbuartclk-gate", -1, + SCU1_CLK_STOP2, 12, 0), + GATE_CLK(SCU1_CLK_GATE_CANCLK, CLK_GATE_ASPEED, "canclk-gate", SCU1_CLK_CAN, + SCU1_CLK_STOP2, 13, 0), + GATE_CLK(SCU1_CLK_GATE_PCICLK, CLK_GATE_ASPEED, "pciclk-gate", -1, + SCU1_CLK_STOP2, 14, 0), + GATE_CLK(SCU1_CLK_GATE_SLICLK, CLK_GATE_ASPEED, "soc1-sliclk-gate", -1, + SCU1_CLK_STOP2, 15, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_E2MCLK, CLK_GATE_ASPEED, "soc1-e2m-gate", -1, + SCU1_CLK_STOP2, 16, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_PORTCUSB2CLK, CLK_GATE_ASPEED, "portcusb2-gate", -1, + SCU1_CLK_STOP2, 17, 0), + GATE_CLK(SCU1_CLK_GATE_PORTDUSB2CLK, CLK_GATE_ASPEED, "portdusb2-gate", -1, + SCU1_CLK_STOP2, 18, 0), + GATE_CLK(SCU1_CLK_GATE_LTPI1TXCLK, CLK_GATE_ASPEED, "ltp1tx-gate", -1, + SCU1_CLK_STOP2, 19, 0), +}; + +static struct clk_hw *ast2700_clk_hw_register_fixed_display(void __iomem *reg, const char *name, + struct ast2700_clk_ctrl *clk_ctrl) +{ + unsigned int mult, div, r, n; + u32 xdclk; + u32 val; + + val = readl(clk_ctrl->base + SCU0_CLK_SEL2); + if (val & BIT(29)) + xdclk = 800 * HZ_PER_MHZ; + else + xdclk = 1000 * HZ_PER_MHZ; + + val = readl(reg); + r = val & GENMASK(15, 0); + n = (val >> 16) & GENMASK(15, 0); + mult = r; + div = 2 * n; + + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, 0, (xdclk * mult) / div); +} + +static struct clk_hw *ast2700_clk_hw_register_hpll(void __iomem *reg, + const char *name, const struct clk_hw *parent_hw, + struct ast2700_clk_ctrl *clk_ctrl) +{ + unsigned int mult, div; + u32 val; + + val = readl(clk_ctrl->base + SCU0_HWSTRAP1); + if ((readl(clk_ctrl->base) & REVISION_ID) && (val & BIT(3))) { + switch ((val & GENMASK(4, 2)) >> 2) { + case 2: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1800 * HZ_PER_MHZ); + case 3: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1700 * HZ_PER_MHZ); + case 6: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1200 * HZ_PER_MHZ); + case 7: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 800 * HZ_PER_MHZ); + default: + return ERR_PTR(-EINVAL); + } + } else if ((val & GENMASK(3, 2)) != 0) { + switch ((val & GENMASK(3, 2)) >> 2) { + case 1: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1900 * HZ_PER_MHZ); + case 2: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1800 * HZ_PER_MHZ); + case 3: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1700 * HZ_PER_MHZ); + default: + return ERR_PTR(-EINVAL); + } + } else { + val = readl(reg); + + if (val & BIT(24)) { + /* Pass through mode */ + mult = 1; + div = 1; + } else { + u32 m = val & 0x1fff; + u32 n = (val >> 13) & 0x3f; + u32 p = (val >> 19) & 0xf; + + mult = (m + 1) / (2 * (n + 1)); + div = p + 1; + } + } + + return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name, + parent_hw, 0, mult, div); +} + +static struct clk_hw *ast2700_clk_hw_register_pll(int clk_idx, void __iomem *reg, + const char *name, const struct clk_hw *parent_hw, + struct ast2700_clk_ctrl *clk_ctrl) +{ + int scu = clk_ctrl->clk_data->scu; + unsigned int mult, div; + u32 val = readl(reg); + + if (val & BIT(24)) { + /* Pass through mode */ + mult = 1; + div = 1; + } else { + u32 m = val & 0x1fff; + u32 n = (val >> 13) & 0x3f; + u32 p = (val >> 19) & 0xf; + + if (scu) { + mult = (m + 1) / (n + 1); + div = p + 1; + } else { + if (clk_idx == SCU0_CLK_MPLL) { + mult = m / (n + 1); + div = p + 1; + } else { + mult = (m + 1) / (2 * (n + 1)); + div = p + 1; + } + } + } + + return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name, + parent_hw, 0, mult, div); +} + +static struct clk_hw *ast2700_clk_hw_register_uartpll(void __iomem *reg, const char *name, + const struct clk_hw *parent_hw, + struct ast2700_clk_ctrl *clk_ctrl) +{ + unsigned int mult, div; + u32 val = readl(reg); + u32 r = val & 0xff; + u32 n = (val >> 8) & 0x3ff; + + mult = r; + div = n * 2; + + return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name, + parent_hw, 0, mult, div); +} + +static struct clk_hw *ast2700_clk_hw_register_misc(int clk_idx, void __iomem *reg, + const char *name, const struct clk_hw *parent_hw, + struct ast2700_clk_ctrl *clk_ctrl) +{ + u32 div = 0; + + if (clk_idx == SCU0_CLK_MPHY) { + div = readl(reg) + 1; + } else if (clk_idx == SCU0_CLK_U2PHY_REFCLK) { + if (readl(clk_ctrl->base) & REVISION_ID) + div = (GET_USB_REFCLK_DIV(readl(reg)) + 1) << 4; + else + div = (GET_USB_REFCLK_DIV(readl(reg)) + 1) << 1; + } else { + return ERR_PTR(-EINVAL); + } + + return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name, + parent_hw, 0, 1, div); +} + +static int ast2700_clk_is_enabled(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + u32 clk = BIT(gate->bit_idx); + u32 reg; + + reg = readl(gate->reg); + + return !(reg & clk); +} + +static int ast2700_clk_enable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + u32 clk = BIT(gate->bit_idx); + + if (readl(gate->reg) & clk) + writel(clk, gate->reg + 0x04); + + return 0; +} + +static void ast2700_clk_disable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + u32 clk = BIT(gate->bit_idx); + + /* Clock is set to enable, so use write to set register */ + writel(clk, gate->reg); +} + +static const struct clk_ops ast2700_clk_gate_ops = { + .enable = ast2700_clk_enable, + .disable = ast2700_clk_disable, + .is_enabled = ast2700_clk_is_enabled, +}; + +static struct clk_hw *ast2700_clk_hw_register_gate(struct device *dev, const char *name, + const struct clk_hw *parent_hw, + void __iomem *reg, u8 clock_idx, + unsigned long flags, spinlock_t *lock) +{ + struct clk_init_data init; + struct clk_gate *gate; + struct clk_hw *hw; + int ret = -EINVAL; + + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &ast2700_clk_gate_ops; + init.flags = flags; + init.parent_names = NULL; + init.parent_hws = parent_hw ? &parent_hw : NULL; + init.parent_data = NULL; + init.num_parents = parent_hw ? 1 : 0; + + gate->reg = reg; + gate->bit_idx = clock_idx; + gate->flags = 0; + gate->lock = lock; + gate->hw.init = &init; + + hw = &gate->hw; + ret = clk_hw_register(dev, hw); + if (ret) { + kfree(gate); + hw = ERR_PTR(ret); + } + + return hw; +} + +static void ast2700_soc1_configure_i3c_clk(struct ast2700_clk_ctrl *clk_ctrl) +{ + if (readl(clk_ctrl->base) & REVISION_ID) { + u32 val; + + /* I3C 250MHz = HPLL/4 */ + val = readl(clk_ctrl->base + SCU1_CLK_SEL2) & ~SCU1_CLK_I3C_DIV_MASK; + val |= FIELD_PREP(SCU1_CLK_I3C_DIV_MASK, SCU1_CLK_I3C_DIV(4)); + writel(val, clk_ctrl->base + SCU1_CLK_SEL2); + } +} + +static inline const struct clk_hw *get_parent_hw_or_null(struct clk_hw **hws, int idx) +{ + if (idx < 0) + return NULL; + else + return hws[idx]; +} + +static int ast2700_soc_clk_probe(struct platform_device *pdev) +{ + const struct ast2700_clk_data *clk_data; + struct clk_hw_onecell_data *clk_hw_data; + struct ast2700_clk_ctrl *clk_ctrl; + struct device *dev = &pdev->dev; + struct auxiliary_device *adev; + void __iomem *clk_base; + struct clk_hw **hws; + char *reset_name; + int ret; + int i; + + clk_ctrl = devm_kzalloc(dev, sizeof(*clk_ctrl), GFP_KERNEL); + if (!clk_ctrl) + return -ENOMEM; + clk_ctrl->dev = dev; + dev_set_drvdata(&pdev->dev, clk_ctrl); + + spin_lock_init(&clk_ctrl->lock); + + clk_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(clk_base)) + return PTR_ERR(clk_base); + + clk_ctrl->base = clk_base; + + clk_data = device_get_match_data(dev); + if (!clk_data) + return -ENODEV; + + clk_ctrl->clk_data = clk_data; + reset_name = devm_kasprintf(dev, GFP_KERNEL, "reset%d", clk_data->scu); + + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, clk_data->nr_clks), + GFP_KERNEL); + if (!clk_hw_data) + return -ENOMEM; + + clk_hw_data->num = clk_data->nr_clks; + hws = clk_hw_data->hws; + + if (clk_data->scu) + ast2700_soc1_configure_i3c_clk(clk_ctrl); + + for (i = 0; i < clk_data->nr_clks; i++) { + const struct ast2700_clk_info *clk = &clk_data->clk_info[i]; + const struct clk_hw *phw = NULL; + unsigned int id = clk->id; + void __iomem *reg = NULL; + + if (id >= clk_hw_data->num || hws[id]) { + dev_err(dev, "clk id %u invalid for %s\n", id, clk->name); + return -EINVAL; + } + + if (clk->type == CLK_FIXED) { + const struct ast2700_clk_fixed_rate_data *fixed_rate = &clk->data.rate; + + hws[id] = devm_clk_hw_register_fixed_rate(dev, clk->name, NULL, 0, + fixed_rate->fixed_rate); + } else if (clk->type == CLK_FIXED_FACTOR) { + const struct ast2700_clk_fixed_factor_data *factor = &clk->data.factor; + + phw = hws[factor->parent_id]; + hws[id] = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk->name, + phw, 0, factor->mult, + factor->div); + } else if (clk->type == CLK_FIXED_DISPLAY) { + reg = clk_ctrl->base + clk->data.display_rate.reg; + + hws[id] = ast2700_clk_hw_register_fixed_display(reg, clk->name, clk_ctrl); + } else if (clk->type == CLK_HPLL) { + const struct ast2700_clk_pll_data *pll = &clk->data.pll; + + reg = clk_ctrl->base + pll->reg; + phw = hws[pll->parent_id]; + hws[id] = ast2700_clk_hw_register_hpll(reg, clk->name, phw, clk_ctrl); + } else if (clk->type == CLK_PLL) { + const struct ast2700_clk_pll_data *pll = &clk->data.pll; + + reg = clk_ctrl->base + pll->reg; + phw = hws[pll->parent_id]; + hws[id] = ast2700_clk_hw_register_pll(id, reg, clk->name, phw, clk_ctrl); + } else if (clk->type == CLK_UART_PLL) { + const struct ast2700_clk_pll_data *pll = &clk->data.pll; + + reg = clk_ctrl->base + pll->reg; + phw = hws[pll->parent_id]; + hws[id] = ast2700_clk_hw_register_uartpll(reg, clk->name, phw, clk_ctrl); + } else if (clk->type == CLK_MUX) { + const struct ast2700_clk_mux_data *mux = &clk->data.mux; + + reg = clk_ctrl->base + mux->reg; + for (int j = 0; j < mux->num_parents; j++) { + unsigned int pid = mux->parent_ids[j]; + + mux->parent_hws[j] = hws[pid]; + } + + hws[id] = devm_clk_hw_register_mux_parent_hws(dev, clk->name, + mux->parent_hws, + mux->num_parents, 0, + reg, mux->bit_shift, + mux->bit_width, 0, + &clk_ctrl->lock); + } else if (clk->type == CLK_MISC) { + const struct ast2700_clk_pll_data *pll = &clk->data.pll; + + reg = clk_ctrl->base + pll->reg; + phw = hws[pll->parent_id]; + hws[id] = ast2700_clk_hw_register_misc(id, reg, clk->name, phw, clk_ctrl); + } else if (clk->type == CLK_DIVIDER) { + const struct ast2700_clk_div_data *divider = &clk->data.div; + + reg = clk_ctrl->base + divider->reg; + phw = hws[divider->parent_id]; + hws[id] = clk_hw_register_divider_table_parent_hw(dev, clk->name, + phw, + 0, reg, + divider->bit_shift, + divider->bit_width, 0, + divider->div_table, + &clk_ctrl->lock); + } else if (clk->type == CLK_GATE_ASPEED) { + const struct ast2700_clk_gate_data *gate = &clk->data.gate; + + phw = get_parent_hw_or_null(hws, gate->parent_id); + reg = clk_ctrl->base + gate->reg; + hws[id] = ast2700_clk_hw_register_gate(dev, clk->name, phw, reg, gate->bit, + gate->flags, &clk_ctrl->lock); + } else { + const struct ast2700_clk_gate_data *gate = &clk->data.gate; + + phw = get_parent_hw_or_null(hws, gate->parent_id); + reg = clk_ctrl->base + gate->reg; + hws[id] = devm_clk_hw_register_gate_parent_hw(dev, clk->name, phw, + gate->flags, reg, gate->bit, + 0, &clk_ctrl->lock); + } + + if (IS_ERR(hws[id])) + return PTR_ERR(hws[id]); + } + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_hw_data); + if (ret) + return ret; + + adev = devm_auxiliary_device_create(dev, reset_name, (__force void *)clk_base); + if (!adev) + return -ENODEV; + + return 0; +} + +static const struct ast2700_clk_data ast2700_clk0_data = { + .scu = 0, + .nr_clks = ARRAY_SIZE(ast2700_scu0_clk_info), + .clk_info = ast2700_scu0_clk_info, +}; + +static const struct ast2700_clk_data ast2700_clk1_data = { + .scu = 1, + .nr_clks = ARRAY_SIZE(ast2700_scu1_clk_info), + .clk_info = ast2700_scu1_clk_info, +}; + +static const struct of_device_id ast2700_scu_match[] = { + { .compatible = "aspeed,ast2700-scu0", .data = &ast2700_clk0_data }, + { .compatible = "aspeed,ast2700-scu1", .data = &ast2700_clk1_data }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, ast2700_scu_match); + +static struct platform_driver ast2700_scu_driver = { + .probe = ast2700_soc_clk_probe, + .driver = { + .name = "clk-ast2700", + .of_match_table = ast2700_scu_match, + }, +}; + +module_platform_driver(ast2700_scu_driver); From 2ad2d0e291ac6f4ffc66dce11c09ccc6dd968a9b Mon Sep 17 00:00:00 2001 From: Jammy Huang Date: Fri, 3 Oct 2025 09:58:44 +0800 Subject: [PATCH 164/165] dt-bindings: clock: aspeed: Add VIDEO reset definition ASPEED clock controller provides a couple of resets. Add the define of video to allow referring to it. Signed-off-by: Jammy Huang Acked-by: Conor Dooley Signed-off-by: Stephen Boyd --- include/dt-bindings/clock/aspeed-clock.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/clock/aspeed-clock.h b/include/dt-bindings/clock/aspeed-clock.h index 06d568382c77..671e5a476eae 100644 --- a/include/dt-bindings/clock/aspeed-clock.h +++ b/include/dt-bindings/clock/aspeed-clock.h @@ -53,5 +53,6 @@ #define ASPEED_RESET_AHB 8 #define ASPEED_RESET_CRT1 9 #define ASPEED_RESET_HACE 10 +#define ASPEED_RESET_VIDEO 11 #endif From 5f35b48a0daa799ee6346f7b6b4fe433d6565280 Mon Sep 17 00:00:00 2001 From: Jammy Huang Date: Fri, 3 Oct 2025 09:58:45 +0800 Subject: [PATCH 165/165] clk: aspeed: Add reset for HACE/VIDEO Add mappings of reset per hw's definition. Signed-off-by: Jammy Huang Signed-off-by: Stephen Boyd --- drivers/clk/aspeed/clk-aspeed.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/aspeed/clk-aspeed.c b/drivers/clk/aspeed/clk-aspeed.c index ff84191d0fe8..74c8c1377b70 100644 --- a/drivers/clk/aspeed/clk-aspeed.c +++ b/drivers/clk/aspeed/clk-aspeed.c @@ -278,6 +278,8 @@ static const u8 aspeed_resets[] = { [ASPEED_RESET_PECI] = 10, [ASPEED_RESET_I2C] = 2, [ASPEED_RESET_AHB] = 1, + [ASPEED_RESET_HACE] = 4, + [ASPEED_RESET_VIDEO] = 6, /* * SCUD4 resets start at an offset to separate them from