From f4d3d7340e719dd3d2c23ce8d6c360e2f93ba7e4 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 22 Oct 2024 17:22:52 +0530 Subject: [PATCH 01/81] dt-bindings: clock: qcom: Add QCS615 GCC clocks Add device tree bindings for global clock controller on QCS615 SoCs. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20241022-qcs615-clock-driver-v4-3-3d716ad0d987@quicinc.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,qcs615-gcc.yaml | 59 +++++ include/dt-bindings/clock/qcom,qcs615-gcc.h | 211 ++++++++++++++++++ 2 files changed, 270 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml create mode 100644 include/dt-bindings/clock/qcom,qcs615-gcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml new file mode 100644 index 0000000000000..4a828e102d25b --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,qcs615-gcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Global Clock & Reset Controller on QCS615 + +maintainers: + - Taniya Das + +description: | + Qualcomm global clock control module provides the clocks, resets and power + domains on QCS615. + + See also: include/dt-bindings/clock/qcom,qcs615-gcc.h + +properties: + compatible: + const: qcom,qcs615-gcc + + clocks: + items: + - description: Board XO source + - description: Board active XO source + - description: Sleep clock source + + clock-names: + items: + - const: bi_tcxo + - const: bi_tcxo_ao + - const: sleep_clk + +required: + - compatible + - clocks + - clock-names + - '#power-domain-cells' + +allOf: + - $ref: qcom,gcc.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + clock-controller@100000 { + compatible = "qcom,qcs615-gcc"; + reg = <0x00100000 0x1f0000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&rpmhcc RPMH_CXO_CLK_A>, + <&sleep_clk>; + clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; +... diff --git a/include/dt-bindings/clock/qcom,qcs615-gcc.h b/include/dt-bindings/clock/qcom,qcs615-gcc.h new file mode 100644 index 0000000000000..9704091636b87 --- /dev/null +++ b/include/dt-bindings/clock/qcom,qcs615-gcc.h @@ -0,0 +1,211 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_QCS615_H +#define _DT_BINDINGS_CLK_QCOM_GCC_QCS615_H + +/* GCC clocks */ +#define GPLL0_OUT_AUX2_DIV 0 +#define GPLL3_OUT_AUX2_DIV 1 +#define GPLL0 2 +#define GPLL3 3 +#define GPLL4 4 +#define GPLL6 5 +#define GPLL6_OUT_MAIN 6 +#define GPLL7 7 +#define GPLL8 8 +#define GPLL8_OUT_MAIN 9 +#define GCC_AGGRE_UFS_PHY_AXI_CLK 10 +#define GCC_AGGRE_USB2_SEC_AXI_CLK 11 +#define GCC_AGGRE_USB3_PRIM_AXI_CLK 12 +#define GCC_AHB2PHY_EAST_CLK 13 +#define GCC_AHB2PHY_WEST_CLK 14 +#define GCC_BOOT_ROM_AHB_CLK 15 +#define GCC_CAMERA_AHB_CLK 16 +#define GCC_CAMERA_HF_AXI_CLK 17 +#define GCC_CAMERA_XO_CLK 18 +#define GCC_CE1_AHB_CLK 19 +#define GCC_CE1_AXI_CLK 20 +#define GCC_CE1_CLK 21 +#define GCC_CFG_NOC_USB2_SEC_AXI_CLK 22 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 23 +#define GCC_CPUSS_AHB_CLK 24 +#define GCC_CPUSS_AHB_CLK_SRC 25 +#define GCC_CPUSS_GNOC_CLK 26 +#define GCC_DDRSS_GPU_AXI_CLK 27 +#define GCC_DISP_AHB_CLK 28 +#define GCC_DISP_GPLL0_DIV_CLK_SRC 29 +#define GCC_DISP_HF_AXI_CLK 30 +#define GCC_DISP_XO_CLK 31 +#define GCC_EMAC_AXI_CLK 32 +#define GCC_EMAC_PTP_CLK 33 +#define GCC_EMAC_PTP_CLK_SRC 34 +#define GCC_EMAC_RGMII_CLK 35 +#define GCC_EMAC_RGMII_CLK_SRC 36 +#define GCC_EMAC_SLV_AHB_CLK 37 +#define GCC_GP1_CLK 38 +#define GCC_GP1_CLK_SRC 39 +#define GCC_GP2_CLK 40 +#define GCC_GP2_CLK_SRC 41 +#define GCC_GP3_CLK 42 +#define GCC_GP3_CLK_SRC 43 +#define GCC_GPU_CFG_AHB_CLK 44 +#define GCC_GPU_GPLL0_CLK_SRC 45 +#define GCC_GPU_GPLL0_DIV_CLK_SRC 46 +#define GCC_GPU_IREF_CLK 47 +#define GCC_GPU_MEMNOC_GFX_CLK 48 +#define GCC_GPU_SNOC_DVM_GFX_CLK 49 +#define GCC_PCIE0_PHY_REFGEN_CLK 50 +#define GCC_PCIE_0_AUX_CLK 51 +#define GCC_PCIE_0_AUX_CLK_SRC 52 +#define GCC_PCIE_0_CFG_AHB_CLK 53 +#define GCC_PCIE_0_CLKREF_CLK 54 +#define GCC_PCIE_0_MSTR_AXI_CLK 55 +#define GCC_PCIE_0_PIPE_CLK 56 +#define GCC_PCIE_0_SLV_AXI_CLK 57 +#define GCC_PCIE_0_SLV_Q2A_AXI_CLK 58 +#define GCC_PCIE_PHY_AUX_CLK 59 +#define GCC_PCIE_PHY_REFGEN_CLK_SRC 60 +#define GCC_PDM2_CLK 61 +#define GCC_PDM2_CLK_SRC 62 +#define GCC_PDM_AHB_CLK 63 +#define GCC_PDM_XO4_CLK 64 +#define GCC_PRNG_AHB_CLK 65 +#define GCC_QMIP_CAMERA_NRT_AHB_CLK 66 +#define GCC_QMIP_DISP_AHB_CLK 67 +#define GCC_QMIP_PCIE_AHB_CLK 68 +#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK 69 +#define GCC_QSPI_CNOC_PERIPH_AHB_CLK 70 +#define GCC_QSPI_CORE_CLK 71 +#define GCC_QSPI_CORE_CLK_SRC 72 +#define GCC_QUPV3_WRAP0_CORE_2X_CLK 73 +#define GCC_QUPV3_WRAP0_CORE_CLK 74 +#define GCC_QUPV3_WRAP0_S0_CLK 75 +#define GCC_QUPV3_WRAP0_S0_CLK_SRC 76 +#define GCC_QUPV3_WRAP0_S1_CLK 77 +#define GCC_QUPV3_WRAP0_S1_CLK_SRC 78 +#define GCC_QUPV3_WRAP0_S2_CLK 79 +#define GCC_QUPV3_WRAP0_S2_CLK_SRC 80 +#define GCC_QUPV3_WRAP0_S3_CLK 81 +#define GCC_QUPV3_WRAP0_S3_CLK_SRC 82 +#define GCC_QUPV3_WRAP0_S4_CLK 83 +#define GCC_QUPV3_WRAP0_S4_CLK_SRC 84 +#define GCC_QUPV3_WRAP0_S5_CLK 85 +#define GCC_QUPV3_WRAP0_S5_CLK_SRC 86 +#define GCC_QUPV3_WRAP1_CORE_2X_CLK 87 +#define GCC_QUPV3_WRAP1_CORE_CLK 88 +#define GCC_QUPV3_WRAP1_S0_CLK 89 +#define GCC_QUPV3_WRAP1_S0_CLK_SRC 90 +#define GCC_QUPV3_WRAP1_S1_CLK 91 +#define GCC_QUPV3_WRAP1_S1_CLK_SRC 92 +#define GCC_QUPV3_WRAP1_S2_CLK 93 +#define GCC_QUPV3_WRAP1_S2_CLK_SRC 94 +#define GCC_QUPV3_WRAP1_S3_CLK 95 +#define GCC_QUPV3_WRAP1_S3_CLK_SRC 96 +#define GCC_QUPV3_WRAP1_S4_CLK 97 +#define GCC_QUPV3_WRAP1_S4_CLK_SRC 98 +#define GCC_QUPV3_WRAP1_S5_CLK 99 +#define GCC_QUPV3_WRAP1_S5_CLK_SRC 100 +#define GCC_QUPV3_WRAP_0_M_AHB_CLK 101 +#define GCC_QUPV3_WRAP_0_S_AHB_CLK 102 +#define GCC_QUPV3_WRAP_1_M_AHB_CLK 103 +#define GCC_QUPV3_WRAP_1_S_AHB_CLK 104 +#define GCC_RX1_USB2_CLKREF_CLK 105 +#define GCC_RX3_USB2_CLKREF_CLK 106 +#define GCC_SDCC1_AHB_CLK 107 +#define GCC_SDCC1_APPS_CLK 108 +#define GCC_SDCC1_APPS_CLK_SRC 109 +#define GCC_SDCC1_ICE_CORE_CLK 110 +#define GCC_SDCC1_ICE_CORE_CLK_SRC 111 +#define GCC_SDCC2_AHB_CLK 112 +#define GCC_SDCC2_APPS_CLK 113 +#define GCC_SDCC2_APPS_CLK_SRC 114 +#define GCC_SDR_CORE_CLK 115 +#define GCC_SDR_CSR_HCLK 116 +#define GCC_SDR_PRI_MI2S_CLK 117 +#define GCC_SDR_SEC_MI2S_CLK 118 +#define GCC_SDR_WR0_MEM_CLK 119 +#define GCC_SDR_WR1_MEM_CLK 120 +#define GCC_SDR_WR2_MEM_CLK 121 +#define GCC_SYS_NOC_CPUSS_AHB_CLK 122 +#define GCC_UFS_CARD_CLKREF_CLK 123 +#define GCC_UFS_MEM_CLKREF_CLK 124 +#define GCC_UFS_PHY_AHB_CLK 125 +#define GCC_UFS_PHY_AXI_CLK 126 +#define GCC_UFS_PHY_AXI_CLK_SRC 127 +#define GCC_UFS_PHY_ICE_CORE_CLK 128 +#define GCC_UFS_PHY_ICE_CORE_CLK_SRC 129 +#define GCC_UFS_PHY_PHY_AUX_CLK 130 +#define GCC_UFS_PHY_PHY_AUX_CLK_SRC 131 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK 132 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK 133 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK 134 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC 135 +#define GCC_USB20_SEC_MASTER_CLK 136 +#define GCC_USB20_SEC_MASTER_CLK_SRC 137 +#define GCC_USB20_SEC_MOCK_UTMI_CLK 138 +#define GCC_USB20_SEC_MOCK_UTMI_CLK_SRC 139 +#define GCC_USB20_SEC_SLEEP_CLK 140 +#define GCC_USB2_PRIM_CLKREF_CLK 141 +#define GCC_USB2_SEC_CLKREF_CLK 142 +#define GCC_USB2_SEC_PHY_AUX_CLK 143 +#define GCC_USB2_SEC_PHY_AUX_CLK_SRC 144 +#define GCC_USB2_SEC_PHY_COM_AUX_CLK 145 +#define GCC_USB2_SEC_PHY_PIPE_CLK 146 +#define GCC_USB30_PRIM_MASTER_CLK 147 +#define GCC_USB30_PRIM_MASTER_CLK_SRC 148 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK 149 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 150 +#define GCC_USB30_PRIM_SLEEP_CLK 151 +#define GCC_USB3_PRIM_CLKREF_CLK 152 +#define GCC_USB3_PRIM_PHY_AUX_CLK 153 +#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 154 +#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 155 +#define GCC_USB3_PRIM_PHY_PIPE_CLK 156 +#define GCC_USB3_SEC_CLKREF_CLK 157 +#define GCC_VIDEO_AHB_CLK 158 +#define GCC_VIDEO_AXI0_CLK 159 +#define GCC_VIDEO_XO_CLK 160 +#define GCC_VSENSOR_CLK_SRC 161 +#define GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK 162 +#define GCC_UFS_PHY_AXI_HW_CTL_CLK 163 +#define GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK 164 +#define GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK 165 +#define GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK 166 + +/* GCC Resets */ +#define GCC_EMAC_BCR 0 +#define GCC_QUSB2PHY_PRIM_BCR 1 +#define GCC_QUSB2PHY_SEC_BCR 2 +#define GCC_USB30_PRIM_BCR 3 +#define GCC_USB2_PHY_SEC_BCR 4 +#define GCC_USB3_DP_PHY_SEC_BCR 5 +#define GCC_USB3PHY_PHY_SEC_BCR 6 +#define GCC_PCIE_0_BCR 7 +#define GCC_PCIE_0_PHY_BCR 8 +#define GCC_PCIE_PHY_BCR 9 +#define GCC_PCIE_PHY_COM_BCR 10 +#define GCC_UFS_PHY_BCR 11 +#define GCC_USB20_SEC_BCR 12 +#define GCC_USB3_PHY_PRIM_SP0_BCR 13 +#define GCC_USB3PHY_PHY_PRIM_SP0_BCR 14 +#define GCC_SDCC1_BCR 15 +#define GCC_SDCC2_BCR 16 + +/* GCC power domains */ +#define EMAC_GDSC 0 +#define PCIE_0_GDSC 1 +#define UFS_PHY_GDSC 2 +#define USB20_SEC_GDSC 3 +#define USB30_PRIM_GDSC 4 +#define HLOS1_VOTE_AGGRE_NOC_MMU_AUDIO_TBU_GDSC 5 +#define HLOS1_VOTE_AGGRE_NOC_MMU_TBU1_GDSC 6 +#define HLOS1_VOTE_AGGRE_NOC_MMU_TBU2_GDSC 7 +#define HLOS1_VOTE_AGGRE_NOC_MMU_PCIE_TBU_GDSC 8 +#define HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC 9 +#define HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC 10 +#define HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC 11 + +#endif From d87daa18535d38385f1da460c557c004e0b66347 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 26 Aug 2024 20:31:14 +0300 Subject: [PATCH 02/81] dt-bindings: clk: at91: Add clock IDs for the slow clock controller Add clock IDs for the slow clock controller. Previously, raw numbers were used (0 or 1) for clocks generated by the slow clock controller. This leads to confusion and wrong IDs were used on few device trees. To avoid this add macros. Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240826173116.3628337-2-claudiu.beznea@tuxon.dev Signed-off-by: Claudiu Beznea --- include/dt-bindings/clock/at91.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h index 6ede88c3992d1..99f4767ff6bb4 100644 --- a/include/dt-bindings/clock/at91.h +++ b/include/dt-bindings/clock/at91.h @@ -55,4 +55,8 @@ #define AT91_PMC_GCKRDY 24 /* Generated Clocks */ #endif +/* Slow clock. */ +#define SCKC_MD_SLCK 0 +#define SCKC_TD_SLCK 1 + #endif From 802244fae1f8f151ec2a4ba091a0cb14b32ac27f Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 26 Aug 2024 20:31:15 +0300 Subject: [PATCH 03/81] clk: at91: sckc: Use SCKC_{TD, MD}_SLCK IDs for clk32k clocks Use the newly introduced macros instead of raw numbers. With this the code is a bit easier to understand. Reviewed-by: Alexander Dahl Link: https://lore.kernel.org/r/20240826173116.3628337-3-claudiu.beznea@tuxon.dev Signed-off-by: Claudiu Beznea --- drivers/clk/at91/sckc.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c index 7741d8f3dbee9..021d1b412af4c 100644 --- a/drivers/clk/at91/sckc.c +++ b/drivers/clk/at91/sckc.c @@ -12,6 +12,8 @@ #include #include +#include + #define SLOW_CLOCK_FREQ 32768 #define SLOWCK_SW_CYCLES 5 #define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \ @@ -470,7 +472,7 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np) { void __iomem *regbase = of_iomap(np, 0); struct clk_hw_onecell_data *clk_data; - struct clk_hw *slow_rc, *slow_osc; + struct clk_hw *slow_rc, *slow_osc, *hw; const char *xtal_name; const struct clk_hw *parent_hws[2]; static struct clk_parent_data parent_data = { @@ -506,19 +508,19 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np) /* MD_SLCK and TD_SLCK. */ clk_data->num = 2; - clk_data->hws[0] = clk_hw_register_fixed_rate_parent_hw(NULL, "md_slck", - slow_rc, - 0, 32768); - if (IS_ERR(clk_data->hws[0])) + hw = clk_hw_register_fixed_rate_parent_hw(NULL, "md_slck", slow_rc, + 0, 32768); + if (IS_ERR(hw)) goto clk_data_free; + clk_data->hws[SCKC_MD_SLCK] = hw; parent_hws[0] = slow_rc; parent_hws[1] = slow_osc; - clk_data->hws[1] = at91_clk_register_sam9x5_slow(regbase, "td_slck", - parent_hws, 2, - &at91sam9x60_bits); - if (IS_ERR(clk_data->hws[1])) + hw = at91_clk_register_sam9x5_slow(regbase, "td_slck", parent_hws, + 2, &at91sam9x60_bits); + if (IS_ERR(hw)) goto unregister_md_slck; + clk_data->hws[SCKC_TD_SLCK] = hw; ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); if (WARN_ON(ret)) @@ -527,9 +529,9 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np) return; unregister_td_slck: - at91_clk_unregister_sam9x5_slow(clk_data->hws[1]); + at91_clk_unregister_sam9x5_slow(clk_data->hws[SCKC_TD_SLCK]); unregister_md_slck: - clk_hw_unregister(clk_data->hws[0]); + clk_hw_unregister(clk_data->hws[SCKC_MD_SLCK]); clk_data_free: kfree(clk_data); unregister_slow_osc: From 2a5711c7dc6f20e132f99b13731952bdb3530acf Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 17 Aug 2024 11:46:04 +0200 Subject: [PATCH 04/81] dt-bindings: clock: qcom,sc7280-lpasscorecc: order properties to match convention By convention we expect first "compatible", then "reg" and then rest. Order properties to match convention and what is in "required:" block. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20240817094605.27185-1-krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson --- .../clock/qcom,sc7280-lpasscorecc.yaml | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml index deee5423d66eb..5e6737c39897d 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml @@ -18,12 +18,6 @@ description: | include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h properties: - clocks: true - - clock-names: true - - reg: true - compatible: enum: - qcom,sc7280-lpassaoncc @@ -31,12 +25,18 @@ properties: - qcom,sc7280-lpasscorecc - qcom,sc7280-lpasshm - power-domains: - maxItems: 1 + reg: true + + clocks: true + + clock-names: true '#clock-cells': const: 1 + power-domains: + maxItems: 1 + '#power-domain-cells': const: 1 @@ -57,8 +57,6 @@ required: - '#clock-cells' - '#power-domain-cells' -additionalProperties: false - allOf: - if: properties: @@ -125,6 +123,9 @@ allOf: reg: maxItems: 1 + +additionalProperties: false + examples: - | #include From 9d40c5a698de6ba629f2abc8dd43b8a2db469307 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 17 Aug 2024 11:46:05 +0200 Subject: [PATCH 05/81] dt-bindings: clock: qcom,sc7280-lpasscorecc: add top-level constraints Properties with variable number of items per each device are expected to have widest constraints in top-level "properties:" block and further customized (narrowed) in "if:then:". Add missing top-level constraints for reg, clocks and clock-names. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20240817094605.27185-2-krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sc7280-lpasscorecc.yaml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml index 5e6737c39897d..488d639594240 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml @@ -25,11 +25,17 @@ properties: - qcom,sc7280-lpasscorecc - qcom,sc7280-lpasshm - reg: true + reg: + minItems: 1 + maxItems: 2 - clocks: true + clocks: + minItems: 1 + maxItems: 3 - clock-names: true + clock-names: + minItems: 1 + maxItems: 3 '#clock-cells': const: 1 From 188002bd234035199769cb1a8c7a20b51754327b Mon Sep 17 00:00:00 2001 From: Dharma Balasubiramani Date: Fri, 6 Dec 2024 12:59:51 -0700 Subject: [PATCH 06/81] dt-bindings: clocks: atmel,at91sam9x5-sckc: add sama7d65 Add bindings for SAMA7D65's slow clock controller. Signed-off-by: Dharma Balasubiramani Signed-off-by: Ryan Wanner Acked-by: Conor Dooley Reviewed-by: Claudiu Beznea Link: https://lore.kernel.org/r/b7a8a22a571f6fc2be56a25f26757f37fa8d2bb3.1733505542.git.Ryan.Wanner@microchip.com Signed-off-by: Claudiu Beznea --- .../devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml b/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml index c2283cd07f054..d4cf8ae2961e9 100644 --- a/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml +++ b/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml @@ -20,6 +20,7 @@ properties: - items: - enum: - microchip,sam9x7-sckc + - microchip,sama7d65-sckc - microchip,sama7g5-sckc - const: microchip,sam9x60-sckc From 1c9eb9e684c606982c5dba019c58eaed5474c3c0 Mon Sep 17 00:00:00 2001 From: Dharma Balasubiramani Date: Fri, 6 Dec 2024 12:59:52 -0700 Subject: [PATCH 07/81] dt-bindings: clock: Add SAMA7D65 PMC compatible string Add the `microchip,sama7d65-pmc` compatible string to the existing binding, since the SAMA7D65 PMC shares the same properties and clock requirements as the SAMA7G5. Export MCK3 and MCK5 to be accessed and referenced in DT to assign to the clocks property for sama7d65 SoC. Signed-off-by: Dharma Balasubiramani Signed-off-by: Ryan Wanner Reviewed-by: Claudiu Beznea Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/5252a28531deaee67af1edd8e72d45ca57783464.1733505542.git.Ryan.Wanner@microchip.com [claudiu.beznea: use tabs instead of spaces in include/dt-bindings/clock/at91.h] Signed-off-by: Claudiu Beznea --- .../devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml | 2 ++ include/dt-bindings/clock/at91.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml b/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml index c9eb60776b4d4..885d47dd5724f 100644 --- a/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml +++ b/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml @@ -43,6 +43,7 @@ properties: - atmel,sama5d4-pmc - microchip,sam9x60-pmc - microchip,sam9x7-pmc + - microchip,sama7d65-pmc - microchip,sama7g5-pmc - const: syscon @@ -90,6 +91,7 @@ allOf: enum: - microchip,sam9x60-pmc - microchip,sam9x7-pmc + - microchip,sama7d65-pmc - microchip,sama7g5-pmc then: properties: diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h index 99f4767ff6bb4..f2a7b7d39c0d0 100644 --- a/include/dt-bindings/clock/at91.h +++ b/include/dt-bindings/clock/at91.h @@ -42,6 +42,10 @@ #define PMC_PLLADIV2 (PMC_MAIN + 11) #define PMC_LVDSPLL (PMC_MAIN + 12) +/* SAMA7D65 */ +#define PMC_MCK3 (PMC_MAIN + 13) +#define PMC_MCK5 (PMC_MAIN + 14) + #ifndef AT91_PMC_MOSCS #define AT91_PMC_MOSCS 0 /* MOSCS Flag */ #define AT91_PMC_LOCKA 1 /* PLLA Lock */ From e8f81b561360d45832cfd546a1ce566745d184d9 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 21 Dec 2024 13:24:10 +0100 Subject: [PATCH 08/81] dt-bindings: clock: qcom,x1e80100-gpucc: Extend for X1P42100 To make it easier for X1P4 and X1E to share a common device tree base, extend the existing latter's GPUCC bindings and reuse them on the former platform. While not in the same file, it only makes sense to introduce the new compatible in this commit as well. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20241221-topic-x1p4_clk-v1-2-dbaeccb74884@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm8450-gpucc.yaml | 1 + include/dt-bindings/clock/qcom,x1e80100-gpucc.h | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml index 5c65f5ecf0f38..02968632fb3af 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml @@ -32,6 +32,7 @@ properties: - qcom,sm8550-gpucc - qcom,sm8650-gpucc - qcom,x1e80100-gpucc + - qcom,x1p42100-gpucc clocks: items: diff --git a/include/dt-bindings/clock/qcom,x1e80100-gpucc.h b/include/dt-bindings/clock/qcom,x1e80100-gpucc.h index 61a3a8f3ac434..27b8f50541fd6 100644 --- a/include/dt-bindings/clock/qcom,x1e80100-gpucc.h +++ b/include/dt-bindings/clock/qcom,x1e80100-gpucc.h @@ -33,9 +33,22 @@ #define GPU_CC_SLEEP_CLK 23 #define GPU_CC_XO_CLK_SRC 24 #define GPU_CC_XO_DIV_CLK_SRC 25 +#define GPU_CC_CX_ACCU_SHIFT_CLK 26 +#define GPU_CC_GX_ACCU_SHIFT_CLK 27 /* GDSCs */ #define GPU_CX_GDSC 0 #define GPU_GX_GDSC 1 +/* GPU_CC resets */ +#define GPU_CC_ACD_BCR 0 +#define GPU_CC_CB_BCR 1 +#define GPU_CC_CX_BCR 2 +#define GPU_CC_FAST_HUB_BCR 3 +#define GPU_CC_FF_BCR 4 +#define GPU_CC_GFX3D_AON_BCR 5 +#define GPU_CC_GMU_BCR 6 +#define GPU_CC_GX_BCR 7 +#define GPU_CC_XO_BCR 8 + #endif From 089c09ee12317def57ab6a5159269315743083e3 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 21 Dec 2024 13:24:09 +0100 Subject: [PATCH 09/81] dt-bindings: clock: qcom,x1e80100-gcc: Add X1P42100 X1P42100 is based on X1E80100 and largely reuses the X1E80100's GCC block, adding a couple wires here and there. Add a compatible for the X1P4 with a fallback to X1E80100. There are some additions in the smaller one, that will be added in the future. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20241221-topic-x1p4_clk-v1-1-dbaeccb74884@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/clock/qcom,x1e80100-gcc.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml index 5951a60ab0815..28797d0c5d8db 100644 --- a/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml @@ -17,7 +17,11 @@ description: | properties: compatible: - const: qcom,x1e80100-gcc + oneOf: + - items: + - const: qcom,x1p42100-gcc + - const: qcom,x1e80100-gcc + - const: qcom,x1e80100-gcc clocks: items: From 99c21c7ca6423913783ea50e2c16be3cc097f17b Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 21 Dec 2024 13:24:11 +0100 Subject: [PATCH 10/81] clk: qcom: Add X1P42100 GPUCC driver The 8-core X1s have a different GPU subsystem compared to their bigger cousins, including the clocks part. Add the GPU clock controller driver to drive these. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20241221-topic-x1p4_clk-v1-3-dbaeccb74884@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-x1p42100.c | 587 ++++++++++++++++++++++++++++++ 3 files changed, 597 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-x1p42100.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index ef89d686cbc4e..32b34b22ef014 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -64,6 +64,15 @@ config CLK_X1E80100_TCSRCC Support for the TCSR clock controller on X1E80100 devices. Say Y if you want to use peripheral devices such as SD/UFS. +config CLK_X1P42100_GPUCC + tristate "X1P42100 Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_X1E8010_GCC + help + Support for the graphics clock controller on X1P42100 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config CLK_QCM2290_GPUCC tristate "QCM2290 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index b09dbdc210eb1..7b5dd918c705b 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GPUCC) += gpucc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_TCSRCC) += tcsrcc-x1e80100.o +obj-$(CONFIG_CLK_X1P42100_GPUCC) += gpucc-x1p42100.o obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o diff --git a/drivers/clk/qcom/gpucc-x1p42100.c b/drivers/clk/qcom/gpucc-x1p42100.c new file mode 100644 index 0000000000000..dba7833396130 --- /dev/null +++ b/drivers/clk/qcom/gpucc-x1p42100.c @@ -0,0 +1,587 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#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_BI_TCXO, + DT_GPLL0_OUT_MAIN, + DT_GPLL0_OUT_MAIN_DIV, +}; + +enum { + P_BI_TCXO, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL1_OUT_MAIN, +}; + +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + +/* 560.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x1d, + .alpha = 0x2aaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +/* 440.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x16, + .alpha = 0xeaaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll gpu_cc_pll1 = { + .offset = 0x1000, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct parent_map gpu_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct freq_tbl ftbl_gpu_cc_ff_clk_src[] = { + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_ff_clk_src = { + .cmd_rcgr = 0x9474, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .freq_tbl = ftbl_gpu_cc_ff_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_ff_clk_src", + .parent_data = gpu_cc_parent_data_0, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(220000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(550000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x9318, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_1, + .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_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gpu_cc_hub_clk_src = { + .cmd_rcgr = 0x93ec, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_2, + .freq_tbl = ftbl_gpu_cc_ff_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_clk_src", + .parent_data = gpu_cc_parent_data_2, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch gpu_cc_ahb_clk = { + .halt_reg = 0x911c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x911c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_crc_ahb_clk = { + .halt_reg = 0x9120, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9120, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_crc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_accu_shift_clk = { + .halt_reg = 0x9480, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9480, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_ff_clk = { + .halt_reg = 0x914c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x914c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_ff_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_ff_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gmu_clk = { + .halt_reg = 0x913c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x913c, + .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 = 0x9144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_freq_measure_clk = { + .halt_reg = 0x9008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_freq_measure_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_accu_shift_clk = { + .halt_reg = 0x947c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x947c, + .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 = 0x90bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x90bc, + .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_gx_vsense_clk = { + .halt_reg = 0x90b0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_vsense_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_aon_clk = { + .halt_reg = 0x93e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x93e8, + .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 = 0x9148, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9148, + .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 = 0x9150, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9150, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_mnd1x_0_gfx3d_clk = { + .halt_reg = 0x9288, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9288, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_mnd1x_0_gfx3d_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_mnd1x_1_gfx3d_clk = { + .halt_reg = 0x928c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x928c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_mnd1x_1_gfx3d_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_sleep_clk = { + .halt_reg = 0x9134, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gpu_cc_cx_gdsc = { + .gdscr = 0x9108, + .gds_hw_ctrl = 0x953c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gpu_cc_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gpu_cc_gx_gdsc = { + .gdscr = 0x905c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gpu_cc_gx_gdsc", + .power_on = gdsc_gx_do_nothing_enable, + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = CLAMP_IO | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gpu_cc_x1p42100_clocks[] = { + [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, + [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, + [GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr, + [GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr, + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, + [GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr, + [GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr, + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr, + [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, + [GPU_CC_GX_VSENSE_CLK] = &gpu_cc_gx_vsense_clk.clkr, + [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, + [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr, + [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr, + [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr, + [GPU_CC_MND1X_0_GFX3D_CLK] = &gpu_cc_mnd1x_0_gfx3d_clk.clkr, + [GPU_CC_MND1X_1_GFX3D_CLK] = &gpu_cc_mnd1x_1_gfx3d_clk.clkr, + [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, + [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, + [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, +}; + +static struct gdsc *gpu_cc_x1p42100_gdscs[] = { + [GPU_CX_GDSC] = &gpu_cc_cx_gdsc, + [GPU_GX_GDSC] = &gpu_cc_gx_gdsc, +}; + +static const struct qcom_reset_map gpu_cc_x1p42100_resets[] = { + [GPU_CC_ACD_BCR] = { 0x9358 }, + [GPU_CC_CB_BCR] = { 0x93a0 }, + [GPU_CC_CX_BCR] = { 0x9104 }, + [GPU_CC_FAST_HUB_BCR] = { 0x93e4 }, + [GPU_CC_FF_BCR] = { 0x9470 }, + [GPU_CC_GFX3D_AON_BCR] = { 0x9198 }, + [GPU_CC_GMU_BCR] = { 0x9314 }, + [GPU_CC_GX_BCR] = { 0x9058 }, + [GPU_CC_XO_BCR] = { 0x9000 }, +}; + +static const struct regmap_config gpu_cc_x1p42100_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9988, + .fast_io = true, +}; + +static struct qcom_cc_desc gpu_cc_x1p42100_desc = { + .config = &gpu_cc_x1p42100_regmap_config, + .clks = gpu_cc_x1p42100_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_x1p42100_clocks), + .resets = gpu_cc_x1p42100_resets, + .num_resets = ARRAY_SIZE(gpu_cc_x1p42100_resets), + .gdscs = gpu_cc_x1p42100_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_x1p42100_gdscs), +}; + +static const struct of_device_id gpu_cc_x1p42100_match_table[] = { + { .compatible = "qcom,x1p42100-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_x1p42100_match_table); + +static int gpu_cc_x1p42100_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; + + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return ret; + + regmap = qcom_cc_map(pdev, &gpu_cc_x1p42100_desc); + if (IS_ERR(regmap)) { + pm_runtime_put(&pdev->dev); + return PTR_ERR(regmap); + } + + clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); + clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); + + /* Keep some clocks always enabled */ + qcom_branch_set_clk_en(regmap, 0x93a4); /* GPU_CC_CB_CLK */ + qcom_branch_set_clk_en(regmap, 0x9004); /* GPU_CC_CXO_AON_CLK */ + qcom_branch_set_clk_en(regmap, 0x900c); /* GPU_CC_DEMET_CLK */ + + ret = qcom_cc_really_probe(&pdev->dev, &gpu_cc_x1p42100_desc, regmap); + + pm_runtime_put(&pdev->dev); + + return ret; +} + +static struct platform_driver gpu_cc_x1p42100_driver = { + .probe = gpu_cc_x1p42100_probe, + .driver = { + .name = "gpucc-x1p42100", + .of_match_table = gpu_cc_x1p42100_match_table, + }, +}; + +module_platform_driver(gpu_cc_x1p42100_driver); + +MODULE_DESCRIPTION("QTI GPUCC X1P42100 Driver"); +MODULE_LICENSE("GPL"); From 967e011013eda287dbec9e8bd3a19ebe730b8a08 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Thu, 19 Dec 2024 22:30:10 +0530 Subject: [PATCH 11/81] clk: qcom: gcc-sm8550: Do not turn off PCIe GDSCs during gdsc_disable() With PWRSTS_OFF_ON, PCIe GDSCs are turned off during gdsc_disable(). This can happen during scenarios such as system suspend and breaks the resume of PCIe controllers from suspend. So use PWRSTS_RET_ON to indicate the GDSC driver to not turn off the GDSCs during gdsc_disable() and allow the hardware to transition the GDSCs to retention when the parent domain enters low power state during system suspend. Cc: stable@vger.kernel.org # 6.2 Fixes: 955f2ea3b9e9 ("clk: qcom: Add GCC driver for SM8550") Reported-by: Neil Armstrong Signed-off-by: Manivannan Sadhasivam Reviewed-by: Neil Armstrong Tested-by: Neil Armstrong # on QRD8550 Link: https://lore.kernel.org/r/20241219170011.70140-1-manivannan.sadhasivam@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sm8550.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c index 5abaeddd6afcc..862a9bf73bcb5 100644 --- a/drivers/clk/qcom/gcc-sm8550.c +++ b/drivers/clk/qcom/gcc-sm8550.c @@ -3003,7 +3003,7 @@ static struct gdsc pcie_0_gdsc = { .pd = { .name = "pcie_0_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3014,7 +3014,7 @@ static struct gdsc pcie_0_phy_gdsc = { .pd = { .name = "pcie_0_phy_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3025,7 +3025,7 @@ static struct gdsc pcie_1_gdsc = { .pd = { .name = "pcie_1_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3036,7 +3036,7 @@ static struct gdsc pcie_1_phy_gdsc = { .pd = { .name = "pcie_1_phy_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; From a57465766a91c6e173876f9cbb424340e214313f Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Thu, 19 Dec 2024 22:30:11 +0530 Subject: [PATCH 12/81] clk: qcom: gcc-sm8650: Do not turn off PCIe GDSCs during gdsc_disable() With PWRSTS_OFF_ON, PCIe GDSCs are turned off during gdsc_disable(). This can happen during scenarios such as system suspend and breaks the resume of PCIe controllers from suspend. So use PWRSTS_RET_ON to indicate the GDSC driver to not turn off the GDSCs during gdsc_disable() and allow the hardware to transition the GDSCs to retention when the parent domain enters low power state during system suspend. Cc: stable@vger.kernel.org # 6.8 Fixes: c58225b7e3d7 ("clk: qcom: add the SM8650 Global Clock Controller driver, part 1") Reported-by: Neil Armstrong Signed-off-by: Manivannan Sadhasivam Reviewed-by: Neil Armstrong Tested-by: Neil Armstrong # on QRD8650 Link: https://lore.kernel.org/r/20241219170011.70140-2-manivannan.sadhasivam@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sm8650.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/gcc-sm8650.c b/drivers/clk/qcom/gcc-sm8650.c index fd9d6544bdd53..9dd5c48f33bed 100644 --- a/drivers/clk/qcom/gcc-sm8650.c +++ b/drivers/clk/qcom/gcc-sm8650.c @@ -3437,7 +3437,7 @@ static struct gdsc pcie_0_gdsc = { .pd = { .name = "pcie_0_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, }; @@ -3448,7 +3448,7 @@ static struct gdsc pcie_0_phy_gdsc = { .pd = { .name = "pcie_0_phy_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, }; @@ -3459,7 +3459,7 @@ static struct gdsc pcie_1_gdsc = { .pd = { .name = "pcie_1_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, }; @@ -3470,7 +3470,7 @@ static struct gdsc pcie_1_phy_gdsc = { .pd = { .name = "pcie_1_phy_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, }; From e18e8bbb97f0a51459163cf8abe116cae64b7207 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 23 Aug 2024 17:38:43 +0200 Subject: [PATCH 13/81] clk: qcom: rpm: simplify locking with guard() Simplify error handling (less gotos) over locks with guard(). Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240823-cleanup-h-guard-clk-qcom-v1-1-68bb9601c9dd@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rpm.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/clk/qcom/clk-rpm.c b/drivers/clk/qcom/clk-rpm.c index 9da034f8f2ff5..ccc112c21667e 100644 --- a/drivers/clk/qcom/clk-rpm.c +++ b/drivers/clk/qcom/clk-rpm.c @@ -4,6 +4,7 @@ * Copyright (c) 2014, The Linux Foundation. All rights reserved. */ +#include #include #include #include @@ -224,10 +225,10 @@ static void clk_rpm_unprepare(struct clk_hw *hw) unsigned long active_rate, sleep_rate; int ret; - mutex_lock(&rpm_clk_lock); + guard(mutex)(&rpm_clk_lock); if (!r->rate) - goto out; + return; /* Take peer clock's rate into account only if it's enabled. */ if (peer->enabled) @@ -237,17 +238,14 @@ static void clk_rpm_unprepare(struct clk_hw *hw) active_rate = r->branch ? !!peer_rate : peer_rate; ret = clk_rpm_set_rate_active(r, active_rate); if (ret) - goto out; + return; sleep_rate = r->branch ? !!peer_sleep_rate : peer_sleep_rate; ret = clk_rpm_set_rate_sleep(r, sleep_rate); if (ret) - goto out; + return; r->enabled = false; - -out: - mutex_unlock(&rpm_clk_lock); } static int clk_rpm_xo_prepare(struct clk_hw *hw) @@ -324,12 +322,12 @@ static int clk_rpm_set_rate(struct clk_hw *hw, unsigned long active_rate, sleep_rate; unsigned long this_rate = 0, this_sleep_rate = 0; unsigned long peer_rate = 0, peer_sleep_rate = 0; - int ret = 0; + int ret; - mutex_lock(&rpm_clk_lock); + guard(mutex)(&rpm_clk_lock); if (!r->enabled) - goto out; + return 0; to_active_sleep(r, rate, &this_rate, &this_sleep_rate); @@ -341,19 +339,16 @@ static int clk_rpm_set_rate(struct clk_hw *hw, active_rate = max(this_rate, peer_rate); ret = clk_rpm_set_rate_active(r, active_rate); if (ret) - goto out; + return ret; sleep_rate = max(this_sleep_rate, peer_sleep_rate); ret = clk_rpm_set_rate_sleep(r, sleep_rate); if (ret) - goto out; + return ret; r->rate = rate; -out: - mutex_unlock(&rpm_clk_lock); - - return ret; + return 0; } static long clk_rpm_round_rate(struct clk_hw *hw, unsigned long rate, From e534612ec7e60989d5b32c90ea2b2f61e5abde0e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 23 Aug 2024 17:38:44 +0200 Subject: [PATCH 14/81] clk: qcom: smd-rpm: simplify locking with guard() Simplify error handling (less gotos) over locks with guard(). Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240823-cleanup-h-guard-clk-qcom-v1-2-68bb9601c9dd@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-smd-rpm.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 45c5255bcd11b..b8cd9f7301194 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -4,6 +4,7 @@ * Copyright (c) 2014, The Linux Foundation. All rights reserved. */ +#include #include #include #include @@ -309,10 +310,10 @@ static void clk_smd_rpm_unprepare(struct clk_hw *hw) unsigned long active_rate, sleep_rate; int ret; - mutex_lock(&rpm_smd_clk_lock); + guard(mutex)(&rpm_smd_clk_lock); if (!r->rate) - goto out; + return; /* Take peer clock's rate into account only if it's enabled. */ if (peer->enabled) @@ -322,17 +323,14 @@ static void clk_smd_rpm_unprepare(struct clk_hw *hw) active_rate = r->branch ? !!peer_rate : peer_rate; ret = clk_smd_rpm_set_rate_active(r, active_rate); if (ret) - goto out; + return; sleep_rate = r->branch ? !!peer_sleep_rate : peer_sleep_rate; ret = clk_smd_rpm_set_rate_sleep(r, sleep_rate); if (ret) - goto out; + return; r->enabled = false; - -out: - mutex_unlock(&rpm_smd_clk_lock); } static int clk_smd_rpm_set_rate(struct clk_hw *hw, unsigned long rate, @@ -345,10 +343,10 @@ static int clk_smd_rpm_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long peer_rate = 0, peer_sleep_rate = 0; int ret = 0; - mutex_lock(&rpm_smd_clk_lock); + guard(mutex)(&rpm_smd_clk_lock); if (!r->enabled) - goto out; + return 0; to_active_sleep(r, rate, &this_rate, &this_sleep_rate); @@ -360,19 +358,16 @@ static int clk_smd_rpm_set_rate(struct clk_hw *hw, unsigned long rate, active_rate = max(this_rate, peer_rate); ret = clk_smd_rpm_set_rate_active(r, active_rate); if (ret) - goto out; + return ret; sleep_rate = max(this_sleep_rate, peer_sleep_rate); ret = clk_smd_rpm_set_rate_sleep(r, sleep_rate); if (ret) - goto out; + return ret; r->rate = rate; -out: - mutex_unlock(&rpm_smd_clk_lock); - - return ret; + return 0; } static long clk_smd_rpm_round_rate(struct clk_hw *hw, unsigned long rate, From 7fe3067b885df61691660e53141a0fdb2cd14c48 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 23 Aug 2024 17:38:45 +0200 Subject: [PATCH 15/81] clk: qcom: spmi-pmic-div: simplify locking with guard() Simplify error handling (less gotos) over locks with guard(). Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240823-cleanup-h-guard-clk-qcom-v1-3-68bb9601c9dd@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-spmi-pmic-div.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/clk/qcom/clk-spmi-pmic-div.c b/drivers/clk/qcom/clk-spmi-pmic-div.c index f394031eb0e52..41a0a4f3b4fb3 100644 --- a/drivers/clk/qcom/clk-spmi-pmic-div.c +++ b/drivers/clk/qcom/clk-spmi-pmic-div.c @@ -3,6 +3,7 @@ */ #include +#include #include #include #include @@ -140,30 +141,26 @@ static int clk_spmi_pmic_div_set_rate(struct clk_hw *hw, unsigned long rate, { struct clkdiv *clkdiv = to_clkdiv(hw); unsigned int div_factor = div_to_div_factor(parent_rate / rate); - unsigned long flags; bool enabled; int ret; - spin_lock_irqsave(&clkdiv->lock, flags); + guard(spinlock_irqsave)(&clkdiv->lock); + enabled = is_spmi_pmic_clkdiv_enabled(clkdiv); if (enabled) { ret = spmi_pmic_clkdiv_set_enable_state(clkdiv, false); if (ret) - goto unlock; + return ret; } ret = regmap_update_bits(clkdiv->regmap, clkdiv->base + REG_DIV_CTL1, DIV_CTL1_DIV_FACTOR_MASK, div_factor); if (ret) - goto unlock; + return ret; if (enabled) ret = __spmi_pmic_clkdiv_set_enable_state(clkdiv, true, div_factor); - -unlock: - spin_unlock_irqrestore(&clkdiv->lock, flags); - return ret; } From 94465062260063143ab806cdd16d5e183643343d Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 22 Oct 2024 17:22:50 +0530 Subject: [PATCH 16/81] dt-bindings: clock: qcom-rpmhcc: Add RPMHCC bindings for QCS615 Add bindings and update documentation for clock rpmh driver on QCS615 SoCs. Acked-by: Krzysztof Kozlowski Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20241022-qcs615-clock-driver-v4-1-3d716ad0d987@quicinc.com Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml index a561a306b947a..a9cd33aef73b6 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml @@ -17,6 +17,7 @@ description: | properties: compatible: enum: + - qcom,qcs615-rpmh-clk - qcom,qdu1000-rpmh-clk - qcom,sa8775p-rpmh-clk - qcom,sar2130p-rpmh-clk From 42a1905a10d622ab0a4ff564b0117444f4384c35 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 22 Oct 2024 17:22:51 +0530 Subject: [PATCH 17/81] clk: qcom: rpmhcc: Add support for QCS615 Clocks Add the RPMHCC clocks required for QCS615 SoC. Reviewed-by: Dmitry Baryshkov Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20241022-qcs615-clock-driver-v4-2-3d716ad0d987@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rpmh.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index eefc322ce3679..0a326b675d0e0 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -807,6 +807,24 @@ static const struct clk_rpmh_desc clk_rpmh_x1e80100 = { .num_clks = ARRAY_SIZE(x1e80100_rpmh_clocks), }; +static struct clk_hw *qcs615_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, + [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, + [RPMH_LN_BB_CLK2] = &clk_rpmh_ln_bb_clk2_a2.hw, + [RPMH_LN_BB_CLK2_A] = &clk_rpmh_ln_bb_clk2_a2_ao.hw, + [RPMH_LN_BB_CLK3] = &clk_rpmh_ln_bb_clk3_a2.hw, + [RPMH_LN_BB_CLK3_A] = &clk_rpmh_ln_bb_clk3_a2_ao.hw, + [RPMH_RF_CLK1] = &clk_rpmh_rf_clk1_a.hw, + [RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_a_ao.hw, + [RPMH_RF_CLK2] = &clk_rpmh_rf_clk2_a.hw, + [RPMH_RF_CLK2_A] = &clk_rpmh_rf_clk2_a_ao.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_qcs615 = { + .clks = qcs615_rpmh_clocks, + .num_clks = ARRAY_SIZE(qcs615_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -890,6 +908,7 @@ static int clk_rpmh_probe(struct platform_device *pdev) } static const struct of_device_id clk_rpmh_match_table[] = { + { .compatible = "qcom,qcs615-rpmh-clk", .data = &clk_rpmh_qcs615}, { .compatible = "qcom,qdu1000-rpmh-clk", .data = &clk_rpmh_qdu1000}, { .compatible = "qcom,sa8775p-rpmh-clk", .data = &clk_rpmh_sa8775p}, { .compatible = "qcom,sar2130p-rpmh-clk", .data = &clk_rpmh_sar2130p}, From 39d6dcf67fe955eadd787052a8963837be801794 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 22 Oct 2024 17:22:53 +0530 Subject: [PATCH 18/81] clk: qcom: gcc: Add support for QCS615 GCC clocks Add the global clock controller support for QCS615 SoC. Signed-off-by: Taniya Das Reviewed-by: Imran Shaik Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20241022-qcs615-clock-driver-v4-4-3d716ad0d987@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-qcs615.c | 3034 +++++++++++++++++++++++++++++++++ 3 files changed, 3044 insertions(+) create mode 100644 drivers/clk/qcom/gcc-qcs615.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 32b34b22ef014..76950bd01153a 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -504,6 +504,15 @@ config QCS_GCC_8300 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, SD/UFS, PCIe etc. +config QCS_GCC_615 + tristate "QCS615 Global Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the global clock controller on QCS615 devices. + Say Y if you want to use multimedia devices or peripheral + devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc. + config SC_CAMCC_7180 tristate "SC7180 Camera Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 7b5dd918c705b..5666554484ed2 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -72,6 +72,7 @@ obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_QCM_GCC_2290) += gcc-qcm2290.o obj-$(CONFIG_QCM_DISPCC_2290) += dispcc-qcm2290.o obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o +obj-$(CONFIG_QCS_GCC_615) += gcc-qcs615.o obj-$(CONFIG_QCS_GCC_8300) += gcc-qcs8300.o obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o diff --git a/drivers/clk/qcom/gcc-qcs615.c b/drivers/clk/qcom/gcc-qcs615.c new file mode 100644 index 0000000000000..9695446bc2a3c --- /dev/null +++ b/drivers/clk/qcom/gcc-qcs615.c @@ -0,0 +1,3034 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#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 "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_GPLL0_OUT_AUX2_DIV, + P_GPLL0_OUT_MAIN, + P_GPLL3_OUT_MAIN, + P_GPLL3_OUT_MAIN_DIV, + P_GPLL4_OUT_MAIN, + P_GPLL6_OUT_MAIN, + P_GPLL7_OUT_MAIN, + P_GPLL8_OUT_MAIN, + P_SLEEP_CLK, +}; + +static struct clk_alpha_pll gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +/* Fixed divider clock of GPLL0 instead of PLL normal postdiv */ +static struct clk_fixed_factor gpll0_out_aux2_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data) { + .name = "gpll0_out_aux2_div", + .parent_data = &(const struct clk_parent_data) { + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll3 = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gpll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +/* Fixed divider clock of GPLL3 instead of PLL normal postdiv */ +static struct clk_fixed_factor gpll3_out_aux2_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data) { + .name = "gpll3_out_aux2_div", + .parent_data = &(const struct clk_parent_data) { + .hw = &gpll3.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll4 = { + .offset = 0x76000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gpll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll6 = { + .offset = 0x13000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gpll6", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll6_out_main[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll6_out_main = { + .offset = 0x13000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll6_out_main, + .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll6_out_main", + .parent_hws = (const struct clk_hw*[]) { + &gpll6.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static struct clk_alpha_pll gpll7 = { + .offset = 0x1a000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gpll7", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll8 = { + .offset = 0x1b000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gpll8", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll8_out_main[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll8_out_main = { + .offset = 0x1b000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll8_out_main, + .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll8_out_main", + .parent_hws = (const struct clk_hw*[]) { + &gpll8.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_AUX2_DIV, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2_div.hw }, +}; + +static const struct clk_parent_data gcc_parent_data_0_ao[] = { + { .index = DT_BI_TCXO_AO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL6_OUT_MAIN, 2 }, + { P_GPLL0_OUT_AUX2_DIV, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll6_out_main.clkr.hw }, + { .hw = &gpll0_out_aux2_div.hw }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GPLL0_OUT_AUX2_DIV, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .index = DT_SLEEP_CLK }, + { .hw = &gpll0_out_aux2_div.hw }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .index = DT_SLEEP_CLK }, +}; + +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_GPLL0_OUT_MAIN, 1 }, + { P_GPLL7_OUT_MAIN, 3 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL0_OUT_AUX2_DIV, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll7.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll0_out_aux2_div.hw }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL7_OUT_MAIN, 3 }, + { P_GPLL0_OUT_AUX2_DIV, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll7.clkr.hw }, + { .hw = &gpll0_out_aux2_div.hw }, +}; + +static const struct parent_map gcc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL3_OUT_MAIN_DIV, 4 }, + { P_GPLL0_OUT_AUX2_DIV, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll3_out_aux2_div.hw }, + { .hw = &gpll0_out_aux2_div.hw }, +}; + +static const struct parent_map gcc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL8_OUT_MAIN, 2 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL0_OUT_AUX2_DIV, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll8_out_main.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll0_out_aux2_div.hw }, +}; + +static const struct parent_map gcc_parent_map_9[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL3_OUT_MAIN, 4 }, +}; + +static const struct clk_parent_data gcc_parent_data_9[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { + .cmd_rcgr = 0x48014, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_cpuss_ahb_clk_src", + .parent_data = gcc_parent_data_0_ao, + .num_parents = ARRAY_SIZE(gcc_parent_data_0_ao), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0), + F(75000000, P_GPLL0_OUT_AUX2_DIV, 4, 0, 0), + F(125000000, P_GPLL7_OUT_MAIN, 4, 0, 0), + F(250000000, P_GPLL7_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac_ptp_clk_src = { + .cmd_rcgr = 0x6038, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_emac_ptp_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac_ptp_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac_rgmii_clk_src[] = { + F(2500000, P_BI_TCXO, 1, 25, 192), + F(5000000, P_BI_TCXO, 1, 25, 96), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_AUX2_DIV, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0), + F(75000000, P_GPLL0_OUT_AUX2_DIV, 4, 0, 0), + F(125000000, P_GPLL7_OUT_MAIN, 4, 0, 0), + F(250000000, P_GPLL7_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac_rgmii_clk_src = { + .cmd_rcgr = 0x601c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_emac_rgmii_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac_rgmii_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(25000000, P_GPLL0_OUT_AUX2_DIV, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp1_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x65004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp2_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x66004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_0_aux_clk_src = { + .cmd_rcgr = 0x6b02c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .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_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_phy_refgen_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = { + .cmd_rcgr = 0x6f014, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_phy_refgen_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_refgen_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 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), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = { + F(60000000, P_GPLL0_OUT_AUX2_DIV, 5, 0, 0), + F(133250000, P_GPLL3_OUT_MAIN_DIV, 4, 0, 0), + F(266500000, P_GPLL3_OUT_MAIN_DIV, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_qspi_core_clk_src = { + .cmd_rcgr = 0x4b008, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gcc_qspi_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qspi_core_clk_src", + .parent_data = gcc_parent_data_7, + .num_parents = ARRAY_SIZE(gcc_parent_data_7), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, P_GPLL0_OUT_AUX2_DIV, 1, 384, 15625), + F(14745600, P_GPLL0_OUT_AUX2_DIV, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GPLL0_OUT_AUX2_DIV, 1, 1536, 15625), + F(32000000, P_GPLL0_OUT_AUX2_DIV, 1, 8, 75), + F(48000000, P_GPLL0_OUT_AUX2_DIV, 1, 4, 25), + F(64000000, P_GPLL0_OUT_AUX2_DIV, 1, 16, 75), + F(75000000, P_GPLL0_OUT_AUX2_DIV, 4, 0, 0), + F(80000000, P_GPLL0_OUT_AUX2_DIV, 1, 4, 15), + F(96000000, P_GPLL0_OUT_AUX2_DIV, 1, 8, 25), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(102400000, P_GPLL0_OUT_AUX2_DIV, 1, 128, 375), + F(112000000, P_GPLL0_OUT_AUX2_DIV, 1, 28, 75), + F(117964800, P_GPLL0_OUT_AUX2_DIV, 1, 6144, 15625), + F(120000000, P_GPLL0_OUT_AUX2_DIV, 2.5, 0, 0), + F(128000000, P_GPLL6_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { + .cmd_rcgr = 0x17148, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { + .cmd_rcgr = 0x17278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { + .cmd_rcgr = 0x173a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { + .cmd_rcgr = 0x174d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { + .cmd_rcgr = 0x17608, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { + .cmd_rcgr = 0x17738, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { + .cmd_rcgr = 0x18148, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_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_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { + .cmd_rcgr = 0x18278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { + .cmd_rcgr = 0x183a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s2_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_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { + .cmd_rcgr = 0x184d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { + .cmd_rcgr = 0x18608, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_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_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { + .cmd_rcgr = 0x18738, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = { + F(144000, P_BI_TCXO, 16, 3, 25), + F(400000, P_BI_TCXO, 12, 1, 4), + F(20000000, P_GPLL0_OUT_AUX2_DIV, 5, 1, 3), + F(25000000, P_GPLL0_OUT_AUX2_DIV, 6, 1, 2), + F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2_DIV, 3, 0, 0), + F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0), + F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { + .cmd_rcgr = 0x12028, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_apps_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = { + F(75000000, P_GPLL0_OUT_AUX2_DIV, 4, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x12010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_AUX2_DIV, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2_DIV, 3, 0, 0), + F(202000000, P_GPLL8_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1400c, + .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), + .ops = &clk_rcg2_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = { + F(25000000, P_GPLL0_OUT_AUX2_DIV, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { + .cmd_rcgr = 0x77020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .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_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_AUX2_DIV, 8, 0, 0), + F(75000000, P_GPLL0_OUT_AUX2_DIV, 4, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { + .cmd_rcgr = 0x77048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .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_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x7707c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_pcie_0_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), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_AUX2_DIV, 8, 0, 0), + F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { + .cmd_rcgr = 0x77060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_unipro_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_unipro_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb20_sec_master_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + F(120000000, P_GPLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb20_sec_master_clk_src = { + .cmd_rcgr = 0xa601c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb20_sec_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_sec_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_usb20_sec_mock_utmi_clk_src = { + .cmd_rcgr = 0xa6034, + .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_usb20_sec_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb2_sec_phy_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb2_sec_phy_aux_clk_src = { + .cmd_rcgr = 0xa6060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_usb2_sec_phy_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb2_sec_phy_aux_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { + F(66666667, P_GPLL0_OUT_AUX2_DIV, 4.5, 0, 0), + F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0xf01c, + .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), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(20000000, P_GPLL0_OUT_AUX2_DIV, 15, 0, 0), + F(40000000, P_GPLL0_OUT_AUX2_DIV, 7.5, 0, 0), + F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0xf034, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_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), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0xf060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_usb2_sec_phy_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_vsensor_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_vsensor_clk_src = { + .cmd_rcgr = 0x7a018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_gcc_vsensor_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_vsensor_clk_src", + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { + .halt_reg = 0x770c0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x770c0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x770c0, + .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_usb2_sec_axi_clk = { + .halt_reg = 0xa6084, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xa6084, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb2_sec_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_sec_master_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 = 0xf07c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xf07c, + .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_ahb2phy_east_clk = { + .halt_reg = 0x6a008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6a008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x6a008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ahb2phy_east_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ahb2phy_west_clk = { + .halt_reg = 0x6a004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6a004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x6a004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ahb2phy_west_clk", + .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 = 0x52004, + .enable_mask = BIT(10), + .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 = 0xb030, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb030, + .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_ce1_ahb_clk = { + .halt_reg = 0x4100c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x4100c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ce1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_axi_clk = { + .halt_reg = 0x41008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ce1_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_clk = { + .halt_reg = 0x41004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ce1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb2_sec_axi_clk = { + .halt_reg = 0xa609c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xa609c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb2_sec_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_sec_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0xf078, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xf078, + .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_cpuss_ahb_clk = { + .halt_reg = 0x48000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cpuss_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_cpuss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_gpu_axi_clk = { + .halt_reg = 0x71154, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x71154, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ddrss_gpu_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpll0_out_aux2_div.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0xb038, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb038, + .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_emac_axi_clk = { + .halt_reg = 0x6010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac_ptp_clk = { + .halt_reg = 0x6034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac_ptp_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac_ptp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac_rgmii_clk = { + .halt_reg = 0x6018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac_rgmii_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac_rgmii_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac_slv_ahb_clk = { + .halt_reg = 0x6014, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x6014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x6014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac_slv_ahb_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_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpll0_out_aux2_div.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_iref_clk = { + .halt_reg = 0x8c010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_iref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_memnoc_gfx_clk = { + .halt_reg = 0x7100c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7100c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = { + .halt_reg = 0x71018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x71018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_snoc_dvm_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie0_phy_refgen_clk = { + .halt_reg = 0x6f02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6f02c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie0_phy_refgen_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_phy_refgen_clk_src.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 = 0x6b020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .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 = 0x6b01c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b01c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x5200c, + .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_clkref_clk = { + .halt_reg = 0x8c00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c00c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_mstr_axi_clk = { + .halt_reg = 0x6b018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .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_pipe_clk = { + .halt_reg = 0x6b024, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_axi_clk = { + .halt_reg = 0x6b014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x5200c, + .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 = 0x6b010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .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_pcie_phy_aux_clk = { + .halt_reg = 0x6f004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6f004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_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_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, + .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_prng_ahb_clk = { + .halt_reg = 0x34004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x34004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_prng_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = { + .halt_reg = 0xb018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xb018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb018, + .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_disp_ahb_clk = { + .halt_reg = 0xb020, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xb020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_disp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_pcie_ahb_clk = { + .halt_reg = 0x6b044, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_pcie_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = { + .halt_reg = 0xb014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xb014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb014, + .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_qspi_cnoc_periph_ahb_clk = { + .halt_reg = 0x4b000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4b000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qspi_cnoc_periph_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_core_clk = { + .halt_reg = 0x4b004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4b004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qspi_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qspi_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = { + .halt_reg = 0x17014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_clk = { + .halt_reg = 0x1700c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s0_clk = { + .halt_reg = 0x17144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s1_clk = { + .halt_reg = 0x17274, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s2_clk = { + .halt_reg = 0x173a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s3_clk = { + .halt_reg = 0x174d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s4_clk = { + .halt_reg = 0x17604, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s5_clk = { + .halt_reg = 0x17734, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = { + .halt_reg = 0x18014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .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 = 0x1800c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .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_s0_clk = { + .halt_reg = 0x18144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .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 = 0x18274, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .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 = 0x183a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .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 = 0x184d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .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 = 0x18604, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .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 = 0x18734, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .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_wrap_0_m_ahb_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_0_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = { + .halt_reg = 0x17008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_0_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = { + .halt_reg = 0x18004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_1_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { + .halt_reg = 0x18008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x18008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x5200c, + .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_rx1_usb2_clkref_clk = { + .halt_reg = 0x8c030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_rx1_usb2_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_rx3_usb2_clkref_clk = { + .halt_reg = 0x8c038, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8c038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_rx3_usb2_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x12008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x12004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc1_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x1200c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1200c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_ice_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc1_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x14008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14008, + .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_sys_noc_cpuss_ahb_clk = { + .halt_reg = 0x4819c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) { + .name = "gcc_sys_noc_cpuss_ahb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &gcc_cpuss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_clkref_clk = { + .halt_reg = 0x8c004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8c004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_card_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_mem_clkref_clk = { + .halt_reg = 0x8c000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_mem_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ahb_clk = { + .halt_reg = 0x77014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77014, + .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 = 0x77010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77010, + .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 = 0x77044, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77044, + .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 = 0x77078, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77078, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77078, + .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 = 0x7701c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x7701c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { + .halt_reg = 0x77018, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x77018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_unipro_core_clk = { + .halt_reg = 0x77040, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77040, + .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_usb20_sec_master_clk = { + .halt_reg = 0xa6010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xa6010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_sec_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_sec_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_sec_mock_utmi_clk = { + .halt_reg = 0xa6018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa6018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_sec_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_sec_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_sec_sleep_clk = { + .halt_reg = 0xa6014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa6014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_sec_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2_prim_clkref_clk = { + .halt_reg = 0x8c028, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8c028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb2_prim_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2_sec_clkref_clk = { + .halt_reg = 0x8c018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8c018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb2_sec_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2_sec_phy_aux_clk = { + .halt_reg = 0xa6050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa6050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb2_sec_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb2_sec_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2_sec_phy_com_aux_clk = { + .halt_reg = 0xa6054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa6054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb2_sec_phy_com_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb2_sec_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2_sec_phy_pipe_clk = { + .halt_reg = 0xa6058, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0xa6058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb2_sec_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0xf010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xf010, + .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 = 0xf018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf018, + .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_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 = 0xf014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_clkref_clk = { + .halt_reg = 0x8c014, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x8c014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_aux_clk = { + .halt_reg = 0xf050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf050, + .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 = 0xf054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf054, + .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 = 0xf058, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0xf058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sec_clkref_clk = { + .halt_reg = 0x8c008, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x8c008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_sec_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi0_clk = { + .halt_reg = 0xb024, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_hw *gcc_qcs615_hws[] = { + [GPLL0_OUT_AUX2_DIV] = &gpll0_out_aux2_div.hw, + [GPLL3_OUT_AUX2_DIV] = &gpll3_out_aux2_div.hw, +}; + +static struct gdsc emac_gdsc = { + .gdscr = 0x6004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "emac_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc pcie_0_gdsc = { + .gdscr = 0x6b004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "pcie_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ufs_phy_gdsc = { + .gdscr = 0x77004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "ufs_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc usb20_sec_gdsc = { + .gdscr = 0xa6004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "usb20_sec_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc usb30_prim_gdsc = { + .gdscr = 0xf004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc hlos1_vote_aggre_noc_mmu_audio_tbu_gdsc = { + .gdscr = 0x7d040, + .pd = { + .name = "hlos1_vote_aggre_noc_mmu_audio_tbu", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_aggre_noc_mmu_tbu1_gdsc = { + .gdscr = 0x7d044, + .pd = { + .name = "hlos1_vote_aggre_noc_mmu_tbu1", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_aggre_noc_mmu_tbu2_gdsc = { + .gdscr = 0x7d048, + .pd = { + .name = "hlos1_vote_aggre_noc_mmu_tbu2", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc = { + .gdscr = 0x7d04c, + .pd = { + .name = "hlos1_vote_aggre_noc_mmu_pcie_tbu", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = { + .gdscr = 0x7d050, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = { + .gdscr = 0x7d054, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_sf_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc = { + .gdscr = 0x7d058, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct clk_regmap *gcc_qcs615_clocks[] = { + [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, + [GCC_AGGRE_USB2_SEC_AXI_CLK] = &gcc_aggre_usb2_sec_axi_clk.clkr, + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, + [GCC_AHB2PHY_EAST_CLK] = &gcc_ahb2phy_east_clk.clkr, + [GCC_AHB2PHY_WEST_CLK] = &gcc_ahb2phy_west_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_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr, + [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr, + [GCC_CE1_CLK] = &gcc_ce1_clk.clkr, + [GCC_CFG_NOC_USB2_SEC_AXI_CLK] = &gcc_cfg_noc_usb2_sec_axi_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr, + [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr, + [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, + [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_EMAC_AXI_CLK] = &gcc_emac_axi_clk.clkr, + [GCC_EMAC_PTP_CLK] = &gcc_emac_ptp_clk.clkr, + [GCC_EMAC_PTP_CLK_SRC] = &gcc_emac_ptp_clk_src.clkr, + [GCC_EMAC_RGMII_CLK] = &gcc_emac_rgmii_clk.clkr, + [GCC_EMAC_RGMII_CLK_SRC] = &gcc_emac_rgmii_clk_src.clkr, + [GCC_EMAC_SLV_AHB_CLK] = &gcc_emac_slv_ahb_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, + [GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr, + [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr, + [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr, + [GCC_PCIE0_PHY_REFGEN_CLK] = &gcc_pcie0_phy_refgen_clk.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_CLKREF_CLK] = &gcc_pcie_0_clkref_clk.clkr, + [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr, + [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.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_PCIE_PHY_AUX_CLK] = &gcc_pcie_phy_aux_clk.clkr, + [GCC_PCIE_PHY_REFGEN_CLK_SRC] = &gcc_pcie_phy_refgen_clk_src.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_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr, + [GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr, + [GCC_QMIP_PCIE_AHB_CLK] = &gcc_qmip_pcie_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, + [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr, + [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr, + [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr, + [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr, + [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr, + [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr, + [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr, + [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr, + [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr, + [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr, + [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr, + [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr, + [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr, + [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr, + [GCC_QUPV3_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_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_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr, + [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr, + [GCC_RX3_USB2_CLKREF_CLK] = &gcc_rx3_usb2_clkref_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr, + [GCC_UFS_CARD_CLKREF_CLK] = &gcc_ufs_card_clkref_clk.clkr, + [GCC_UFS_MEM_CLKREF_CLK] = &gcc_ufs_mem_clkref_clk.clkr, + [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr, + [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr, + [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr, + [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_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.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_USB20_SEC_MASTER_CLK] = &gcc_usb20_sec_master_clk.clkr, + [GCC_USB20_SEC_MASTER_CLK_SRC] = &gcc_usb20_sec_master_clk_src.clkr, + [GCC_USB20_SEC_MOCK_UTMI_CLK] = &gcc_usb20_sec_mock_utmi_clk.clkr, + [GCC_USB20_SEC_MOCK_UTMI_CLK_SRC] = &gcc_usb20_sec_mock_utmi_clk_src.clkr, + [GCC_USB20_SEC_SLEEP_CLK] = &gcc_usb20_sec_sleep_clk.clkr, + [GCC_USB2_PRIM_CLKREF_CLK] = &gcc_usb2_prim_clkref_clk.clkr, + [GCC_USB2_SEC_CLKREF_CLK] = &gcc_usb2_sec_clkref_clk.clkr, + [GCC_USB2_SEC_PHY_AUX_CLK] = &gcc_usb2_sec_phy_aux_clk.clkr, + [GCC_USB2_SEC_PHY_AUX_CLK_SRC] = &gcc_usb2_sec_phy_aux_clk_src.clkr, + [GCC_USB2_SEC_PHY_COM_AUX_CLK] = &gcc_usb2_sec_phy_com_aux_clk.clkr, + [GCC_USB2_SEC_PHY_PIPE_CLK] = &gcc_usb2_sec_phy_pipe_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_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_SEC_CLKREF_CLK] = &gcc_usb3_sec_clkref_clk.clkr, + [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, + [GCC_VSENSOR_CLK_SRC] = &gcc_vsensor_clk_src.clkr, + [GPLL0] = &gpll0.clkr, + [GPLL3] = &gpll3.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL6] = &gpll6.clkr, + [GPLL6_OUT_MAIN] = &gpll6_out_main.clkr, + [GPLL7] = &gpll7.clkr, + [GPLL8] = &gpll8.clkr, + [GPLL8_OUT_MAIN] = &gpll8_out_main.clkr, +}; + +static struct gdsc *gcc_qcs615_gdscs[] = { + [EMAC_GDSC] = &emac_gdsc, + [PCIE_0_GDSC] = &pcie_0_gdsc, + [UFS_PHY_GDSC] = &ufs_phy_gdsc, + [USB20_SEC_GDSC] = &usb20_sec_gdsc, + [USB30_PRIM_GDSC] = &usb30_prim_gdsc, + [HLOS1_VOTE_AGGRE_NOC_MMU_AUDIO_TBU_GDSC] = &hlos1_vote_aggre_noc_mmu_audio_tbu_gdsc, + [HLOS1_VOTE_AGGRE_NOC_MMU_TBU1_GDSC] = &hlos1_vote_aggre_noc_mmu_tbu1_gdsc, + [HLOS1_VOTE_AGGRE_NOC_MMU_TBU2_GDSC] = &hlos1_vote_aggre_noc_mmu_tbu2_gdsc, + [HLOS1_VOTE_AGGRE_NOC_MMU_PCIE_TBU_GDSC] = &hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_sf_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc, +}; + +static const struct qcom_reset_map gcc_qcs615_resets[] = { + [GCC_EMAC_BCR] = { 0x6000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0xd000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0xd004 }, + [GCC_USB30_PRIM_BCR] = { 0xf000 }, + [GCC_USB2_PHY_SEC_BCR] = { 0x50018 }, + [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50020 }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x5001c }, + [GCC_PCIE_0_BCR] = { 0x6b000 }, + [GCC_PCIE_0_PHY_BCR] = { 0x6c01c }, + [GCC_PCIE_PHY_BCR] = { 0x6f000 }, + [GCC_PCIE_PHY_COM_BCR] = { 0x6f010 }, + [GCC_UFS_PHY_BCR] = { 0x77000 }, + [GCC_USB20_SEC_BCR] = { 0xa6000 }, + [GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x50008 }, + [GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x50000 }, + [GCC_SDCC1_BCR] = { 0x12000 }, + [GCC_SDCC2_BCR] = { 0x14000 }, +}; + +static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_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_s2_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), +}; + +static const struct regmap_config gcc_qcs615_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xa609c, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_qcs615_desc = { + .config = &gcc_qcs615_regmap_config, + .clk_hws = gcc_qcs615_hws, + .num_clk_hws = ARRAY_SIZE(gcc_qcs615_hws), + .clks = gcc_qcs615_clocks, + .num_clks = ARRAY_SIZE(gcc_qcs615_clocks), + .resets = gcc_qcs615_resets, + .num_resets = ARRAY_SIZE(gcc_qcs615_resets), + .gdscs = gcc_qcs615_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_qcs615_gdscs), +}; + +static const struct of_device_id gcc_qcs615_match_table[] = { + { .compatible = "qcom,qcs615-gcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_qcs615_match_table); + +static int gcc_qcs615_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + regmap = qcom_cc_map(pdev, &gcc_qcs615_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + /* + * Disable the GPLL0 active input to MM blocks and GPU + * via MISC registers. + */ + regmap_update_bits(regmap, 0x0b084, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x9b000, BIT(0), BIT(0)); + + /* Keep some clocks always enabled */ + qcom_branch_set_clk_en(regmap, 0xb008); /* GCC_CAMERA_AHB_CLK */ + qcom_branch_set_clk_en(regmap, 0xb044); /* GCC_CAMERA_XO_CLK */ + qcom_branch_set_clk_en(regmap, 0xb00c); /* GCC_DISP_AHB_CLK */ + qcom_branch_set_clk_en(regmap, 0xb048); /* GCC_DISP_XO_CLK */ + qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */ + qcom_branch_set_clk_en(regmap, 0xb004); /* GCC_VIDEO_AHB_CLK */ + qcom_branch_set_clk_en(regmap, 0xb040); /* GCC_VIDEO_XO_CLK */ + qcom_branch_set_clk_en(regmap, 0x480040); /* GCC_CPUSS_GNOC_CLK */ + + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, + ARRAY_SIZE(gcc_dfs_clocks)); + if (ret) + return ret; + + return qcom_cc_really_probe(&pdev->dev, &gcc_qcs615_desc, regmap); +} + +static struct platform_driver gcc_qcs615_driver = { + .probe = gcc_qcs615_probe, + .driver = { + .name = "gcc-qcs615", + .of_match_table = gcc_qcs615_match_table, + }, +}; + +static int __init gcc_qcs615_init(void) +{ + return platform_driver_register(&gcc_qcs615_driver); +} +subsys_initcall(gcc_qcs615_init); + +static void __exit gcc_qcs615_exit(void) +{ + platform_driver_unregister(&gcc_qcs615_driver); +} +module_exit(gcc_qcs615_exit); + +MODULE_DESCRIPTION("QTI GCC QCS615 Driver"); +MODULE_LICENSE("GPL"); From a9b7c84d22fb1687d63ca2a386773015cf59436b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 12 Nov 2024 02:36:54 +0100 Subject: [PATCH 19/81] clk: imx8mp: Fix clkout1/2 support The CLKOUTn may be fed from PLL1/2/3, but the PLL1/2/3 has to be enabled first by setting PLL_CLKE bit 11 in CCM_ANALOG_SYS_PLLn_GEN_CTRL register. The CCM_ANALOG_SYS_PLLn_GEN_CTRL bit 11 is modeled by plln_out clock. Fix the clock tree and place the clkout1/2 under plln_sel instead of plain plln to let the clock subsystem correctly control the bit 11 and enable the PLL in case the CLKOUTn is supplied by PLL1/2/3. Fixes: 43896f56b59e ("clk: imx8mp: add clkout1/2 support") Signed-off-by: Marek Vasut Reviewed-by: Peng Fan Link: https://lore.kernel.org/r/20241112013718.333771-1-marex@denx.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index 516dbd170c8a3..fb18f507f1213 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -399,8 +399,9 @@ static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_r static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out", "dummy", "dummy", "gpu_pll_out", "vpu_pll_out", - "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3", - "dummy", "dummy", "osc_24m", "dummy", "osc_32k"}; + "arm_pll_out", "sys_pll1_out", "sys_pll2_out", + "sys_pll3_out", "dummy", "dummy", "osc_24m", + "dummy", "osc_32k"}; static struct clk_hw **hws; static struct clk_hw_onecell_data *clk_hw_data; From b7f67545ca9fa13f6e12debd68a92c1c664e2e3b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 12 Nov 2024 02:37:35 +0100 Subject: [PATCH 20/81] clk: imx: pll14xx: Add 208 MHz and 416 MHz entries for PLL1416x The PLL1416x is used to implement SYS_PLL3 on i.MX8MP and can be used to drive CLKOUTn clock. Add 208 MHz and 416 MHz entries to the PLL so they can be generated by the PLL and used to produce e.g. 13 MHz or 26 MHz on CLKOUTn output. Signed-off-by: Marek Vasut Reviewed-by: Peng Fan Link: https://lore.kernel.org/r/20241112013805.333798-1-marex@denx.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-pll14xx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index d63564dbb12ca..f290981ea13bd 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -56,7 +56,9 @@ static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = { PLL_1416X_RATE(700000000U, 350, 3, 2), PLL_1416X_RATE(640000000U, 320, 3, 2), PLL_1416X_RATE(600000000U, 300, 3, 2), + PLL_1416X_RATE(416000000U, 208, 3, 2), PLL_1416X_RATE(320000000U, 160, 3, 2), + PLL_1416X_RATE(208000000U, 208, 3, 3), }; static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = { From 32e9dea2645fa10dfa08b4e333918affaf1e4de5 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 19 Nov 2024 09:58:03 +0800 Subject: [PATCH 21/81] dt-bindings: clock: imx93: Add SPDIF IPG clk Add SPDIF IPG clk. The SPDIF IPG clock and root clock share same clock gate. Fixes: 1c4a4f7362fd ("arm64: dts: imx93: Add audio device nodes") Signed-off-by: Shengjiu Wang Reviewed-by: Frank Li Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20241119015805.3840606-2-shengjiu.wang@nxp.com Signed-off-by: Abel Vesa --- include/dt-bindings/clock/imx93-clock.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/clock/imx93-clock.h b/include/dt-bindings/clock/imx93-clock.h index 6c685067288b5..c393fad3a3469 100644 --- a/include/dt-bindings/clock/imx93-clock.h +++ b/include/dt-bindings/clock/imx93-clock.h @@ -209,5 +209,6 @@ #define IMX91_CLK_ENET2_REGULAR 204 #define IMX91_CLK_ENET2_REGULAR_GATE 205 #define IMX91_CLK_ENET1_QOS_TSN_GATE 206 +#define IMX93_CLK_SPDIF_IPG 207 #endif From 6a7853544482e2336b5b8bb9a4b964f9d687f290 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 19 Nov 2024 09:58:04 +0800 Subject: [PATCH 22/81] clk: imx93: Add IMX93_CLK_SPDIF_IPG clock Split IMX93_CLK_SPDIF_IPG from IMX93_CLK_SPDIF_GATE because the IMX93_CLK_SPDIF_GATE controls the gate of IPG clock and root clock. Without this change, disabling IMX93_CLK_SPDIF_GATE would also disable the IPG clock, causing register access failures. Fixes: 1c4a4f7362fd ("arm64: dts: imx93: Add audio device nodes") Signed-off-by: Shengjiu Wang Reviewed-by: Frank Li Link: https://lore.kernel.org/r/20241119015805.3840606-3-shengjiu.wang@nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx93.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c index 58a516dd385bf..eb818db008fb6 100644 --- a/drivers/clk/imx/clk-imx93.c +++ b/drivers/clk/imx/clk-imx93.c @@ -15,7 +15,7 @@ #include "clk.h" -#define IMX93_CLK_END 207 +#define IMX93_CLK_END 208 #define PLAT_IMX93 BIT(0) #define PLAT_IMX91 BIT(1) @@ -38,6 +38,7 @@ static u32 share_count_sai2; static u32 share_count_sai3; static u32 share_count_mub; static u32 share_count_pdm; +static u32 share_count_spdif; static const char * const a55_core_sels[] = {"a55_alt", "arm_pll"}; static const char *parent_names[MAX_SEL][4] = { @@ -252,7 +253,8 @@ static const struct imx93_clk_ccgr { { IMX93_CLK_MQS1_GATE, "mqs1", "sai1_root", 0x9b00, }, { IMX93_CLK_MQS2_GATE, "mqs2", "sai3_root", 0x9b40, }, { IMX93_CLK_AUD_XCVR_GATE, "aud_xcvr", "audio_xcvr_root", 0x9b80, }, - { IMX93_CLK_SPDIF_GATE, "spdif", "spdif_root", 0x9c00, }, + { IMX93_CLK_SPDIF_IPG, "spdif_ipg_clk", "bus_wakeup_root", 0x9c00, 0, &share_count_spdif}, + { IMX93_CLK_SPDIF_GATE, "spdif", "spdif_root", 0x9c00, 0, &share_count_spdif}, { IMX93_CLK_HSIO_32K_GATE, "hsio_32k", "osc_32k", 0x9dc0, }, { IMX93_CLK_ENET1_GATE, "enet1", "wakeup_axi_root", 0x9e00, 0, NULL, PLAT_IMX93, }, { IMX93_CLK_ENET_QOS_GATE, "enet_qos", "wakeup_axi_root", 0x9e40, 0, NULL, PLAT_IMX93, }, From 570b890e66334f283710af36feb2115f16c7a27c Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 19 Nov 2024 09:58:05 +0800 Subject: [PATCH 23/81] arm64: dts: imx93: Use IMX93_CLK_SPDIF_IPG as SPDIF IPG clock IMX93_CLK_BUS_WAKEUP is not accurate IPG clock, which missed the clock gate part. IMX93_CLK_SPDIF_IPG is the correct clock. Fixes: 1c4a4f7362fd ("arm64: dts: imx93: Add audio device nodes") Signed-off-by: Shengjiu Wang Reviewed-by: Frank Li Acked-by: Shawn Guo Link: https://lore.kernel.org/r/20241119015805.3840606-4-shengjiu.wang@nxp.com Signed-off-by: Abel Vesa --- arch/arm64/boot/dts/freescale/imx93.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi index 688488de8cd28..56766fdb0b1e5 100644 --- a/arch/arm64/boot/dts/freescale/imx93.dtsi +++ b/arch/arm64/boot/dts/freescale/imx93.dtsi @@ -925,7 +925,7 @@ reg-names = "ram", "regs", "rxfifo", "txfifo"; interrupts = , ; - clocks = <&clk IMX93_CLK_BUS_WAKEUP>, + clocks = <&clk IMX93_CLK_SPDIF_IPG>, <&clk IMX93_CLK_SPDIF_GATE>, <&clk IMX93_CLK_DUMMY>, <&clk IMX93_CLK_AUD_XCVR_GATE>; From 48806be086360846bb308c5ee21fcab8405a3da7 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 25 Dec 2024 08:14:43 +0800 Subject: [PATCH 24/81] clk: imx: Apply some clks only for i.MX93 Enable the LVDS gate, MIPI DSI, PXP, FLEXIO and MU only for i.MX93, because i.MX91 does not support them. Update enet clk entry format to align with others. Fixes: a27bfff88dd2 ("clk: imx: add i.MX91 clk") Signed-off-by: Peng Fan Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20241225001443.883131-1-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx93.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c index eb818db008fb6..c5f358a75f307 100644 --- a/drivers/clk/imx/clk-imx93.c +++ b/drivers/clk/imx/clk-imx93.c @@ -71,8 +71,8 @@ static const struct imx93_clk_root { { IMX93_CLK_WAKEUP_AXI, "wakeup_axi_root", 0x0380, FAST_SEL, CLK_IS_CRITICAL }, { IMX93_CLK_SWO_TRACE, "swo_trace_root", 0x0400, LOW_SPEED_IO_SEL, }, { IMX93_CLK_M33_SYSTICK, "m33_systick_root", 0x0480, LOW_SPEED_IO_SEL, 0, PLAT_IMX93, }, - { IMX93_CLK_FLEXIO1, "flexio1_root", 0x0500, LOW_SPEED_IO_SEL, }, - { IMX93_CLK_FLEXIO2, "flexio2_root", 0x0580, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_FLEXIO1, "flexio1_root", 0x0500, LOW_SPEED_IO_SEL, 0, PLAT_IMX93, }, + { IMX93_CLK_FLEXIO2, "flexio2_root", 0x0580, LOW_SPEED_IO_SEL, 0, PLAT_IMX93, }, { IMX93_CLK_LPTMR1, "lptmr1_root", 0x0700, LOW_SPEED_IO_SEL, }, { IMX93_CLK_LPTMR2, "lptmr2_root", 0x0780, LOW_SPEED_IO_SEL, }, { IMX93_CLK_TPM2, "tpm2_root", 0x0880, TPM_SEL, }, @@ -178,10 +178,10 @@ static const struct imx93_clk_ccgr { { IMX93_CLK_WDOG5_GATE, "wdog5", "osc_24m", 0x8400, }, { IMX93_CLK_SEMA1_GATE, "sema1", "bus_aon_root", 0x8440, }, { IMX93_CLK_SEMA2_GATE, "sema2", "bus_wakeup_root", 0x8480, }, - { IMX93_CLK_MU1_A_GATE, "mu1_a", "bus_aon_root", 0x84c0, CLK_IGNORE_UNUSED }, - { IMX93_CLK_MU2_A_GATE, "mu2_a", "bus_wakeup_root", 0x84c0, CLK_IGNORE_UNUSED }, - { IMX93_CLK_MU1_B_GATE, "mu1_b", "bus_aon_root", 0x8500, 0, &share_count_mub }, - { IMX93_CLK_MU2_B_GATE, "mu2_b", "bus_wakeup_root", 0x8500, 0, &share_count_mub }, + { IMX93_CLK_MU1_A_GATE, "mu1_a", "bus_aon_root", 0x84c0, CLK_IGNORE_UNUSED, NULL, PLAT_IMX93 }, + { IMX93_CLK_MU2_A_GATE, "mu2_a", "bus_wakeup_root", 0x84c0, CLK_IGNORE_UNUSED, NULL, PLAT_IMX93 }, + { IMX93_CLK_MU1_B_GATE, "mu1_b", "bus_aon_root", 0x8500, 0, &share_count_mub, PLAT_IMX93 }, + { IMX93_CLK_MU2_B_GATE, "mu2_b", "bus_wakeup_root", 0x8500, 0, &share_count_mub, PLAT_IMX93 }, { IMX93_CLK_EDMA1_GATE, "edma1", "m33_root", 0x8540, }, { IMX93_CLK_EDMA2_GATE, "edma2", "wakeup_axi_root", 0x8580, }, { IMX93_CLK_FLEXSPI1_GATE, "flexspi1", "flexspi1_root", 0x8640, }, @@ -189,8 +189,8 @@ static const struct imx93_clk_ccgr { { IMX93_CLK_GPIO2_GATE, "gpio2", "bus_wakeup_root", 0x88c0, }, { IMX93_CLK_GPIO3_GATE, "gpio3", "bus_wakeup_root", 0x8900, }, { IMX93_CLK_GPIO4_GATE, "gpio4", "bus_wakeup_root", 0x8940, }, - { IMX93_CLK_FLEXIO1_GATE, "flexio1", "flexio1_root", 0x8980, }, - { IMX93_CLK_FLEXIO2_GATE, "flexio2", "flexio2_root", 0x89c0, }, + { IMX93_CLK_FLEXIO1_GATE, "flexio1", "flexio1_root", 0x8980, 0, NULL, PLAT_IMX93}, + { IMX93_CLK_FLEXIO2_GATE, "flexio2", "flexio2_root", 0x89c0, 0, NULL, PLAT_IMX93}, { IMX93_CLK_LPIT1_GATE, "lpit1", "bus_aon_root", 0x8a00, }, { IMX93_CLK_LPIT2_GATE, "lpit2", "bus_wakeup_root", 0x8a40, }, { IMX93_CLK_LPTMR1_GATE, "lptmr1", "lptmr1_root", 0x8a80, }, @@ -239,10 +239,10 @@ static const struct imx93_clk_ccgr { { IMX93_CLK_SAI3_GATE, "sai3", "sai3_root", 0x94c0, 0, &share_count_sai3}, { IMX93_CLK_SAI3_IPG, "sai3_ipg_clk", "bus_wakeup_root", 0x94c0, 0, &share_count_sai3}, { IMX93_CLK_MIPI_CSI_GATE, "mipi_csi", "media_apb_root", 0x9580, }, - { IMX93_CLK_MIPI_DSI_GATE, "mipi_dsi", "media_apb_root", 0x95c0, }, - { IMX93_CLK_LVDS_GATE, "lvds", "media_ldb_root", 0x9600, }, + { IMX93_CLK_MIPI_DSI_GATE, "mipi_dsi", "media_apb_root", 0x95c0, 0, NULL, PLAT_IMX93 }, + { IMX93_CLK_LVDS_GATE, "lvds", "media_ldb_root", 0x9600, 0, NULL, PLAT_IMX93 }, { IMX93_CLK_LCDIF_GATE, "lcdif", "media_apb_root", 0x9640, }, - { IMX93_CLK_PXP_GATE, "pxp", "media_apb_root", 0x9680, }, + { IMX93_CLK_PXP_GATE, "pxp", "media_apb_root", 0x9680, 0, NULL, PLAT_IMX93 }, { IMX93_CLK_ISI_GATE, "isi", "media_apb_root", 0x96c0, }, { IMX93_CLK_NIC_MEDIA_GATE, "nic_media", "media_axi_root", 0x9700, }, { IMX93_CLK_USB_CONTROLLER_GATE, "usb_controller", "hsio_root", 0x9a00, }, @@ -258,8 +258,8 @@ static const struct imx93_clk_ccgr { { IMX93_CLK_HSIO_32K_GATE, "hsio_32k", "osc_32k", 0x9dc0, }, { IMX93_CLK_ENET1_GATE, "enet1", "wakeup_axi_root", 0x9e00, 0, NULL, PLAT_IMX93, }, { IMX93_CLK_ENET_QOS_GATE, "enet_qos", "wakeup_axi_root", 0x9e40, 0, NULL, PLAT_IMX93, }, - { IMX91_CLK_ENET2_REGULAR_GATE, "enet2_regular", "wakeup_axi_root", 0x9e00, 0, NULL, PLAT_IMX91, }, - { IMX91_CLK_ENET1_QOS_TSN_GATE, "enet1_qos_tsn", "wakeup_axi_root", 0x9e40, 0, NULL, PLAT_IMX91, }, + { IMX91_CLK_ENET2_REGULAR_GATE, "enet2_regular", "wakeup_axi_root", 0x9e00, 0, NULL, PLAT_IMX91, }, + { IMX91_CLK_ENET1_QOS_TSN_GATE, "enet1_qos_tsn", "wakeup_axi_root", 0x9e40, 0, NULL, PLAT_IMX91, }, /* Critical because clk accessed during CPU idle */ { IMX93_CLK_SYS_CNT_GATE, "sys_cnt", "osc_24m", 0x9e80, CLK_IS_CRITICAL}, { IMX93_CLK_TSTMR1_GATE, "tstmr1", "bus_aon_root", 0x9ec0, }, From 89aa5925d201b90a48416784831916ca203658f9 Mon Sep 17 00:00:00 2001 From: Anastasia Belova Date: Tue, 3 Dec 2024 11:42:31 +0300 Subject: [PATCH 25/81] clk: qcom: clk-rpmh: prevent integer overflow in recalc_rate aggr_state and unit fields are u32. The result of their multiplication may not fit in this type. Add explicit casting to prevent overflow. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 04053f4d23a4 ("clk: qcom: clk-rpmh: Add IPA clock support") Cc: stable@vger.kernel.org # 5.4+ Signed-off-by: Anastasia Belova Link: https://lore.kernel.org/r/20241203084231.6001-1-abelova@astralinux.ru Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rpmh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 0a326b675d0e0..7c6b6ef642c11 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -329,7 +329,7 @@ static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw, { struct clk_rpmh *c = to_clk_rpmh(hw); - return c->aggr_state * c->unit; + return (unsigned long)c->aggr_state * c->unit; } static const struct clk_ops clk_rpmh_bcm_ops = { From 96fe1a7ee477d701cfc98ab9d3c730c35d966861 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Fri, 20 Dec 2024 10:03:30 +0100 Subject: [PATCH 26/81] clk: qcom: gcc-sm6350: Add missing parent_map for two clocks If a clk_rcg2 has a parent, it should also have parent_map defined, otherwise we'll get a NULL pointer dereference when calling clk_set_rate like the following: [ 3.388105] Call trace: [ 3.390664] qcom_find_src_index+0x3c/0x70 (P) [ 3.395301] qcom_find_src_index+0x1c/0x70 (L) [ 3.399934] _freq_tbl_determine_rate+0x48/0x100 [ 3.404753] clk_rcg2_determine_rate+0x1c/0x28 [ 3.409387] clk_core_determine_round_nolock+0x58/0xe4 [ 3.421414] clk_core_round_rate_nolock+0x48/0xfc [ 3.432974] clk_core_round_rate_nolock+0xd0/0xfc [ 3.444483] clk_core_set_rate_nolock+0x8c/0x300 [ 3.455886] clk_set_rate+0x38/0x14c Add the parent_map property for two clocks where it's missing and also un-inline the parent_data as well to keep the matching parent_map and parent_data together. Fixes: 131abae905df ("clk: qcom: Add SM6350 GCC driver") Cc: stable@vger.kernel.org Signed-off-by: Luca Weiss Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20241220-sm6350-parent_map-v1-1-64f3d04cb2eb@fairphone.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sm6350.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c index a811fad2aa278..74346dc026068 100644 --- a/drivers/clk/qcom/gcc-sm6350.c +++ b/drivers/clk/qcom/gcc-sm6350.c @@ -182,6 +182,14 @@ static const struct clk_parent_data gcc_parent_data_2_ao[] = { { .hw = &gpll0_out_odd.clkr.hw }, }; +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .fw_name = "bi_tcxo" }, +}; + static const struct parent_map gcc_parent_map_4[] = { { P_BI_TCXO, 0 }, { P_GPLL0_OUT_MAIN, 1 }, @@ -701,13 +709,12 @@ static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { .cmd_rcgr = 0x3a0b0, .mnd_width = 0, .hid_width = 5, + .parent_map = gcc_parent_map_3, .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_phy_aux_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", - }, - .num_parents = 1, + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), .ops = &clk_rcg2_ops, }, }; @@ -764,13 +771,12 @@ static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { .cmd_rcgr = 0x1a034, .mnd_width = 0, .hid_width = 5, + .parent_map = gcc_parent_map_3, .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb30_prim_mock_utmi_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", - }, - .num_parents = 1, + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), .ops = &clk_rcg2_ops, }, }; From d4cdb196f182d2fbe336c968228be00d8c3fed05 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Fri, 20 Dec 2024 10:03:31 +0100 Subject: [PATCH 27/81] clk: qcom: dispcc-sm6350: Add missing parent_map for a clock If a clk_rcg2 has a parent, it should also have parent_map defined, otherwise we'll get a NULL pointer dereference when calling clk_set_rate like the following: [ 3.388105] Call trace: [ 3.390664] qcom_find_src_index+0x3c/0x70 (P) [ 3.395301] qcom_find_src_index+0x1c/0x70 (L) [ 3.399934] _freq_tbl_determine_rate+0x48/0x100 [ 3.404753] clk_rcg2_determine_rate+0x1c/0x28 [ 3.409387] clk_core_determine_round_nolock+0x58/0xe4 [ 3.421414] clk_core_round_rate_nolock+0x48/0xfc [ 3.432974] clk_core_round_rate_nolock+0xd0/0xfc [ 3.444483] clk_core_set_rate_nolock+0x8c/0x300 [ 3.455886] clk_set_rate+0x38/0x14c Add the parent_map property for the clock where it's missing and also un-inline the parent_data as well to keep the matching parent_map and parent_data together. Fixes: 837519775f1d ("clk: qcom: Add display clock controller driver for SM6350") Cc: stable@vger.kernel.org Signed-off-by: Luca Weiss Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20241220-sm6350-parent_map-v1-2-64f3d04cb2eb@fairphone.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/dispcc-sm6350.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c index 50facb36701af..2bc6b5f99f572 100644 --- a/drivers/clk/qcom/dispcc-sm6350.c +++ b/drivers/clk/qcom/dispcc-sm6350.c @@ -187,13 +187,12 @@ static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { .cmd_rcgr = 0x1144, .mnd_width = 0, .hid_width = 5, + .parent_map = disp_cc_parent_map_6, .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "disp_cc_mdss_dp_aux_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", - }, - .num_parents = 1, + .parent_data = disp_cc_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), .ops = &clk_rcg2_ops, }, }; From 3e632d9c33d8a4f0d8f98e69b56bd2f2145d91c4 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Mon, 28 Oct 2024 19:48:15 +0100 Subject: [PATCH 28/81] clk: qcom: apss-ipq-pll: drop 'alpha_en_mask' from IPQ5018 PLL config Since neither 'alpha' nor 'alpha_hi' is defined in the configuration, those will be initialized with zero values implicitly. By using zero alpha values, the output rate of the PLL will be the same whether alpha mode is enabled or not. Remove the superfluous initialization of the 'alpha_en_mask' member to make it clear that enabling alpha mode is not required to get the desired output rate. Despite that enabling alpha mode is not needed for the initial configuration, the set_rate() op might require that it is enabled already. In this particular case however, the clk_alpha_pll_stromer_set_rate() function will get reset the ALPHA_EN bit when the PLL's rate changes, so dropping 'alpha_en_mask' is safe. No functional changes, the initial rate of the PLL is the same both before and after the patch. Tested on TP-Link Archer AX55 v1 (IPQ5018). Signed-off-by: Gabor Juhos Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20241028-alpha-mode-cleanup-v2-1-9bc6d712bd76@gmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/apss-ipq-pll.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/qcom/apss-ipq-pll.c b/drivers/clk/qcom/apss-ipq-pll.c index e8632db2c5428..dec2a5019cc77 100644 --- a/drivers/clk/qcom/apss-ipq-pll.c +++ b/drivers/clk/qcom/apss-ipq-pll.c @@ -73,7 +73,6 @@ static const struct alpha_pll_config ipq5018_pll_config = { .main_output_mask = BIT(0), .aux_output_mask = BIT(1), .early_output_mask = BIT(3), - .alpha_en_mask = BIT(24), .status_val = 0x3, .status_mask = GENMASK(10, 8), .lock_det = BIT(2), From 41c5ebfb9b4b42b1479f16a50d96146fa945abce Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Mon, 28 Oct 2024 19:48:16 +0100 Subject: [PATCH 29/81] clk: qcom: apps-ipq-pll: drop 'alpha_en_mask' from IPQ5332 PLL config Since neither 'alpha' nor 'alpha_hi' is defined in the configuration, those will be initialized with zero values implicitly. By using zero alpha values, the output rate of the PLL will be the same whether alpha mode is enabled or not. Remove the superfluous initialization of the 'alpha_en_mask' member to make it clear that enabling alpha mode is not required to get the desired output rate. Despite that enabling alpha mode is not needed for the initial configuration, the set_rate() op might require that it is enabled already. In this particular case however, the clk_alpha_pll_stromer_plus_set_rate() function will get reset the ALPHA_EN bit when the PLL's rate changes, so dropping 'alpha_en_mask' is safe. While at it, also add a comment to indicate the frequency the PLL runs at with the current configuration. No functional changes, the initial rate of the PLL is the same both before and after the patch. Tested on Xiaomi Router BE3600 2.5G (IPQ5312, out-of-tree board). Reviewed-by: Dmitry Baryshkov Signed-off-by: Gabor Juhos Link: https://lore.kernel.org/r/20241028-alpha-mode-cleanup-v2-2-9bc6d712bd76@gmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/apss-ipq-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/apss-ipq-pll.c b/drivers/clk/qcom/apss-ipq-pll.c index dec2a5019cc77..d6c1aea7e9e1e 100644 --- a/drivers/clk/qcom/apss-ipq-pll.c +++ b/drivers/clk/qcom/apss-ipq-pll.c @@ -79,13 +79,13 @@ static const struct alpha_pll_config ipq5018_pll_config = { .test_ctl_hi_val = 0x00400003, }; +/* 1.080 GHz configuration */ static const struct alpha_pll_config ipq5332_pll_config = { .l = 0x2d, .config_ctl_val = 0x4001075b, .main_output_mask = BIT(0), .aux_output_mask = BIT(1), .early_output_mask = BIT(3), - .alpha_en_mask = BIT(24), .status_val = 0x3, .status_mask = GENMASK(10, 8), .lock_det = BIT(2), From 5d11fd2a919b153c68cda42c175b4e45668654a9 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Mon, 28 Oct 2024 19:48:17 +0100 Subject: [PATCH 30/81] clk: qcom: gcc-ipq6018: remove alpha values from NSS Crypto PLL's config Since both the 'alpha' and 'alpha_hi' members of the configuration is initialized with zero values, the output rate of the PLL will be the same whether alpha mode is enabled or not. Remove the initialization of the alpha* members to make it clear that alpha mode is not required to get the desired output rate. Despite that enabling alpha mode is not needed for the initial configuration, the set_rate() op might require that it is enabled already. In this particular case however, the clk_alpha_pll_set_rate() function will get reset the ALPHA_EN bit when the PLL's rate changes, so dropping 'alpha_en_mask' is safe. While at it, also add a comment to indicate the frequency the PLL runs at with the current configuration. No functional changes, the PLL runs at 1.2 GHz both before and after the change. Tested on Xiaomi Mi Router AX1800 (IPQ6018, out-of-tree board). Reviewed-by: Dmitry Baryshkov Signed-off-by: Gabor Juhos Link: https://lore.kernel.org/r/20241028-alpha-mode-cleanup-v2-3-9bc6d712bd76@gmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-ipq6018.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/qcom/gcc-ipq6018.c b/drivers/clk/qcom/gcc-ipq6018.c index ab0f7fc665a97..d861191b0c85c 100644 --- a/drivers/clk/qcom/gcc-ipq6018.c +++ b/drivers/clk/qcom/gcc-ipq6018.c @@ -4194,10 +4194,9 @@ static const struct alpha_pll_config ubi32_pll_config = { .test_ctl_hi_val = 0x4000, }; +/* 1200 MHz configuration */ static const struct alpha_pll_config nss_crypto_pll_config = { .l = 0x32, - .alpha = 0x0, - .alpha_hi = 0x0, .config_ctl_val = 0x4001055b, .main_output_mask = BIT(0), .pre_div_val = 0x0, @@ -4206,7 +4205,6 @@ static const struct alpha_pll_config nss_crypto_pll_config = { .post_div_mask = GENMASK(11, 8), .vco_mask = GENMASK(21, 20), .vco_val = 0x0, - .alpha_en_mask = BIT(24), }; static struct clk_hw *gcc_ipq6018_hws[] = { From b9286a91b59fe9c7f8e231fce8e51df3b1442f6b Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Mon, 28 Oct 2024 19:48:18 +0100 Subject: [PATCH 31/81] clk: qcom: dispcc-qcm2290: remove alpha values from disp_cc_pll0_config Since both the 'alpha' and 'alpha_hi' members of the configuration is initialized (the latter is implicitly) with zero values, the output rate of the PLL will be the same whether alpha mode is enabled or not. Remove the initialization of the alpha* members to make it clear that the alpha mode is not required to get the desired output rate. Despite that enabling alpha mode is not needed for the initial configuration, the set_rate() op might require that it is enabled already. In this particular case however, the clk_alpha_pll_set_rate() function will get reset the ALPHA_EN bit when the PLL's rate changes, so dropping 'alpha_en_mask' is safe. No functional changes intended, compile tested only. Signed-off-by: Gabor Juhos Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20241028-alpha-mode-cleanup-v2-4-9bc6d712bd76@gmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/dispcc-qcm2290.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/clk/qcom/dispcc-qcm2290.c b/drivers/clk/qcom/dispcc-qcm2290.c index 449ffea2295d3..d7bb1399e1022 100644 --- a/drivers/clk/qcom/dispcc-qcm2290.c +++ b/drivers/clk/qcom/dispcc-qcm2290.c @@ -40,8 +40,6 @@ static const struct pll_vco spark_vco[] = { /* 768MHz configuration */ static const struct alpha_pll_config disp_cc_pll0_config = { .l = 0x28, - .alpha = 0x0, - .alpha_en_mask = BIT(24), .vco_val = 0x2 << 20, .vco_mask = GENMASK(21, 20), .main_output_mask = BIT(0), From 320f7a476c5fe79f50d00c75debfd9f63a0e713f Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Mon, 28 Oct 2024 19:48:19 +0100 Subject: [PATCH 32/81] clk: qcom: dispcc-sm6115: remove alpha values from disp_cc_pll0_config Since both the 'alpha' and 'alpha_hi' members of the configuration is initialized (the latter is implicitly) with zero values, the output rate of the PLL will be the same whether alpha mode is enabled or not. Remove the initialization of the alpha* members to make it clear that the alpha mode is not required to get the desired output rate. Despite that enabling alpha mode is not needed for the initial configuration, the set_rate() op might require that it is enabled already. In this particular case however, the clk_alpha_pll_set_rate() function will get reset the ALPHA_EN bit when the PLL's rate changes, so dropping 'alpha_en_mask' is safe. No functional changes intended, compile tested only. Reviewed-by: Dmitry Baryshkov Signed-off-by: Gabor Juhos Link: https://lore.kernel.org/r/20241028-alpha-mode-cleanup-v2-5-9bc6d712bd76@gmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/dispcc-sm6115.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/clk/qcom/dispcc-sm6115.c b/drivers/clk/qcom/dispcc-sm6115.c index 939887f82ecc3..2b236d52b29fe 100644 --- a/drivers/clk/qcom/dispcc-sm6115.c +++ b/drivers/clk/qcom/dispcc-sm6115.c @@ -48,8 +48,6 @@ static const struct pll_vco spark_vco[] = { /* 768MHz configuration */ static const struct alpha_pll_config disp_cc_pll0_config = { .l = 0x28, - .alpha = 0x0, - .alpha_en_mask = BIT(24), .vco_val = 0x2 << 20, .vco_mask = GENMASK(21, 20), .main_output_mask = BIT(0), From 33f1722eb86e45320a3dd7b3d42f6593a1d595c2 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Mon, 21 Oct 2024 19:32:48 +0200 Subject: [PATCH 33/81] clk: qcom: clk-alpha-pll: fix alpha mode configuration Commit c45ae598fc16 ("clk: qcom: support for alpha mode configuration") added support for configuring alpha mode, but it seems that the feature was never working in practice. The value of the alpha_{en,mode}_mask members of the configuration gets added to the value parameter passed to the regmap_update_bits() function, however the same values are not getting applied to the bitmask. As the result, the respective bits in the USER_CTL register are never modifed which leads to improper configuration of several PLLs. The following table shows the PLL configurations where the 'alpha_en_mask' member is set and which are passed as a parameter for the clk_alpha_pll_configure() function. In the table the 'expected rate' column shows the rate the PLL should run at with the given configuration, and the 'real rate' column shows the rate the PLL runs at actually. The real rates has been verified on hardwareOn IPQ* platforms, on other platforms, those are computed values only. file pll expected rate real rate dispcc-qcm2290.c disp_cc_pll0 768.0 MHz 768.0 MHz dispcc-sm6115.c disp_cc_pll0 768.0 MHz 768.0 MHz gcc-ipq5018.c ubi32_pll 1000.0 MHz != 984.0 MHz gcc-ipq6018.c nss_crypto_pll 1200.0 MHz 1200.0 MHz gcc-ipq6018.c ubi32_pll 1497.6 MHz != 1488.0 MHz gcc-ipq8074.c nss_crypto_pll 1200.0 MHz != 1190.4 MHz gcc-qcm2290.c gpll11 532.0 MHz != 518.4 MHz gcc-qcm2290.c gpll8 533.2 MHz != 518.4 MHz gcc-qcs404.c gpll3 921.6 MHz 921.6 MHz gcc-sm6115.c gpll11 600.0 MHz != 595.2 MHz gcc-sm6115.c gpll8 800.0 MHz != 787.2 MHz gpucc-sdm660.c gpu_cc_pll0 800.0 MHz != 787.2 MHz gpucc-sdm660.c gpu_cc_pll1 740.0 MHz != 729.6 MHz gpucc-sm6115.c gpu_cc_pll0 1200.0 MHz != 1190.4 MHz gpucc-sm6115.c gpu_cc_pll1 640.0 MHz != 633.6 MHz gpucc-sm6125.c gpu_pll0 1020.0 MHz != 1017.6 MHz gpucc-sm6125.c gpu_pll1 930.0 MHz != 921.6 MHz mmcc-sdm660.c mmpll8 930.0 MHz != 921.6 MHz mmcc-sdm660.c mmpll5 825.0 MHz != 806.4 MHz As it can be seen from the above, there are several PLLs which are configured incorrectly. Change the code to apply both 'alpha_en_mask' and 'alpha_mode_mask' values to the bitmask in order to configure the alpha mode correctly. Applying the 'alpha_en_mask' fixes the initial rate of the PLLs showed in the table above. Since the 'alpha_mode_mask' is not used by any driver currently, that part of the change causes no functional changes. Cc: stable@vger.kernel.org Fixes: c45ae598fc16 ("clk: qcom: support for alpha mode configuration") Signed-off-by: Gabor Juhos Reviewed-by: Dmitry Baryshkov Tested-by: Gabor Juhos Link: https://lore.kernel.org/r/20241021-fix-alpha-mode-config-v1-1-f32c254e02bc@gmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-alpha-pll.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index b8351f8c0b840..35e97eab5d059 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -432,6 +432,8 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, mask |= config->pre_div_mask; mask |= config->post_div_mask; mask |= config->vco_mask; + mask |= config->alpha_en_mask; + mask |= config->alpha_mode_mask; regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val); From 1474149c4209943b37a2c01b82f07ba39465e5fe Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 26 Oct 2024 12:58:13 +0200 Subject: [PATCH 34/81] clk: qcom: Make GCC_8150 depend on QCOM_GDSC Like all other non-ancient Qualcomm clock drivers, QCOM_GDSC is required, as the GCC driver defines and instantiates a bunch of GDSCs. Add the missing dependency. Reported-by: Vladimir Zapolskiy Closes: https://lore.kernel.org/linux-arm-msm/ab85f2ae-6c97-4fbb-a15b-31cc9e1f77fc@linaro.org/ Signed-off-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Reviewed-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20241026-topic-8150gcc_kconfig-v1-1-3772013d8804@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 76950bd01153a..a96049605f0de 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1097,6 +1097,7 @@ config SM_GCC_7150 config SM_GCC_8150 tristate "SM8150 Global Clock Controller" depends on ARM64 || COMPILE_TEST + select QCOM_GDSC help Support for the global clock controller on SM8150 devices. Say Y if you want to use peripheral devices such as UART, From d9377941f2732d2f6f53ec9520321a19c687717a Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 27 Dec 2024 13:23:03 +0000 Subject: [PATCH 35/81] clk: qcom: camcc-x1e80100: Set titan_top_gdsc as the parent GDSC of subordinate GDSCs The Titan TOP GDSC is the parent GDSC for all other GDSCs in the CAMCC block. None of the subordinate blocks will switch on without the parent GDSC switched on. Fixes: 76126a5129b5 ("clk: qcom: Add camcc clock driver for x1e80100") Acked-by: Rajendra Nayak Reviewed-by: Konrad Dybcio Signed-off-by: Bryan O'Donoghue Reviewed-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20241227-b4-linux-next-24-12-16-titan-top-gdsc-v1-1-c96ef62fc307@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-x1e80100.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/clk/qcom/camcc-x1e80100.c b/drivers/clk/qcom/camcc-x1e80100.c index 85e76c7712ad8..b73524ae64b1b 100644 --- a/drivers/clk/qcom/camcc-x1e80100.c +++ b/drivers/clk/qcom/camcc-x1e80100.c @@ -2212,6 +2212,8 @@ static struct clk_branch cam_cc_sfe_0_fast_ahb_clk = { }, }; +static struct gdsc cam_cc_titan_top_gdsc; + static struct gdsc cam_cc_bps_gdsc = { .gdscr = 0x10004, .en_rest_wait_val = 0x2, @@ -2221,6 +2223,7 @@ static struct gdsc cam_cc_bps_gdsc = { .name = "cam_cc_bps_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -2233,6 +2236,7 @@ static struct gdsc cam_cc_ife_0_gdsc = { .name = "cam_cc_ife_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -2245,6 +2249,7 @@ static struct gdsc cam_cc_ife_1_gdsc = { .name = "cam_cc_ife_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -2257,6 +2262,7 @@ static struct gdsc cam_cc_ipe_0_gdsc = { .name = "cam_cc_ipe_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -2269,6 +2275,7 @@ static struct gdsc cam_cc_sfe_0_gdsc = { .name = "cam_cc_sfe_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; From 9a497710cab94140762bcfbd9b6dc2c45f30678b Mon Sep 17 00:00:00 2001 From: Ryan Wanner Date: Fri, 20 Dec 2024 14:07:09 -0700 Subject: [PATCH 36/81] clk: at91: sama7d65: add sama7d65 pmc driver Add clock support for SAMA7D65 SoC. Increase maximum number of valid master clocks. The PMC for the SAMA7D65 requires 9 master clocks. Increase maximum amount of PLLs to 9 to support SAMA7D65 SoC PLL requirements. Signed-off-by: Ryan Wanner Reviewed-by: Claudiu Beznea Link: https://lore.kernel.org/r/549fa8590fe9b4380e413f8eed87392f28754395.1734723585.git.Ryan.Wanner@microchip.com [claudiu.beznea: sorted alphanumerically the Makefile entries, reorder the code for resource cleanup in sama7d65_pmc_setup()] Signed-off-by: Claudiu Beznea --- drivers/clk/at91/Makefile | 1 + drivers/clk/at91/clk-master.c | 2 +- drivers/clk/at91/clk-sam9x60-pll.c | 2 +- drivers/clk/at91/pmc.c | 1 + drivers/clk/at91/sama7d65.c | 1375 ++++++++++++++++++++++++++++ 5 files changed, 1379 insertions(+), 2 deletions(-) create mode 100644 drivers/clk/at91/sama7d65.c diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile index 8e3684ba2c74e..9128a06b860dd 100644 --- a/drivers/clk/at91/Makefile +++ b/drivers/clk/at91/Makefile @@ -24,4 +24,5 @@ obj-$(CONFIG_SOC_SAM9X7) += sam9x7.o obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o dt-compat.o obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o dt-compat.o obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o dt-compat.o +obj-$(CONFIG_SOC_SAMA7D65) += sama7d65.o obj-$(CONFIG_SOC_SAMA7G5) += sama7g5.o diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index 15c46489ba850..7a544e429d34e 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c @@ -20,7 +20,7 @@ #define PMC_MCR_CSS_SHIFT (16) -#define MASTER_MAX_ID 4 +#define MASTER_MAX_ID 9 #define to_clk_master(hw) container_of(hw, struct clk_master, hw) diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c index fda0411022246..cefd9948e1039 100644 --- a/drivers/clk/at91/clk-sam9x60-pll.c +++ b/drivers/clk/at91/clk-sam9x60-pll.c @@ -23,7 +23,7 @@ #define UPLL_DIV 2 #define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1) -#define PLL_MAX_ID 7 +#define PLL_MAX_ID 9 struct sam9x60_pll_core { struct regmap *regmap; diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 5aa9c1f1c8866..acf780a815890 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -151,6 +151,7 @@ static struct syscore_ops pmc_syscore_ops = { static const struct of_device_id pmc_dt_ids[] = { { .compatible = "atmel,sama5d2-pmc" }, { .compatible = "microchip,sama7g5-pmc", }, + { .compatible = "microchip,sama7d65-pmc", }, { /* sentinel */ } }; diff --git a/drivers/clk/at91/sama7d65.c b/drivers/clk/at91/sama7d65.c new file mode 100644 index 0000000000000..a5d40df8b2f27 --- /dev/null +++ b/drivers/clk/at91/sama7d65.c @@ -0,0 +1,1375 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SAMA7D65 PMC code. + * + * Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries + * + * Author: Ryan Wanner + */ +#include +#include +#include +#include + +#include + +#include "pmc.h" + +static DEFINE_SPINLOCK(pmc_pll_lock); +static DEFINE_SPINLOCK(pmc_mck0_lock); +static DEFINE_SPINLOCK(pmc_mckX_lock); + +#define PMC_INDEX_MAX 25 + +/* + * PLL clocks identifiers + * @PLL_ID_CPU: CPU PLL identifier + * @PLL_ID_SYS: System PLL identifier + * @PLL_ID_DDR: DDR PLL identifier + * @PLL_ID_GPU: Graphics subsystem PLL identifier + * @PLL_ID_BAUD: Baud PLL identifier + * @PLL_ID_AUDIO: Audio PLL identifier + * @PLL_ID_ETH: Ethernet PLL identifier + * @PLL_ID_LVDS: LVDS PLL identifier + * @PLL_ID_USB: USB PLL identifier + */ +enum pll_ids { + PLL_ID_CPU, + PLL_ID_SYS, + PLL_ID_DDR, + PLL_ID_GPU, + PLL_ID_BAUD, + PLL_ID_AUDIO, + PLL_ID_ETH, + PLL_ID_LVDS, + PLL_ID_USB, + PLL_ID_MAX +}; + +/* + * PLL component identifier + * @PLL_COMPID_FRAC: Fractional PLL component identifier + * @PLL_COMPID_DIV0: 1st PLL divider component identifier + * @PLL_COMPID_DIV1: 2nd PLL divider component identifier + */ +enum pll_component_id { + PLL_COMPID_FRAC, + PLL_COMPID_DIV0, + PLL_COMPID_DIV1, + PLL_COMPID_MAX +}; + +/* + * PLL type identifiers + * @PLL_TYPE_FRAC: fractional PLL identifier + * @PLL_TYPE_DIV: divider PLL identifier + */ +enum pll_type { + PLL_TYPE_FRAC, + PLL_TYPE_DIV +}; + +/* Layout for fractional PLLs. */ +static const struct clk_pll_layout pll_layout_frac = { + .mul_mask = GENMASK(31, 24), + .frac_mask = GENMASK(21, 0), + .mul_shift = 24, + .frac_shift = 0, +}; + +/* Layout for DIVPMC dividers. */ +static const struct clk_pll_layout pll_layout_divpmc = { + .div_mask = GENMASK(7, 0), + .endiv_mask = BIT(29), + .div_shift = 0, + .endiv_shift = 29, +}; + +/* Layout for DIVIO dividers. */ +static const struct clk_pll_layout pll_layout_divio = { + .div_mask = GENMASK(19, 12), + .endiv_mask = BIT(30), + .div_shift = 12, + .endiv_shift = 30, +}; + +/* + * CPU PLL output range. + * Notice: The upper limit has been setup to 1000000002 due to hardware + * block which cannot output exactly 1GHz. + */ +static const struct clk_range cpu_pll_outputs[] = { + { .min = 2343750, .max = 1000000002 }, +}; + +/* PLL output range. */ +static const struct clk_range pll_outputs[] = { + { .min = 2343750, .max = 1200000000 }, +}; + +/* + * Min: fCOREPLLCK = 600 MHz, PMC_PLL_CTRL0.DIVPMC = 255 + * Max: fCOREPLLCK = 800 MHz, PMC_PLL_CTRL0.DIVPMC = 0 + */ +static const struct clk_range lvdspll_outputs[] = { + { .min = 16406250, .max = 800000000 }, +}; + +static const struct clk_range upll_outputs[] = { + { .min = 480000000, .max = 480000000 }, +}; + +/* Fractional PLL core output range. */ +static const struct clk_range core_outputs[] = { + { .min = 600000000, .max = 1200000000 }, +}; + +static const struct clk_range lvdspll_core_outputs[] = { + { .min = 600000000, .max = 1200000000 }, +}; + +static const struct clk_range upll_core_outputs[] = { + { .min = 600000000, .max = 1200000000 }, +}; + +/* CPU PLL characteristics. */ +static const struct clk_pll_characteristics cpu_pll_characteristics = { + .input = { .min = 12000000, .max = 50000000 }, + .num_output = ARRAY_SIZE(cpu_pll_outputs), + .output = cpu_pll_outputs, + .core_output = core_outputs, +}; + +/* PLL characteristics. */ +static const struct clk_pll_characteristics pll_characteristics = { + .input = { .min = 12000000, .max = 50000000 }, + .num_output = ARRAY_SIZE(pll_outputs), + .output = pll_outputs, + .core_output = core_outputs, +}; + +static const struct clk_pll_characteristics lvdspll_characteristics = { + .input = { .min = 12000000, .max = 50000000 }, + .num_output = ARRAY_SIZE(lvdspll_outputs), + .output = lvdspll_outputs, + .core_output = lvdspll_core_outputs, +}; + +static const struct clk_pll_characteristics upll_characteristics = { + .input = { .min = 20000000, .max = 50000000 }, + .num_output = ARRAY_SIZE(upll_outputs), + .output = upll_outputs, + .core_output = upll_core_outputs, + .upll = true, +}; + +/* + * SAMA7D65 PLL possible parents + * @SAMA7D65_PLL_PARENT_MAINCK: MAINCK is PLL a parent + * @SAMA7D65_PLL_PARENT_MAIN_XTAL: MAIN XTAL is a PLL parent + * @SAMA7D65_PLL_PARENT_FRACCK: Frac PLL is a PLL parent (for PLL dividers) + */ +enum sama7d65_pll_parent { + SAMA7D65_PLL_PARENT_MAINCK, + SAMA7D65_PLL_PARENT_MAIN_XTAL, + SAMA7D65_PLL_PARENT_FRACCK +}; + +/* + * PLL clocks description + * @n: clock name + * @l: clock layout + * @c: clock characteristics + * @hw: pointer to clk_hw + * @t: clock type + * @f: clock flags + * @p: clock parent + * @eid: export index in sama7d65->chws[] array + * @safe_div: intermediate divider need to be set on PRE_RATE_CHANGE + * notification + */ +static struct sama7d65_pll { + const char *n; + const struct clk_pll_layout *l; + const struct clk_pll_characteristics *c; + struct clk_hw *hw; + unsigned long f; + enum sama7d65_pll_parent p; + u8 t; + u8 eid; + u8 safe_div; +} sama7d65_plls[][PLL_COMPID_MAX] = { + [PLL_ID_CPU] = { + [PLL_COMPID_FRAC] = { + .n = "cpupll_fracck", + .p = SAMA7D65_PLL_PARENT_MAINCK, + .l = &pll_layout_frac, + .c = &cpu_pll_characteristics, + .t = PLL_TYPE_FRAC, + /* + * This feeds cpupll_divpmcck which feeds CPU. It should + * not be disabled. + */ + .f = CLK_IS_CRITICAL, + }, + + [PLL_COMPID_DIV0] = { + .n = "cpupll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &cpu_pll_characteristics, + .t = PLL_TYPE_DIV, + /* This feeds CPU. It should not be disabled. */ + .f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .eid = PMC_CPUPLL, + /* + * Safe div=15 should be safe even for switching b/w 1GHz and + * 90MHz (frac pll might go up to 1.2GHz). + */ + .safe_div = 15, + }, + }, + + [PLL_ID_SYS] = { + [PLL_COMPID_FRAC] = { + .n = "syspll_fracck", + .p = SAMA7D65_PLL_PARENT_MAINCK, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + /* + * This feeds syspll_divpmcck which may feed critical parts + * of the systems like timers. Therefore it should not be + * disabled. + */ + .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, + }, + + [PLL_COMPID_DIV0] = { + .n = "syspll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + /* + * This may feed critical parts of the systems like timers. + * Therefore it should not be disabled. + */ + .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, + .eid = PMC_SYSPLL, + }, + }, + + [PLL_ID_DDR] = { + [PLL_COMPID_FRAC] = { + .n = "ddrpll_fracck", + .p = SAMA7D65_PLL_PARENT_MAINCK, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + /* + * This feeds ddrpll_divpmcck which feeds DDR. It should not + * be disabled. + */ + .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, + }, + + [PLL_COMPID_DIV0] = { + .n = "ddrpll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + /* This feeds DDR. It should not be disabled. */ + .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, + }, + }, + + [PLL_ID_GPU] = { + [PLL_COMPID_FRAC] = { + .n = "gpupll_fracck", + .p = SAMA7D65_PLL_PARENT_MAINCK, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + .f = CLK_SET_RATE_GATE, + }, + + [PLL_COMPID_DIV0] = { + .n = "gpupll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, + }, + }, + + [PLL_ID_BAUD] = { + [PLL_COMPID_FRAC] = { + .n = "baudpll_fracck", + .p = SAMA7D65_PLL_PARENT_MAINCK, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + .f = CLK_SET_RATE_GATE, + }, + + [PLL_COMPID_DIV0] = { + .n = "baudpll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, + .eid = PMC_BAUDPLL, + }, + }, + + [PLL_ID_AUDIO] = { + [PLL_COMPID_FRAC] = { + .n = "audiopll_fracck", + .p = SAMA7D65_PLL_PARENT_MAIN_XTAL, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + .f = CLK_SET_RATE_GATE, + }, + + [PLL_COMPID_DIV0] = { + .n = "audiopll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, + .eid = PMC_AUDIOPMCPLL, + }, + + [PLL_COMPID_DIV1] = { + .n = "audiopll_diviock", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divio, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, + .eid = PMC_AUDIOIOPLL, + }, + }, + + [PLL_ID_ETH] = { + [PLL_COMPID_FRAC] = { + .n = "ethpll_fracck", + .p = SAMA7D65_PLL_PARENT_MAIN_XTAL, + .l = &pll_layout_frac, + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + .f = CLK_SET_RATE_GATE, + }, + + [PLL_COMPID_DIV0] = { + .n = "ethpll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, + .eid = PMC_ETHPLL, + }, + }, + + [PLL_ID_LVDS] = { + [PLL_COMPID_FRAC] = { + .n = "lvdspll_fracck", + .p = SAMA7D65_PLL_PARENT_MAIN_XTAL, + .l = &pll_layout_frac, + .c = &lvdspll_characteristics, + .t = PLL_TYPE_FRAC, + .f = CLK_SET_RATE_GATE, + }, + + [PLL_COMPID_DIV0] = { + .n = "lvdspll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &lvdspll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, + .eid = PMC_LVDSPLL, + }, + }, + + [PLL_ID_USB] = { + [PLL_COMPID_FRAC] = { + .n = "usbpll_fracck", + .p = SAMA7D65_PLL_PARENT_MAIN_XTAL, + .l = &pll_layout_frac, + .c = &upll_characteristics, + .t = PLL_TYPE_FRAC, + .f = CLK_SET_RATE_GATE, + }, + + [PLL_COMPID_DIV0] = { + .n = "usbpll_divpmcck", + .p = SAMA7D65_PLL_PARENT_FRACCK, + .l = &pll_layout_divpmc, + .c = &upll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, + .eid = PMC_UTMI, + }, + }, +}; + +/* Used to create an array entry identifying a PLL by its components. */ +#define PLL_IDS_TO_ARR_ENTRY(_id, _comp) { PLL_ID_##_id, PLL_COMPID_##_comp} + +/* + * Master clock (MCK[0..9]) description + * @n: clock name + * @ep_chg_chg_id: index in parents array that specifies the changeable + * @ep: extra parents names array (entry formed by PLL components + * identifiers (see enum pll_component_id)) + * @hw: pointer to clk_hw + * parent + * @ep_count: extra parents count + * @ep_mux_table: mux table for extra parents + * @id: clock id + * @eid: export index in sama7d65->chws[] array + * @c: true if clock is critical and cannot be disabled + */ +static struct { + const char *n; + struct { + int pll_id; + int pll_compid; + } ep[4]; + struct clk_hw *hw; + int ep_chg_id; + u8 ep_count; + u8 ep_mux_table[4]; + u8 id; + u8 eid; + u8 c; +} sama7d65_mckx[] = { + { .n = "mck0", }, /* Dummy entry for MCK0 to store hw in probe. */ + { .n = "mck1", + .id = 1, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_count = 1, + .ep_chg_id = INT_MIN, + .eid = PMC_MCK1, + .c = 1, }, + + { .n = "mck2", + .id = 2, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), }, + .ep_mux_table = { 5, 6, }, + .ep_count = 2, + .ep_chg_id = INT_MIN, + .c = 1, }, + + { .n = "mck3", + .id = 3, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(DDR, DIV0), }, + .ep_mux_table = { 5, 6, }, + .ep_count = 2, + .ep_chg_id = INT_MIN, + .eid = PMC_MCK3, + .c = 1, }, + + { .n = "mck4", + .id = 4, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_count = 1, + .ep_chg_id = INT_MIN, + .c = 1, }, + + { .n = "mck5", + .id = 5, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_count = 1, + .ep_chg_id = INT_MIN, + .eid = PMC_MCK5, + .c = 1, }, + + { .n = "mck6", + .id = 6, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_chg_id = INT_MIN, + .ep_count = 1, + .c = 1, }, + + { .n = "mck7", + .id = 7, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_chg_id = INT_MIN, + .ep_count = 1, }, + + { .n = "mck8", + .id = 8, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_chg_id = INT_MIN, + .ep_count = 1, }, + + { .n = "mck9", + .id = 9, + .ep = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .ep_mux_table = { 5, }, + .ep_chg_id = INT_MIN, + .ep_count = 1, }, +}; + +/* + * System clock description + * @n: clock name + * @p: clock parent name + * @id: clock id + */ +static const struct { + const char *n; + const char *p; + u8 id; +} sama7d65_systemck[] = { + { .n = "uhpck", .p = "usbck", .id = 6 }, + { .n = "pck0", .p = "prog0", .id = 8, }, + { .n = "pck1", .p = "prog1", .id = 9, }, + { .n = "pck2", .p = "prog2", .id = 10, }, + { .n = "pck3", .p = "prog3", .id = 11, }, + { .n = "pck4", .p = "prog4", .id = 12, }, + { .n = "pck5", .p = "prog5", .id = 13, }, + { .n = "pck6", .p = "prog6", .id = 14, }, + { .n = "pck7", .p = "prog7", .id = 15, }, +}; + +/* Mux table for programmable clocks. */ +static u32 sama7d65_prog_mux_table[] = { 0, 1, 2, 5, 7, 8, 9, 10, 12 }; + +/* + * Peripheral clock parent hw identifier (used to index in sama7d65_mckx[]) + * @PCK_PARENT_HW_MCK0: pck parent hw identifier is MCK0 + * @PCK_PARENT_HW_MCK1: pck parent hw identifier is MCK1 + * @PCK_PARENT_HW_MCK2: pck parent hw identifier is MCK2 + * @PCK_PARENT_HW_MCK3: pck parent hw identifier is MCK3 + * @PCK_PARENT_HW_MCK4: pck parent hw identifier is MCK4 + * @PCK_PARENT_HW_MCK5: pck parent hw identifier is MCK5 + * @PCK_PARENT_HW_MCK6: pck parent hw identifier is MCK6 + * @PCK_PARENT_HW_MCK7: pck parent hw identifier is MCK7 + * @PCK_PARENT_HW_MCK8: pck parent hw identifier is MCK8 + * @PCK_PARENT_HW_MCK9: pck parent hw identifier is MCK9 + * @PCK_PARENT_HW_MAX: max identifier + */ +enum sama7d65_pck_parent_hw_id { + PCK_PARENT_HW_MCK0, + PCK_PARENT_HW_MCK1, + PCK_PARENT_HW_MCK2, + PCK_PARENT_HW_MCK3, + PCK_PARENT_HW_MCK4, + PCK_PARENT_HW_MCK5, + PCK_PARENT_HW_MCK6, + PCK_PARENT_HW_MCK7, + PCK_PARENT_HW_MCK8, + PCK_PARENT_HW_MCK9, + PCK_PARENT_HW_MAX +}; + +/* + * Peripheral clock description + * @n: clock name + * @p: clock parent hw id + * @r: clock range values + * @id: clock id + * @chgp: index in parent array of the changeable parent + */ +static struct { + const char *n; + enum sama7d65_pck_parent_hw_id p; + struct clk_range r; + u8 chgp; + u8 id; +} sama7d65_periphck[] = { + { .n = "pioA_clk", .p = PCK_PARENT_HW_MCK0, .id = 10, }, + { .n = "securam_clk", .p = PCK_PARENT_HW_MCK0, .id = 17, }, + { .n = "sfr_clk", .p = PCK_PARENT_HW_MCK7, .id = 18, }, + { .n = "hsmc_clk", .p = PCK_PARENT_HW_MCK5, .id = 20, }, + { .n = "xdmac0_clk", .p = PCK_PARENT_HW_MCK6, .id = 21, }, + { .n = "xdmac1_clk", .p = PCK_PARENT_HW_MCK6, .id = 22, }, + { .n = "xdmac2_clk", .p = PCK_PARENT_HW_MCK1, .id = 23, }, + { .n = "acc_clk", .p = PCK_PARENT_HW_MCK7, .id = 24, }, + { .n = "aes_clk", .p = PCK_PARENT_HW_MCK6, .id = 26, }, + { .n = "tzaesbasc_clk", .p = PCK_PARENT_HW_MCK8, .id = 27, }, + { .n = "asrc_clk", .p = PCK_PARENT_HW_MCK9, .id = 29, .r = { .max = 200000000, }, }, + { .n = "cpkcc_clk", .p = PCK_PARENT_HW_MCK0, .id = 30, }, + { .n = "eic_clk", .p = PCK_PARENT_HW_MCK7, .id = 33, }, + { .n = "flex0_clk", .p = PCK_PARENT_HW_MCK7, .id = 34, }, + { .n = "flex1_clk", .p = PCK_PARENT_HW_MCK7, .id = 35, }, + { .n = "flex2_clk", .p = PCK_PARENT_HW_MCK7, .id = 36, }, + { .n = "flex3_clk", .p = PCK_PARENT_HW_MCK7, .id = 37, }, + { .n = "flex4_clk", .p = PCK_PARENT_HW_MCK8, .id = 38, }, + { .n = "flex5_clk", .p = PCK_PARENT_HW_MCK8, .id = 39, }, + { .n = "flex6_clk", .p = PCK_PARENT_HW_MCK8, .id = 40, }, + { .n = "flex7_clk", .p = PCK_PARENT_HW_MCK8, .id = 41, }, + { .n = "flex8_clk", .p = PCK_PARENT_HW_MCK9, .id = 42, }, + { .n = "flex9_clk", .p = PCK_PARENT_HW_MCK9, .id = 43, }, + { .n = "flex10_clk", .p = PCK_PARENT_HW_MCK9, .id = 44, }, + { .n = "gmac0_clk", .p = PCK_PARENT_HW_MCK6, .id = 46, }, + { .n = "gmac1_clk", .p = PCK_PARENT_HW_MCK6, .id = 47, }, + { .n = "gmac0_tsu_clk", .p = PCK_PARENT_HW_MCK1, .id = 49, }, + { .n = "gmac1_tsu_clk", .p = PCK_PARENT_HW_MCK1, .id = 50, }, + { .n = "icm_clk", .p = PCK_PARENT_HW_MCK5, .id = 53, }, + { .n = "i2smcc0_clk", .p = PCK_PARENT_HW_MCK9, .id = 54, .r = { .max = 200000000, }, }, + { .n = "i2smcc1_clk", .p = PCK_PARENT_HW_MCK9, .id = 55, .r = { .max = 200000000, }, }, + { .n = "lcd_clk", .p = PCK_PARENT_HW_MCK3, .id = 56, }, + { .n = "matrix_clk", .p = PCK_PARENT_HW_MCK5, .id = 57, }, + { .n = "mcan0_clk", .p = PCK_PARENT_HW_MCK5, .id = 58, .r = { .max = 200000000, }, }, + { .n = "mcan1_clk", .p = PCK_PARENT_HW_MCK5, .id = 59, .r = { .max = 200000000, }, }, + { .n = "mcan2_clk", .p = PCK_PARENT_HW_MCK5, .id = 60, .r = { .max = 200000000, }, }, + { .n = "mcan3_clk", .p = PCK_PARENT_HW_MCK5, .id = 61, .r = { .max = 200000000, }, }, + { .n = "mcan4_clk", .p = PCK_PARENT_HW_MCK5, .id = 62, .r = { .max = 200000000, }, }, + { .n = "pdmc0_clk", .p = PCK_PARENT_HW_MCK9, .id = 64, .r = { .max = 200000000, }, }, + { .n = "pdmc1_clk", .p = PCK_PARENT_HW_MCK9, .id = 65, .r = { .max = 200000000, }, }, + { .n = "pit64b0_clk", .p = PCK_PARENT_HW_MCK7, .id = 66, }, + { .n = "pit64b1_clk", .p = PCK_PARENT_HW_MCK7, .id = 67, }, + { .n = "pit64b2_clk", .p = PCK_PARENT_HW_MCK7, .id = 68, }, + { .n = "pit64b3_clk", .p = PCK_PARENT_HW_MCK8, .id = 69, }, + { .n = "pit64b4_clk", .p = PCK_PARENT_HW_MCK8, .id = 70, }, + { .n = "pit64b5_clk", .p = PCK_PARENT_HW_MCK8, .id = 71, }, + { .n = "pwm_clk", .p = PCK_PARENT_HW_MCK7, .id = 72, }, + { .n = "qspi0_clk", .p = PCK_PARENT_HW_MCK5, .id = 73, }, + { .n = "qspi1_clk", .p = PCK_PARENT_HW_MCK5, .id = 74, }, + { .n = "sdmmc0_clk", .p = PCK_PARENT_HW_MCK1, .id = 75, }, + { .n = "sdmmc1_clk", .p = PCK_PARENT_HW_MCK1, .id = 76, }, + { .n = "sdmmc2_clk", .p = PCK_PARENT_HW_MCK1, .id = 77, }, + { .n = "sha_clk", .p = PCK_PARENT_HW_MCK6, .id = 78, }, + { .n = "spdifrx_clk", .p = PCK_PARENT_HW_MCK9, .id = 79, .r = { .max = 200000000, }, }, + { .n = "spdiftx_clk", .p = PCK_PARENT_HW_MCK9, .id = 80, .r = { .max = 200000000, }, }, + { .n = "ssc0_clk", .p = PCK_PARENT_HW_MCK7, .id = 81, .r = { .max = 200000000, }, }, + { .n = "ssc1_clk", .p = PCK_PARENT_HW_MCK8, .id = 82, .r = { .max = 200000000, }, }, + { .n = "tcb0_ch0_clk", .p = PCK_PARENT_HW_MCK8, .id = 83, .r = { .max = 200000000, }, }, + { .n = "tcb0_ch1_clk", .p = PCK_PARENT_HW_MCK8, .id = 84, .r = { .max = 200000000, }, }, + { .n = "tcb0_ch2_clk", .p = PCK_PARENT_HW_MCK8, .id = 85, .r = { .max = 200000000, }, }, + { .n = "tcb1_ch0_clk", .p = PCK_PARENT_HW_MCK5, .id = 86, .r = { .max = 200000000, }, }, + { .n = "tcb1_ch1_clk", .p = PCK_PARENT_HW_MCK5, .id = 87, .r = { .max = 200000000, }, }, + { .n = "tcb1_ch2_clk", .p = PCK_PARENT_HW_MCK5, .id = 88, .r = { .max = 200000000, }, }, + { .n = "tcpca_clk", .p = PCK_PARENT_HW_MCK5, .id = 89, }, + { .n = "tcpcb_clk", .p = PCK_PARENT_HW_MCK5, .id = 90, }, + { .n = "tdes_clk", .p = PCK_PARENT_HW_MCK6, .id = 91, }, + { .n = "trng_clk", .p = PCK_PARENT_HW_MCK6, .id = 92, }, + { .n = "udphsa_clk", .p = PCK_PARENT_HW_MCK5, .id = 99, }, + { .n = "udphsb_clk", .p = PCK_PARENT_HW_MCK5, .id = 100, }, + { .n = "uhphs_clk", .p = PCK_PARENT_HW_MCK5, .id = 101, }, + { .n = "dsi_clk", .p = PCK_PARENT_HW_MCK3, .id = 103, }, + { .n = "lvdsc_clk", .p = PCK_PARENT_HW_MCK3, .id = 104, }, +}; + +/* + * Generic clock description + * @n: clock name + * @pp: PLL parents (entry formed by PLL components identifiers + * (see enum pll_component_id)) + * @pp_mux_table: PLL parents mux table + * @r: clock output range + * @pp_chg_id: id in parent array of changeable PLL parent + * @pp_count: PLL parents count + * @id: clock id + */ +static const struct { + const char *n; + struct { + int pll_id; + int pll_compid; + } pp[8]; + const char pp_mux_table[8]; + struct clk_range r; + int pp_chg_id; + u8 pp_count; + u8 id; +} sama7d65_gck[] = { + { .n = "adc_gclk", + .id = 25, + .r = { .max = 100000000, }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 8, 9, }, + .pp_count = 2, + .pp_chg_id = INT_MIN, }, + + { .n = "asrc_gclk", + .id = 29, + .r = { .max = 200000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex0_gclk", + .id = 34, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = {8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex1_gclk", + .id = 35, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = {8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex2_gclk", + .id = 36, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = {8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex3_gclk", + .id = 37, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = {8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex4_gclk", + .id = 38, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex5_gclk", + .id = 39, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex6_gclk", + .id = 40, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex7_gclk", + .id = 41, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex8_gclk", + .id = 42, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex9_gclk", + .id = 43, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "flex10_gclk", + .id = 44, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 8, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "gmac0_gclk", + .id = 46, + .r = { .max = 125000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 10, }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "gmac1_gclk", + .id = 47, + .r = { .max = 125000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 10, }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "gmac0_tsu_gclk", + .id = 49, + .r = { .max = 400000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = {10, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "gmac1_tsu_gclk", + .id = 50, + .r = { .max = 400000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 10, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "i2smcc0_gclk", + .id = 54, + .r = { .max = 100000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "i2smcc1_gclk", + .id = 55, + .r = { .max = 100000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "lcdc_gclk", + .id = 56, + .r = { .max = 90000000 }, + .pp_count = 0, + .pp_chg_id = INT_MIN, + }, + + { .n = "mcan0_gclk", + .id = 58, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), }, + .pp_mux_table = { 12 }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "mcan1_gclk", + .id = 59, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), }, + .pp_mux_table = { 12 }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "mcan2_gclk", + .id = 60, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), }, + .pp_mux_table = { 12 }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "mcan3_gclk", + .id = 61, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), }, + .pp_mux_table = { 12 }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "mcan4_gclk", + .id = 62, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(USB, DIV0), }, + .pp_mux_table = { 12 }, + .pp_count = 1, + .pp_chg_id = 4, }, + + { .n = "pdmc0_gclk", + .id = 64, + .r = { .max = 80000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9 }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "pdmc1_gclk", + .id = 65, + .r = { .max = 80000000, }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b0_gclk", + .id = 66, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b1_gclk", + .id = 67, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b2_gclk", + .id = 68, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b3_gclk", + .id = 69, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = {8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b4_gclk", + .id = 70, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = {8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "pit64b5_gclk", + .id = 71, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = {8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "qspi0_gclk", + .id = 73, + .r = { .max = 400000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 5, 8, }, + .pp_count = 2, + .pp_chg_id = INT_MIN, }, + + { .n = "qspi1_gclk", + .id = 74, + .r = { .max = 266000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), }, + .pp_mux_table = { 5, 8, }, + .pp_count = 2, + .pp_chg_id = INT_MIN, }, + + { .n = "sdmmc0_gclk", + .id = 75, + .r = { .max = 208000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 10, }, + .pp_count = 2, + .pp_chg_id = 4, }, + + { .n = "sdmmc1_gclk", + .id = 76, + .r = { .max = 208000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 10, }, + .pp_count = 2, + .pp_chg_id = 4, }, + + { .n = "sdmmc2_gclk", + .id = 77, + .r = { .max = 208000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 10 }, + .pp_count = 2, + .pp_chg_id = 4, }, + + { .n = "spdifrx_gclk", + .id = 79, + .r = { .max = 150000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "spdiftx_gclk", + .id = 80, + .r = { .max = 25000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), }, + .pp_mux_table = { 9, }, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "tcb0_ch0_gclk", + .id = 83, + .r = { .max = 34000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "tcb1_ch0_gclk", + .id = 86, + .r = { .max = 67000000 }, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = { 8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, + + { .n = "DSI_gclk", + .id = 103, + .r = {.max = 27000000}, + .pp = { PLL_IDS_TO_ARR_ENTRY(SYS, DIV0), }, + .pp_mux_table = {5}, + .pp_count = 1, + .pp_chg_id = INT_MIN, }, + + { .n = "I3CC_gclk", + .id = 105, + .r = {.max = 125000000}, + .pp = { PLL_IDS_TO_ARR_ENTRY(BAUD, DIV0), PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), + PLL_IDS_TO_ARR_ENTRY(ETH, DIV0), }, + .pp_mux_table = {8, 9, 10, }, + .pp_count = 3, + .pp_chg_id = INT_MIN, }, +}; + +/* MCK0 characteristics. */ +static const struct clk_master_characteristics mck0_characteristics = { + .output = { .min = 32768, .max = 200000000 }, + .divisors = { 1, 2, 4, 3, 5 }, + .have_div3_pres = 1, +}; + +/* MCK0 layout. */ +static const struct clk_master_layout mck0_layout = { + .mask = 0x773, + .pres_shift = 4, + .offset = 0x28, +}; + +/* Programmable clock layout. */ +static const struct clk_programmable_layout programmable_layout = { + .pres_mask = 0xff, + .pres_shift = 8, + .css_mask = 0x1f, + .have_slck_mck = 0, + .is_pres_direct = 1, +}; + +/* Peripheral clock layout. */ +static const struct clk_pcr_layout sama7d65_pcr_layout = { + .offset = 0x88, + .cmd = BIT(31), + .gckcss_mask = GENMASK(12, 8), + .pid_mask = GENMASK(6, 0), +}; + +static void __init sama7d65_pmc_setup(struct device_node *np) +{ + const char *main_xtal_name = "main_xtal"; + struct pmc_data *sama7d65_pmc; + const char *parent_names[11]; + void **alloc_mem = NULL; + int alloc_mem_size = 0; + struct regmap *regmap; + struct clk_hw *hw, *main_rc_hw, *main_osc_hw, *main_xtal_hw; + struct clk_hw *td_slck_hw, *md_slck_hw; + static struct clk_parent_data parent_data; + struct clk_hw *parent_hws[10]; + bool bypass; + int i, j; + + td_slck_hw = __clk_get_hw(of_clk_get_by_name(np, "td_slck")); + md_slck_hw = __clk_get_hw(of_clk_get_by_name(np, "md_slck")); + main_xtal_hw = __clk_get_hw(of_clk_get_by_name(np, main_xtal_name)); + + if (!td_slck_hw || !md_slck_hw || !main_xtal_hw) + return; + + regmap = device_node_to_regmap(np); + if (IS_ERR(regmap)) + return; + + sama7d65_pmc = pmc_data_allocate(PMC_INDEX_MAX, + nck(sama7d65_systemck), + nck(sama7d65_periphck), + nck(sama7d65_gck), 8); + if (!sama7d65_pmc) + return; + + alloc_mem = kmalloc(sizeof(void *) * + (ARRAY_SIZE(sama7d65_mckx) + ARRAY_SIZE(sama7d65_gck)), + GFP_KERNEL); + if (!alloc_mem) + goto err_free; + + main_rc_hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000, + 50000000); + if (IS_ERR(main_rc_hw)) + goto err_free; + + bypass = of_property_read_bool(np, "atmel,osc-bypass"); + + parent_data.name = main_xtal_name; + parent_data.fw_name = main_xtal_name; + main_osc_hw = at91_clk_register_main_osc(regmap, "main_osc", NULL, + &parent_data, bypass); + if (IS_ERR(main_osc_hw)) + goto err_free; + + parent_hws[0] = main_rc_hw; + parent_hws[1] = main_osc_hw; + hw = at91_clk_register_sam9x5_main(regmap, "mainck", NULL, parent_hws, 2); + if (IS_ERR(hw)) + goto err_free; + + sama7d65_pmc->chws[PMC_MAIN] = hw; + + for (i = 0; i < PLL_ID_MAX; i++) { + for (j = 0; j < PLL_COMPID_MAX; j++) { + struct clk_hw *parent_hw; + + if (!sama7d65_plls[i][j].n) + continue; + + switch (sama7d65_plls[i][j].t) { + case PLL_TYPE_FRAC: + switch (sama7d65_plls[i][j].p) { + case SAMA7D65_PLL_PARENT_MAINCK: + parent_hw = sama7d65_pmc->chws[PMC_MAIN]; + break; + case SAMA7D65_PLL_PARENT_MAIN_XTAL: + parent_hw = main_xtal_hw; + break; + default: + /* Should not happen. */ + parent_hw = NULL; + break; + } + + hw = sam9x60_clk_register_frac_pll(regmap, + &pmc_pll_lock, sama7d65_plls[i][j].n, + NULL, parent_hw, i, + sama7d65_plls[i][j].c, + sama7d65_plls[i][j].l, + sama7d65_plls[i][j].f); + break; + + case PLL_TYPE_DIV: + hw = sam9x60_clk_register_div_pll(regmap, + &pmc_pll_lock, sama7d65_plls[i][j].n, + NULL, sama7d65_plls[i][0].hw, i, + sama7d65_plls[i][j].c, + sama7d65_plls[i][j].l, + sama7d65_plls[i][j].f, + sama7d65_plls[i][j].safe_div); + break; + + default: + continue; + } + + if (IS_ERR(hw)) + goto err_free; + + sama7d65_plls[i][j].hw = hw; + if (sama7d65_plls[i][j].eid) + sama7d65_pmc->chws[sama7d65_plls[i][j].eid] = hw; + } + } + + hw = at91_clk_register_master_div(regmap, "mck0", NULL, + sama7d65_plls[PLL_ID_CPU][1].hw, + &mck0_layout, &mck0_characteristics, + &pmc_mck0_lock, CLK_GET_RATE_NOCACHE, 5); + if (IS_ERR(hw)) + goto err_free; + + sama7d65_pmc->chws[PMC_MCK] = hw; + sama7d65_mckx[PCK_PARENT_HW_MCK0].hw = hw; + + parent_hws[0] = md_slck_hw; + parent_hws[1] = td_slck_hw; + parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN]; + for (i = PCK_PARENT_HW_MCK1; i < ARRAY_SIZE(sama7d65_mckx); i++) { + u8 num_parents = 3 + sama7d65_mckx[i].ep_count; + struct clk_hw *tmp_parent_hws[8]; + u32 *mux_table; + + mux_table = kmalloc_array(num_parents, sizeof(*mux_table), + GFP_KERNEL); + if (!mux_table) + goto err_free; + + alloc_mem[alloc_mem_size++] = mux_table; + + PMC_INIT_TABLE(mux_table, 3); + PMC_FILL_TABLE(&mux_table[3], sama7d65_mckx[i].ep_mux_table, + sama7d65_mckx[i].ep_count); + for (j = 0; j < sama7d65_mckx[i].ep_count; j++) { + u8 pll_id = sama7d65_mckx[i].ep[j].pll_id; + u8 pll_compid = sama7d65_mckx[i].ep[j].pll_compid; + + tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].hw; + } + PMC_FILL_TABLE(&parent_hws[3], tmp_parent_hws, + sama7d65_mckx[i].ep_count); + + hw = at91_clk_sama7g5_register_master(regmap, sama7d65_mckx[i].n, + num_parents, NULL, parent_hws, + mux_table, &pmc_mckX_lock, + sama7d65_mckx[i].id, + sama7d65_mckx[i].c, + sama7d65_mckx[i].ep_chg_id); + + if (IS_ERR(hw)) + goto err_free; + + sama7d65_mckx[i].hw = hw; + if (sama7d65_mckx[i].eid) + sama7d65_pmc->chws[sama7d65_mckx[i].eid] = hw; + } + + parent_names[0] = "syspll_divpmcck"; + parent_names[1] = "usbpll_divpmcck"; + parent_names[2] = "main_osc"; + hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3); + if (IS_ERR(hw)) + goto err_free; + + parent_hws[0] = md_slck_hw; + parent_hws[1] = td_slck_hw; + parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN]; + parent_hws[3] = sama7d65_plls[PLL_ID_SYS][PLL_COMPID_DIV0].hw; + parent_hws[4] = sama7d65_plls[PLL_ID_DDR][PLL_COMPID_DIV0].hw; + parent_hws[5] = sama7d65_plls[PLL_ID_GPU][PLL_COMPID_DIV0].hw; + parent_hws[6] = sama7d65_plls[PLL_ID_BAUD][PLL_COMPID_DIV0].hw; + parent_hws[7] = sama7d65_plls[PLL_ID_AUDIO][PLL_COMPID_DIV0].hw; + parent_hws[8] = sama7d65_plls[PLL_ID_ETH][PLL_COMPID_DIV0].hw; + + for (i = 0; i < 8; i++) { + char name[6]; + + snprintf(name, sizeof(name), "prog%d", i); + + hw = at91_clk_register_programmable(regmap, name, NULL, parent_hws, + 9, i, + &programmable_layout, + sama7d65_prog_mux_table); + if (IS_ERR(hw)) + goto err_free; + + sama7d65_pmc->pchws[i] = hw; + } + + for (i = 0; i < ARRAY_SIZE(sama7d65_systemck); i++) { + hw = at91_clk_register_system(regmap, sama7d65_systemck[i].n, + sama7d65_systemck[i].p, NULL, + sama7d65_systemck[i].id, 0); + if (IS_ERR(hw)) + goto err_free; + + sama7d65_pmc->shws[sama7d65_systemck[i].id] = hw; + } + + for (i = 0; i < ARRAY_SIZE(sama7d65_periphck); i++) { + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &sama7d65_pcr_layout, + sama7d65_periphck[i].n, + NULL, + sama7d65_mckx[sama7d65_periphck[i].p].hw, + sama7d65_periphck[i].id, + &sama7d65_periphck[i].r, + sama7d65_periphck[i].chgp ? 0 : + INT_MIN, 0); + if (IS_ERR(hw)) + goto err_free; + + sama7d65_pmc->phws[sama7d65_periphck[i].id] = hw; + } + + parent_hws[0] = md_slck_hw; + parent_hws[1] = td_slck_hw; + parent_hws[2] = sama7d65_pmc->chws[PMC_MAIN]; + parent_hws[3] = sama7d65_pmc->chws[PMC_MCK1]; + for (i = 0; i < ARRAY_SIZE(sama7d65_gck); i++) { + u8 num_parents = 4 + sama7d65_gck[i].pp_count; + struct clk_hw *tmp_parent_hws[8]; + u32 *mux_table; + + mux_table = kmalloc_array(num_parents, sizeof(*mux_table), + GFP_KERNEL); + if (!mux_table) + goto err_free; + + alloc_mem[alloc_mem_size++] = mux_table; + + PMC_INIT_TABLE(mux_table, 4); + PMC_FILL_TABLE(&mux_table[4], sama7d65_gck[i].pp_mux_table, + sama7d65_gck[i].pp_count); + for (j = 0; j < sama7d65_gck[i].pp_count; j++) { + u8 pll_id = sama7d65_gck[i].pp[j].pll_id; + u8 pll_compid = sama7d65_gck[i].pp[j].pll_compid; + + tmp_parent_hws[j] = sama7d65_plls[pll_id][pll_compid].hw; + } + PMC_FILL_TABLE(&parent_hws[4], tmp_parent_hws, + sama7d65_gck[i].pp_count); + + hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, + &sama7d65_pcr_layout, + sama7d65_gck[i].n, NULL, + parent_hws, mux_table, + num_parents, + sama7d65_gck[i].id, + &sama7d65_gck[i].r, + sama7d65_gck[i].pp_chg_id); + if (IS_ERR(hw)) + goto err_free; + + sama7d65_pmc->ghws[sama7d65_gck[i].id] = hw; + } + + of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama7d65_pmc); + kfree(alloc_mem); + + return; + +err_free: + if (alloc_mem) { + for (i = 0; i < alloc_mem_size; i++) + kfree(alloc_mem[i]); + kfree(alloc_mem); + } + + kfree(sama7d65_pmc); +} + +/* Some clks are used for a clocksource */ +CLK_OF_DECLARE(sama7d65_pmc, "microchip,sama7d65-pmc", sama7d65_pmc_setup); From 88d9dca36aac9659446be1e569d8fbe3462b5741 Mon Sep 17 00:00:00 2001 From: Satya Priya Kakitapalli Date: Fri, 20 Dec 2024 15:20:48 +0530 Subject: [PATCH 37/81] clk: qcom: gcc-mdm9607: Fix cmd_rcgr offset for blsp1_uart6 rcg Fix cmd_rcgr offset for blsp1_uart6_apps_clk_src on mdm9607 platform. Fixes: 48b7253264ea ("clk: qcom: Add MDM9607 GCC driver") Cc: stable@vger.kernel.org Signed-off-by: Satya Priya Kakitapalli Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20241220095048.248425-1-quic_skakitap@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-mdm9607.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/gcc-mdm9607.c b/drivers/clk/qcom/gcc-mdm9607.c index 6e6068b168e66..07f1b78d737a1 100644 --- a/drivers/clk/qcom/gcc-mdm9607.c +++ b/drivers/clk/qcom/gcc-mdm9607.c @@ -535,7 +535,7 @@ static struct clk_rcg2 blsp1_uart5_apps_clk_src = { }; static struct clk_rcg2 blsp1_uart6_apps_clk_src = { - .cmd_rcgr = 0x6044, + .cmd_rcgr = 0x7044, .mnd_width = 16, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, From 9897831de614f1d8d5184547f0e7bf7665eed436 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 3 Jan 2025 23:36:57 -0800 Subject: [PATCH 38/81] dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI Export PLL_VIDEO_2X and PLL_MIPI, these will be used to explicitly select TCON0 clock parent in dts Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux") Reviewed-by: Dragan Simic Reviewed-by: Chen-Yu Tsai Tested-by: Frank Oltmanns # on PinePhone Tested-by: Stuart Gathman # on OG Pinebook Signed-off-by: Vasily Khoruzhick Acked-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20250104074035.1611136-2-anarsoul@gmail.com Signed-off-by: Chen-Yu Tsai --- include/dt-bindings/clock/sun50i-a64-ccu.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h b/include/dt-bindings/clock/sun50i-a64-ccu.h index 175892189e9dc..4f220ea7a23cc 100644 --- a/include/dt-bindings/clock/sun50i-a64-ccu.h +++ b/include/dt-bindings/clock/sun50i-a64-ccu.h @@ -44,7 +44,9 @@ #define _DT_BINDINGS_CLK_SUN50I_A64_H_ #define CLK_PLL_VIDEO0 7 +#define CLK_PLL_VIDEO0_2X 8 #define CLK_PLL_PERIPH0 11 +#define CLK_PLL_MIPI 17 #define CLK_CPUX 21 #define CLK_BUS_MIPI_DSI 28 From 0f368cb7ef103f284f75e962c4c89da5aa8ccec7 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 3 Jan 2025 23:36:58 -0800 Subject: [PATCH 39/81] clk: sunxi-ng: a64: drop redundant CLK_PLL_VIDEO0_2X and CLK_PLL_MIPI Drop redundant CLK_PLL_VIDEO0_2X and CLK_PLL.MIPI. These are now defined in dt-bindings/clock/sun50i-a64-ccu.h Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux") Reviewed-by: Dragan Simic Reviewed-by: Chen-Yu Tsai Tested-by: Frank Oltmanns # on pinephone Tested-by: Stuart Gathman # on OG pinebook Signed-off-by: Vasily Khoruzhick Link: https://patch.msgid.link/20250104074035.1611136-3-anarsoul@gmail.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun50i-a64.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h index a8c11c0b4e067..dfba88a5ad0f7 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h @@ -21,7 +21,6 @@ /* PLL_VIDEO0 exported for HDMI PHY */ -#define CLK_PLL_VIDEO0_2X 8 #define CLK_PLL_VE 9 #define CLK_PLL_DDR0 10 @@ -32,7 +31,6 @@ #define CLK_PLL_PERIPH1_2X 14 #define CLK_PLL_VIDEO1 15 #define CLK_PLL_GPU 16 -#define CLK_PLL_MIPI 17 #define CLK_PLL_HSIC 18 #define CLK_PLL_DE 19 #define CLK_PLL_DDR1 20 From 383ca7bee8a93be9ff5a072936981c2710d2856b Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 3 Jan 2025 23:37:00 -0800 Subject: [PATCH 40/81] clk: sunxi-ng: a64: stop force-selecting PLL-MIPI as TCON0 parent Stop force-selecting PLL-MIPI as TCON0 parent, since it breaks video output on Pinebook that uses RGB to eDP bridge. Partially revert commit ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux"), while still leaving CLK_SET_RATE_NO_REPARENT flag set, since we do not want the clock to be reparented. The issue is that apparently different TCON0 outputs require a different clock, or the mux might be selecting the output type. I did an experiment: I manually configured PLL_MIPI and PLL_VIDEO0_2X to the same clock rate and flipped the switch with devmem. Experiment clearly showed that whenever PLL_MIPI is selected as TCON0 clock parent, the video output stops working. Therefore, TCON0 clock parent corresponding to the output type must be assigned in the device tree. Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux") Reviewed-by: Dragan Simic Reviewed-by: Chen-Yu Tsai Tested-by: Frank Oltmanns # on PinePhone Tested-by: Stuart Gathman # on OG Pinebook Signed-off-by: Vasily Khoruzhick Link: https://patch.msgid.link/20250104074035.1611136-5-anarsoul@gmail.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index 82d7dcbca1cc9..63f0259b0e995 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -535,11 +535,11 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, CLK_SET_RATE_PARENT); /* - * DSI output seems to work only when PLL_MIPI selected. Set it and prevent - * the mux from reparenting. + * Experiments showed that RGB output requires pll-video0-2x, while DSI + * requires pll-mipi. It will not work with incorrect clock, the screen will + * be blank. + * sun50i-a64.dtsi assigns pll-mipi as TCON0 parent by default */ -#define SUN50I_A64_TCON0_CLK_REG 0x118 - static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" }; static const u8 tcon0_table[] = { 0, 2, }; static SUNXI_CCU_MUX_TABLE_WITH_GATE_CLOSEST(tcon0_clk, "tcon0", tcon0_parents, @@ -959,11 +959,6 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev) writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG); - /* Set PLL MIPI as parent for TCON0 */ - val = readl(reg + SUN50I_A64_TCON0_CLK_REG); - val &= ~GENMASK(26, 24); - writel(val | (0 << 24), reg + SUN50I_A64_TCON0_CLK_REG); - ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc); if (ret) return ret; From 42b00f445616335becee9142c0f7ef7abfee5c61 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 4 Dec 2024 11:37:17 -0800 Subject: [PATCH 41/81] dt-bindings: clock: qcom: Add SM8750 GCC Add device tree bindings for the global clock controller on Qualcomm SM8750 platform. Signed-off-by: Taniya Das Signed-off-by: Melody Olvera Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20241204-sm8750_master_clks-v3-5-1a8f31a53a86@quicinc.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm8750-gcc.yaml | 62 +++++ include/dt-bindings/clock/qcom,sm8750-gcc.h | 226 ++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml create mode 100644 include/dt-bindings/clock/qcom,sm8750-gcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml new file mode 100644 index 0000000000000..aab7039fd28db --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sm8750-gcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Global Clock & Reset Controller on SM8750 + +maintainers: + - Taniya Das + +description: | + Qualcomm global clock control module provides the clocks, resets and power + domains on SM8750 + + See also: include/dt-bindings/clock/qcom,sm8750-gcc.h + +properties: + compatible: + const: qcom,sm8750-gcc + + clocks: + items: + - description: Board XO source + - description: Board Always On XO source + - description: Sleep clock source + - description: PCIE 0 Pipe clock source + - description: UFS Phy Rx symbol 0 clock source + - description: UFS Phy Rx symbol 1 clock source + - description: UFS Phy Tx symbol 0 clock source + - description: USB3 Phy wrapper pipe clock source + +required: + - compatible + - clocks + - '#power-domain-cells' + +allOf: + - $ref: qcom,gcc.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + clock-controller@100000 { + compatible = "qcom,sm8750-gcc"; + reg = <0x00100000 0x001f4200>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&rpmhcc RPMH_CXO_CLK_A>, + <&sleep_clk>, + <&pcie0_phy>, + <&ufs_mem_phy 0>, + <&ufs_mem_phy 1>, + <&ufs_mem_phy 2>, + <&usb_1_qmpphy>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + +... diff --git a/include/dt-bindings/clock/qcom,sm8750-gcc.h b/include/dt-bindings/clock/qcom,sm8750-gcc.h new file mode 100644 index 0000000000000..e234595d7f42d --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8750-gcc.h @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SM8750_H +#define _DT_BINDINGS_CLK_QCOM_GCC_SM8750_H + +/* GCC clocks */ +#define GCC_AGGRE_NOC_PCIE_AXI_CLK 0 +#define GCC_AGGRE_UFS_PHY_AXI_CLK 1 +#define GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK 2 +#define GCC_AGGRE_USB3_PRIM_AXI_CLK 3 +#define GCC_BOOT_ROM_AHB_CLK 4 +#define GCC_CAM_BIST_MCLK_AHB_CLK 5 +#define GCC_CAMERA_AHB_CLK 6 +#define GCC_CAMERA_HF_AXI_CLK 7 +#define GCC_CAMERA_SF_AXI_CLK 8 +#define GCC_CAMERA_XO_CLK 9 +#define GCC_CFG_NOC_PCIE_ANOC_AHB_CLK 10 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 11 +#define GCC_CNOC_PCIE_SF_AXI_CLK 12 +#define GCC_DDRSS_GPU_AXI_CLK 13 +#define GCC_DDRSS_PCIE_SF_QTB_CLK 14 +#define GCC_DISP_AHB_CLK 15 +#define GCC_DISP_HF_AXI_CLK 16 +#define GCC_EVA_AHB_CLK 17 +#define GCC_EVA_AXI0_CLK 18 +#define GCC_EVA_AXI0C_CLK 19 +#define GCC_EVA_XO_CLK 20 +#define GCC_GP1_CLK 21 +#define GCC_GP1_CLK_SRC 22 +#define GCC_GP2_CLK 23 +#define GCC_GP2_CLK_SRC 24 +#define GCC_GP3_CLK 25 +#define GCC_GP3_CLK_SRC 26 +#define GCC_GPLL0 27 +#define GCC_GPLL0_OUT_EVEN 28 +#define GCC_GPLL1 29 +#define GCC_GPLL4 30 +#define GCC_GPLL7 31 +#define GCC_GPLL9 32 +#define GCC_GPU_CFG_AHB_CLK 33 +#define GCC_GPU_GEMNOC_GFX_CLK 34 +#define GCC_GPU_GPLL0_CLK_SRC 35 +#define GCC_GPU_GPLL0_DIV_CLK_SRC 36 +#define GCC_PCIE_0_AUX_CLK 37 +#define GCC_PCIE_0_AUX_CLK_SRC 38 +#define GCC_PCIE_0_CFG_AHB_CLK 39 +#define GCC_PCIE_0_MSTR_AXI_CLK 40 +#define GCC_PCIE_0_PHY_RCHNG_CLK 41 +#define GCC_PCIE_0_PHY_RCHNG_CLK_SRC 42 +#define GCC_PCIE_0_PIPE_CLK 43 +#define GCC_PCIE_0_PIPE_CLK_SRC 44 +#define GCC_PCIE_0_SLV_AXI_CLK 45 +#define GCC_PCIE_0_SLV_Q2A_AXI_CLK 46 +#define GCC_PCIE_RSCC_CFG_AHB_CLK 47 +#define GCC_PCIE_RSCC_XO_CLK 48 +#define GCC_PDM2_CLK 49 +#define GCC_PDM2_CLK_SRC 50 +#define GCC_PDM_AHB_CLK 51 +#define GCC_PDM_XO4_CLK 52 +#define GCC_QMIP_CAMERA_CMD_AHB_CLK 53 +#define GCC_QMIP_CAMERA_NRT_AHB_CLK 54 +#define GCC_QMIP_CAMERA_RT_AHB_CLK 55 +#define GCC_QMIP_GPU_AHB_CLK 56 +#define GCC_QMIP_PCIE_AHB_CLK 57 +#define GCC_QMIP_VIDEO_CV_CPU_AHB_CLK 58 +#define GCC_QMIP_VIDEO_CVP_AHB_CLK 59 +#define GCC_QMIP_VIDEO_V_CPU_AHB_CLK 60 +#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK 61 +#define GCC_QUPV3_I2C_CORE_CLK 62 +#define GCC_QUPV3_I2C_S0_CLK 63 +#define GCC_QUPV3_I2C_S0_CLK_SRC 64 +#define GCC_QUPV3_I2C_S1_CLK 65 +#define GCC_QUPV3_I2C_S1_CLK_SRC 66 +#define GCC_QUPV3_I2C_S2_CLK 67 +#define GCC_QUPV3_I2C_S2_CLK_SRC 68 +#define GCC_QUPV3_I2C_S3_CLK 69 +#define GCC_QUPV3_I2C_S3_CLK_SRC 70 +#define GCC_QUPV3_I2C_S4_CLK 71 +#define GCC_QUPV3_I2C_S4_CLK_SRC 72 +#define GCC_QUPV3_I2C_S5_CLK 73 +#define GCC_QUPV3_I2C_S5_CLK_SRC 74 +#define GCC_QUPV3_I2C_S6_CLK 75 +#define GCC_QUPV3_I2C_S6_CLK_SRC 76 +#define GCC_QUPV3_I2C_S7_CLK 77 +#define GCC_QUPV3_I2C_S7_CLK_SRC 78 +#define GCC_QUPV3_I2C_S8_CLK 79 +#define GCC_QUPV3_I2C_S8_CLK_SRC 80 +#define GCC_QUPV3_I2C_S9_CLK 81 +#define GCC_QUPV3_I2C_S9_CLK_SRC 82 +#define GCC_QUPV3_I2C_S_AHB_CLK 83 +#define GCC_QUPV3_WRAP1_CORE_2X_CLK 84 +#define GCC_QUPV3_WRAP1_CORE_CLK 85 +#define GCC_QUPV3_WRAP1_QSPI_REF_CLK 86 +#define GCC_QUPV3_WRAP1_QSPI_REF_CLK_SRC 87 +#define GCC_QUPV3_WRAP1_S0_CLK 88 +#define GCC_QUPV3_WRAP1_S0_CLK_SRC 89 +#define GCC_QUPV3_WRAP1_S1_CLK 90 +#define GCC_QUPV3_WRAP1_S1_CLK_SRC 91 +#define GCC_QUPV3_WRAP1_S2_CLK 92 +#define GCC_QUPV3_WRAP1_S2_CLK_SRC 93 +#define GCC_QUPV3_WRAP1_S3_CLK 94 +#define GCC_QUPV3_WRAP1_S3_CLK_SRC 95 +#define GCC_QUPV3_WRAP1_S4_CLK 96 +#define GCC_QUPV3_WRAP1_S4_CLK_SRC 97 +#define GCC_QUPV3_WRAP1_S5_CLK 98 +#define GCC_QUPV3_WRAP1_S5_CLK_SRC 99 +#define GCC_QUPV3_WRAP1_S6_CLK 100 +#define GCC_QUPV3_WRAP1_S6_CLK_SRC 101 +#define GCC_QUPV3_WRAP1_S7_CLK 102 +#define GCC_QUPV3_WRAP1_S7_CLK_SRC 103 +#define GCC_QUPV3_WRAP2_CORE_2X_CLK 104 +#define GCC_QUPV3_WRAP2_CORE_CLK 105 +#define GCC_QUPV3_WRAP2_IBI_CTRL_0_CLK_SRC 106 +#define GCC_QUPV3_WRAP2_IBI_CTRL_2_CLK 107 +#define GCC_QUPV3_WRAP2_IBI_CTRL_3_CLK 108 +#define GCC_QUPV3_WRAP2_S0_CLK 109 +#define GCC_QUPV3_WRAP2_S0_CLK_SRC 110 +#define GCC_QUPV3_WRAP2_S1_CLK 111 +#define GCC_QUPV3_WRAP2_S1_CLK_SRC 112 +#define GCC_QUPV3_WRAP2_S2_CLK 113 +#define GCC_QUPV3_WRAP2_S2_CLK_SRC 114 +#define GCC_QUPV3_WRAP2_S3_CLK 115 +#define GCC_QUPV3_WRAP2_S3_CLK_SRC 116 +#define GCC_QUPV3_WRAP2_S4_CLK 117 +#define GCC_QUPV3_WRAP2_S4_CLK_SRC 118 +#define GCC_QUPV3_WRAP2_S5_CLK 119 +#define GCC_QUPV3_WRAP2_S5_CLK_SRC 120 +#define GCC_QUPV3_WRAP2_S6_CLK 121 +#define GCC_QUPV3_WRAP2_S6_CLK_SRC 122 +#define GCC_QUPV3_WRAP2_S7_CLK 123 +#define GCC_QUPV3_WRAP2_S7_CLK_SRC 124 +#define GCC_QUPV3_WRAP_1_M_AHB_CLK 125 +#define GCC_QUPV3_WRAP_1_S_AHB_CLK 126 +#define GCC_QUPV3_WRAP_2_IBI_2_AHB_CLK 127 +#define GCC_QUPV3_WRAP_2_IBI_3_AHB_CLK 128 +#define GCC_QUPV3_WRAP_2_M_AHB_CLK 129 +#define GCC_QUPV3_WRAP_2_S_AHB_CLK 130 +#define GCC_SDCC2_AHB_CLK 131 +#define GCC_SDCC2_APPS_CLK 132 +#define GCC_SDCC2_APPS_CLK_SRC 133 +#define GCC_SDCC4_AHB_CLK 134 +#define GCC_SDCC4_APPS_CLK 135 +#define GCC_SDCC4_APPS_CLK_SRC 136 +#define GCC_UFS_PHY_AHB_CLK 137 +#define GCC_UFS_PHY_AXI_CLK 138 +#define GCC_UFS_PHY_AXI_CLK_SRC 139 +#define GCC_UFS_PHY_AXI_HW_CTL_CLK 140 +#define GCC_UFS_PHY_ICE_CORE_CLK 141 +#define GCC_UFS_PHY_ICE_CORE_CLK_SRC 142 +#define GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK 143 +#define GCC_UFS_PHY_PHY_AUX_CLK 144 +#define GCC_UFS_PHY_PHY_AUX_CLK_SRC 145 +#define GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK 146 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK 147 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC 148 +#define GCC_UFS_PHY_RX_SYMBOL_1_CLK 149 +#define GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC 150 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK 151 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC 152 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK 153 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC 154 +#define GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK 155 +#define GCC_USB30_PRIM_MASTER_CLK 156 +#define GCC_USB30_PRIM_MASTER_CLK_SRC 157 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK 158 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 159 +#define GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC 160 +#define GCC_USB30_PRIM_SLEEP_CLK 161 +#define GCC_USB3_PRIM_PHY_AUX_CLK 162 +#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 163 +#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 164 +#define GCC_USB3_PRIM_PHY_PIPE_CLK 165 +#define GCC_USB3_PRIM_PHY_PIPE_CLK_SRC 166 +#define GCC_VIDEO_AHB_CLK 167 +#define GCC_VIDEO_AXI0_CLK 168 +#define GCC_VIDEO_AXI1_CLK 169 +#define GCC_VIDEO_XO_CLK 170 + +/* GCC power domains */ +#define GCC_PCIE_0_GDSC 0 +#define GCC_PCIE_0_PHY_GDSC 1 +#define GCC_UFS_MEM_PHY_GDSC 2 +#define GCC_UFS_PHY_GDSC 3 +#define GCC_USB30_PRIM_GDSC 4 +#define GCC_USB3_PHY_GDSC 5 + +/* GCC resets */ +#define GCC_CAMERA_BCR 0 +#define GCC_DISPLAY_BCR 1 +#define GCC_EVA_BCR 2 +#define GCC_GPU_BCR 3 +#define GCC_PCIE_0_BCR 4 +#define GCC_PCIE_0_LINK_DOWN_BCR 5 +#define GCC_PCIE_0_NOCSR_COM_PHY_BCR 6 +#define GCC_PCIE_0_PHY_BCR 7 +#define GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR 8 +#define GCC_PCIE_PHY_BCR 9 +#define GCC_PCIE_PHY_CFG_AHB_BCR 10 +#define GCC_PCIE_PHY_COM_BCR 11 +#define GCC_PCIE_RSCC_BCR 12 +#define GCC_PDM_BCR 13 +#define GCC_QUPV3_WRAPPER_1_BCR 14 +#define GCC_QUPV3_WRAPPER_2_BCR 15 +#define GCC_QUPV3_WRAPPER_I2C_BCR 16 +#define GCC_QUSB2PHY_PRIM_BCR 17 +#define GCC_QUSB2PHY_SEC_BCR 18 +#define GCC_SDCC2_BCR 19 +#define GCC_SDCC4_BCR 20 +#define GCC_UFS_PHY_BCR 21 +#define GCC_USB30_PRIM_BCR 22 +#define GCC_USB3_DP_PHY_PRIM_BCR 23 +#define GCC_USB3_DP_PHY_SEC_BCR 24 +#define GCC_USB3_PHY_PRIM_BCR 25 +#define GCC_USB3_PHY_SEC_BCR 26 +#define GCC_USB3PHY_PHY_PRIM_BCR 27 +#define GCC_USB3PHY_PHY_SEC_BCR 28 +#define GCC_VIDEO_AXI0_CLK_ARES 29 +#define GCC_VIDEO_AXI1_CLK_ARES 30 +#define GCC_VIDEO_BCR 31 +#define GCC_EVA_AXI0_CLK_ARES 32 +#define GCC_EVA_AXI0C_CLK_ARES 33 + +#endif From 8817c21a45b62c17f18417efbd0b04a3805a1e23 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 4 Dec 2024 11:37:19 -0800 Subject: [PATCH 42/81] dt-bindings: clock: qcom: Document the SM8750 TCSR Clock Controller Add bindings documentation for the SM8750 Clock Controller. Acked-by: Krzysztof Kozlowski Signed-off-by: Melody Olvera Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20241204-sm8750_master_clks-v3-7-1a8f31a53a86@quicinc.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm8550-tcsr.yaml | 2 ++ include/dt-bindings/clock/qcom,sm8750-tcsr.h | 15 +++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,sm8750-tcsr.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml index 3b546deb514af..f3afbb25e8682 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml @@ -16,6 +16,7 @@ description: | See also: - include/dt-bindings/clock/qcom,sm8550-tcsr.h - include/dt-bindings/clock/qcom,sm8650-tcsr.h + - include/dt-bindings/clock/qcom,sm8750-tcsr.h properties: compatible: @@ -24,6 +25,7 @@ properties: - qcom,sar2130p-tcsr - qcom,sm8550-tcsr - qcom,sm8650-tcsr + - qcom,sm8750-tcsr - qcom,x1e80100-tcsr - const: syscon diff --git a/include/dt-bindings/clock/qcom,sm8750-tcsr.h b/include/dt-bindings/clock/qcom,sm8750-tcsr.h new file mode 100644 index 0000000000000..1c502ac7c7f40 --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8750-tcsr.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_TCSR_CC_SM8750_H +#define _DT_BINDINGS_CLK_QCOM_TCSR_CC_SM8750_H + +/* TCSR_CC clocks */ +#define TCSR_PCIE_0_CLKREF_EN 0 +#define TCSR_UFS_CLKREF_EN 1 +#define TCSR_USB2_CLKREF_EN 2 +#define TCSR_USB3_CLKREF_EN 3 + +#endif From 6badb455ae983f4b2b7e91e3083db64765662a6c Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 4 Dec 2024 11:37:13 -0800 Subject: [PATCH 43/81] dt-bindings: clock: qcom-rpmhcc: Add RPMHCC for SM8750 Update the documentation for clock rpmh driver on SM8750 SoCs. Signed-off-by: Melody Olvera Reviewed-by: Krzysztof Kozlowski Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20241204-sm8750_master_clks-v3-1-1a8f31a53a86@quicinc.com Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml index a9cd33aef73b6..dcb872b9cf3e0 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml @@ -38,6 +38,7 @@ properties: - qcom,sm8450-rpmh-clk - qcom,sm8550-rpmh-clk - qcom,sm8650-rpmh-clk + - qcom,sm8750-rpmh-clk - qcom,x1e80100-rpmh-clk clocks: From d7df7a718fd661960f268ef353fdca66fc693f3d Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 4 Dec 2024 11:37:14 -0800 Subject: [PATCH 44/81] clk: qcom: rpmh: Sort the match table alphabetically Update the match table for SC7280 to sort it in alphabetical order. Signed-off-by: Taniya Das Signed-off-by: Melody Olvera Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20241204-sm8750_master_clks-v3-2-1a8f31a53a86@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rpmh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 7c6b6ef642c11..260443e4bb836 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -913,6 +913,7 @@ static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,sa8775p-rpmh-clk", .data = &clk_rpmh_sa8775p}, { .compatible = "qcom,sar2130p-rpmh-clk", .data = &clk_rpmh_sar2130p}, { .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180}, + { .compatible = "qcom,sc7280-rpmh-clk", .data = &clk_rpmh_sc7280}, { .compatible = "qcom,sc8180x-rpmh-clk", .data = &clk_rpmh_sc8180x}, { .compatible = "qcom,sc8280xp-rpmh-clk", .data = &clk_rpmh_sc8280xp}, { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845}, @@ -928,7 +929,6 @@ static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,sm8450-rpmh-clk", .data = &clk_rpmh_sm8450}, { .compatible = "qcom,sm8550-rpmh-clk", .data = &clk_rpmh_sm8550}, { .compatible = "qcom,sm8650-rpmh-clk", .data = &clk_rpmh_sm8650}, - { .compatible = "qcom,sc7280-rpmh-clk", .data = &clk_rpmh_sc7280}, { .compatible = "qcom,x1e80100-rpmh-clk", .data = &clk_rpmh_x1e80100}, { } }; From c035a9e265dd80a018cfde0fd07ceca9e1d07c98 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 4 Dec 2024 11:37:15 -0800 Subject: [PATCH 45/81] clk: qcom: rpmh: Add support for SM8750 rpmh clocks Add the RPMH clocks present in SM8750 SoC. Reviewed-by: Bryan O'Donoghue Signed-off-by: Melody Olvera Signed-off-by: Taniya Das Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20241204-sm8750_master_clks-v3-3-1a8f31a53a86@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rpmh.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 260443e4bb836..18de318895255 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -368,6 +368,8 @@ DEFINE_CLK_RPMH_VRM(rf_clk2, _d, "rfclkd2", 1); DEFINE_CLK_RPMH_VRM(rf_clk3, _d, "rfclkd3", 1); DEFINE_CLK_RPMH_VRM(rf_clk4, _d, "rfclkd4", 1); +DEFINE_CLK_RPMH_VRM(rf_clk3, _a2, "rfclka3", 2); + DEFINE_CLK_RPMH_VRM(clk1, _a1, "clka1", 1); DEFINE_CLK_RPMH_VRM(clk2, _a1, "clka2", 1); DEFINE_CLK_RPMH_VRM(clk3, _a1, "clka3", 1); @@ -825,6 +827,27 @@ static const struct clk_rpmh_desc clk_rpmh_qcs615 = { .num_clks = ARRAY_SIZE(qcs615_rpmh_clocks), }; +static struct clk_hw *sm8750_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, + [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, + [RPMH_LN_BB_CLK1] = &clk_rpmh_clk6_a2.hw, + [RPMH_LN_BB_CLK1_A] = &clk_rpmh_clk6_a2_ao.hw, + [RPMH_LN_BB_CLK3] = &clk_rpmh_clk8_a2.hw, + [RPMH_LN_BB_CLK3_A] = &clk_rpmh_clk8_a2_ao.hw, + [RPMH_RF_CLK1] = &clk_rpmh_rf_clk1_a.hw, + [RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_a_ao.hw, + [RPMH_RF_CLK2] = &clk_rpmh_rf_clk2_a.hw, + [RPMH_RF_CLK2_A] = &clk_rpmh_rf_clk2_a_ao.hw, + [RPMH_RF_CLK3] = &clk_rpmh_rf_clk3_a2.hw, + [RPMH_RF_CLK3_A] = &clk_rpmh_rf_clk3_a2_ao.hw, + [RPMH_IPA_CLK] = &clk_rpmh_ipa.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_sm8750 = { + .clks = sm8750_rpmh_clocks, + .num_clks = ARRAY_SIZE(sm8750_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -929,6 +952,7 @@ static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,sm8450-rpmh-clk", .data = &clk_rpmh_sm8450}, { .compatible = "qcom,sm8550-rpmh-clk", .data = &clk_rpmh_sm8550}, { .compatible = "qcom,sm8650-rpmh-clk", .data = &clk_rpmh_sm8650}, + { .compatible = "qcom,sm8750-rpmh-clk", .data = &clk_rpmh_sm8750}, { .compatible = "qcom,x1e80100-rpmh-clk", .data = &clk_rpmh_x1e80100}, { } }; From 745d755b8551319a100adafc6e776a2766102ea9 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 4 Dec 2024 11:37:16 -0800 Subject: [PATCH 46/81] clk: qcom: clk-alpha-pll: Add support for controlling Taycan PLLs Add clock ops for Taycan PLL, add the register offsets for supporting the PLL. Signed-off-by: Melody Olvera Reviewed-by: Dmitry Baryshkov Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20241204-sm8750_master_clks-v3-4-1a8f31a53a86@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-alpha-pll.c | 14 ++++++++++++++ drivers/clk/qcom/clk-alpha-pll.h | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 35e97eab5d059..9c0cc1e5789da 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -197,6 +197,20 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL_U1] = 0x34, [PLL_OFF_TEST_CTL_U2] = 0x38, }, + [CLK_ALPHA_PLL_TYPE_TAYCAN_ELU] = { + [PLL_OFF_OPMODE] = 0x04, + [PLL_OFF_STATE] = 0x08, + [PLL_OFF_STATUS] = 0x0c, + [PLL_OFF_L_VAL] = 0x10, + [PLL_OFF_ALPHA_VAL] = 0x14, + [PLL_OFF_USER_CTL] = 0x18, + [PLL_OFF_USER_CTL_U] = 0x1c, + [PLL_OFF_CONFIG_CTL] = 0x20, + [PLL_OFF_CONFIG_CTL_U] = 0x24, + [PLL_OFF_CONFIG_CTL_U1] = 0x28, + [PLL_OFF_TEST_CTL] = 0x2c, + [PLL_OFF_TEST_CTL_U] = 0x30, + }, [CLK_ALPHA_PLL_TYPE_RIVIAN_EVO] = { [PLL_OFF_OPMODE] = 0x04, [PLL_OFF_STATUS] = 0x0c, diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index c6d1b8429f951..87bd469d9c2c2 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -27,6 +27,7 @@ enum { CLK_ALPHA_PLL_TYPE_ZONDA_OLE, CLK_ALPHA_PLL_TYPE_LUCID_EVO, CLK_ALPHA_PLL_TYPE_LUCID_OLE, + CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, CLK_ALPHA_PLL_TYPE_DEFAULT_EVO, CLK_ALPHA_PLL_TYPE_BRAMMO_EVO, @@ -185,12 +186,15 @@ extern const struct clk_ops clk_alpha_pll_zonda_ops; #define clk_alpha_pll_zonda_ole_ops clk_alpha_pll_zonda_ops extern const struct clk_ops clk_alpha_pll_lucid_evo_ops; +#define clk_alpha_pll_taycan_elu_ops clk_alpha_pll_lucid_evo_ops extern const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops; #define clk_alpha_pll_reset_lucid_ole_ops clk_alpha_pll_reset_lucid_evo_ops extern const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops; #define clk_alpha_pll_fixed_lucid_ole_ops clk_alpha_pll_fixed_lucid_evo_ops +#define clk_alpha_pll_fixed_taycan_elu_ops clk_alpha_pll_fixed_lucid_evo_ops extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; #define clk_alpha_pll_postdiv_lucid_ole_ops clk_alpha_pll_postdiv_lucid_evo_ops +#define clk_alpha_pll_postdiv_taycan_elu_ops clk_alpha_pll_postdiv_lucid_evo_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 @@ -218,6 +222,9 @@ void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regma const struct alpha_pll_config *config); void clk_lucid_ole_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); +#define clk_taycan_elu_pll_configure(pll, regmap, config) \ + clk_lucid_evo_pll_configure(pll, regmap, config) + void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); void clk_stromer_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, From 3267c774f3ff61fc945a7531b2ae6784c37cd14f Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 4 Dec 2024 11:37:18 -0800 Subject: [PATCH 47/81] clk: qcom: Add support for GCC on SM8750 Add support for GCC for SM8750 platform. Signed-off-by: Melody Olvera Signed-off-by: Taniya Das Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20241204-sm8750_master_clks-v3-6-1a8f31a53a86@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-sm8750.c | 3274 +++++++++++++++++++++++++++++++++ 3 files changed, 3284 insertions(+) create mode 100644 drivers/clk/qcom/gcc-sm8750.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index a96049605f0de..42f05fa27f29a 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1149,6 +1149,15 @@ config SM_GCC_8650 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, SD/UFS, PCIe etc. +config SM_GCC_8750 + tristate "SM8750 Global Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the global clock controller on SM8750 devices. + Say Y if you want to use peripheral devices such as UART, + SPI, I2C, USB, SD/UFS, PCIe etc. + config SM_GPUCC_4450 tristate "SM4450 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 5666554484ed2..beb2f4d7ee84d 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -145,6 +145,7 @@ obj-$(CONFIG_SM_GCC_8350) += gcc-sm8350.o obj-$(CONFIG_SM_GCC_8450) += gcc-sm8450.o obj-$(CONFIG_SM_GCC_8550) += gcc-sm8550.o obj-$(CONFIG_SM_GCC_8650) += gcc-sm8650.o +obj-$(CONFIG_SM_GCC_8750) += gcc-sm8750.o obj-$(CONFIG_SM_GPUCC_4450) += gpucc-sm4450.o obj-$(CONFIG_SM_GPUCC_6115) += gpucc-sm6115.o obj-$(CONFIG_SM_GPUCC_6125) += gpucc-sm6125.o diff --git a/drivers/clk/qcom/gcc-sm8750.c b/drivers/clk/qcom/gcc-sm8750.c new file mode 100644 index 0000000000000..b36d709760958 --- /dev/null +++ b/drivers/clk/qcom/gcc-sm8750.c @@ -0,0 +1,3274 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#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_ELU], + .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_elu_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_ELU], + .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_elu_ops, + }, +}; + +static struct clk_alpha_pll gcc_gpll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .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_elu_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll4 = { + .offset = 0x4000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .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_elu_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll7 = { + .offset = 0x7000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .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_elu_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll9 = { + .offset = 0x9000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .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_elu_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_SLEEP_CLK, 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 }, + { .index = DT_SLEEP_CLK }, + { .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_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_2[] = { + { .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_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 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_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 }, +}; + +static const struct clk_parent_data gcc_parent_data_6[] = { + { .index = DT_BI_TCXO }, +}; + +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_9[] = { + { P_UFS_PHY_RX_SYMBOL_0_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_9[] = { + { .index = DT_UFS_PHY_RX_SYMBOL_0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_10[] = { + { P_UFS_PHY_RX_SYMBOL_1_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_10[] = { + { .index = DT_UFS_PHY_RX_SYMBOL_1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_11[] = { + { P_UFS_PHY_TX_SYMBOL_0_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_11[] = { + { .index = DT_UFS_PHY_TX_SYMBOL_0_CLK }, + { .index = DT_BI_TCXO }, +}; + +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 = 0x6b080, + .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_mux gcc_ufs_phy_rx_symbol_0_clk_src = { + .reg = 0x77068, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_9, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk_src", + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_ufs_phy_rx_symbol_1_clk_src = { + .reg = 0x770ec, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_10, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk_src", + .parent_data = gcc_parent_data_10, + .num_parents = ARRAY_SIZE(gcc_parent_data_10), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_ufs_phy_tx_symbol_0_clk_src = { + .reg = 0x77058, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_11, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk_src", + .parent_data = gcc_parent_data_11, + .num_parents = ARRAY_SIZE(gcc_parent_data_11), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = { + .reg = 0x39070, + .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_1, + .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_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x65004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .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_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x66004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .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_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_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 = 0x6b084, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .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_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_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 = 0x6b068, + .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_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_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_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_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_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_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_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s5_clk_src = { + .cmd_rcgr = 0x17094, + .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_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_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s6_clk_src = { + .cmd_rcgr = 0x170b0, + .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_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_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s7_clk_src = { + .cmd_rcgr = 0x170cc, + .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_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_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s8_clk_src = { + .cmd_rcgr = 0x170e8, + .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_s8_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, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s9_clk_src = { + .cmd_rcgr = 0x17104, + .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_s9_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, + }, +}; + +/* Check this frequency table.*/ +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(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_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(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + 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_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_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_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 const struct freq_tbl ftbl_gcc_qupv3_wrap1_s3_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(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_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_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_s3_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, +}; + +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_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_s0_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_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_s3_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_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_s3_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_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_s3_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap2_ibi_ctrl_0_clk_src[] = { + F(37500000, P_GCC_GPLL0_OUT_EVEN, 8, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_ibi_ctrl_0_clk_src = { + .cmd_rcgr = 0x1e9f4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_qupv3_wrap2_ibi_ctrl_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_ibi_ctrl_0_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +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_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_s0_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_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_s0_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_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_s0_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_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_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_s3_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = { + .name = "gcc_qupv3_wrap2_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_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = { + .cmd_rcgr = 0x1e640, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s3_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s5_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap2_s6_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(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(128000000, P_GCC_GPLL0_OUT_MAIN, 1, 16, 75), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap2_s6_clk_src_init = { + .name = "gcc_qupv3_wrap2_s6_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_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = { + .cmd_rcgr = 0x1e77c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_qupv3_wrap2_s6_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s6_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s7_clk_src_init = { + .name = "gcc_qupv3_wrap2_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_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = { + .cmd_rcgr = 0x1e8b8, + .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_s7_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(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_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_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(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_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = { + 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_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_6, + .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_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_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_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 = 0x39030, + .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_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0x39048, + .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_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0x39074, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .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_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_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 = 0x39060, + .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 = 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_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 = 0x52000, + .enable_mask = BIT(10), + .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 = 0x26024, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x26024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26024, + .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_VOTED, + .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 = 0x3908c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x3908c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3908c, + .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, + .hwcg_reg = 0x10058, + .hwcg_bit = 1, + .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_gpu_axi_clk = { + .halt_reg = 0x71150, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x71150, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71150, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ddrss_gpu_axi_clk", + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_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 = 0x27008, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x27008, + .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_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 = 0x9f018, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x9f018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9f018, + .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_rchng_clk = { + .halt_reg = 0x6b064, + .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 = 0x6b054, + .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_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 = 0x52000, + .enable_mask = BIT(11), + .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_s5_clk = { + .halt_reg = 0x17090, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s6_clk = { + .halt_reg = 0x170ac, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s7_clk = { + .halt_reg = 0x170c8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s7_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s8_clk = { + .halt_reg = 0x170e4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s8_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s8_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s9_clk = { + .halt_reg = 0x17100, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s9_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s9_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_ibi_ctrl_2_clk = { + .halt_reg = 0x1e9ec, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1e9ec, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_ibi_ctrl_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_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_wrap2_ibi_ctrl_3_clk = { + .halt_reg = 0x1e9f0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1e9f0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_ibi_ctrl_3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_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_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_wrap2_s5_clk = { + .halt_reg = 0x1e630, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s6_clk = { + .halt_reg = 0x1e76c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s7_clk = { + .halt_reg = 0x1e8a8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s7_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s7_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_ahb_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_ahb_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_ibi_2_ahb_clk = { + .halt_reg = 0x1e9e4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1e9e4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_2_ibi_2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_ibi_3_ahb_clk = { + .halt_reg = 0x1e9e8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1e9e8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_2_ibi_3_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_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 = 0x39064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39064, + .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 = 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_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 = 0x3906c, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x3906c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3906c, + .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 = 0x32028, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x32028, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32028, + .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 = VOTABLE | 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_sm8750_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_GPU_AXI_CLK] = &gcc_ddrss_gpu_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_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_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_QMIP_CAMERA_CMD_AHB_CLK] = &gcc_qmip_camera_cmd_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_GPU_AHB_CLK] = &gcc_qmip_gpu_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, + [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_S5_CLK] = &gcc_qupv3_i2c_s5_clk.clkr, + [GCC_QUPV3_I2C_S5_CLK_SRC] = &gcc_qupv3_i2c_s5_clk_src.clkr, + [GCC_QUPV3_I2C_S6_CLK] = &gcc_qupv3_i2c_s6_clk.clkr, + [GCC_QUPV3_I2C_S6_CLK_SRC] = &gcc_qupv3_i2c_s6_clk_src.clkr, + [GCC_QUPV3_I2C_S7_CLK] = &gcc_qupv3_i2c_s7_clk.clkr, + [GCC_QUPV3_I2C_S7_CLK_SRC] = &gcc_qupv3_i2c_s7_clk_src.clkr, + [GCC_QUPV3_I2C_S8_CLK] = &gcc_qupv3_i2c_s8_clk.clkr, + [GCC_QUPV3_I2C_S8_CLK_SRC] = &gcc_qupv3_i2c_s8_clk_src.clkr, + [GCC_QUPV3_I2C_S9_CLK] = &gcc_qupv3_i2c_s9_clk.clkr, + [GCC_QUPV3_I2C_S9_CLK_SRC] = &gcc_qupv3_i2c_s9_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_IBI_CTRL_0_CLK_SRC] = &gcc_qupv3_wrap2_ibi_ctrl_0_clk_src.clkr, + [GCC_QUPV3_WRAP2_IBI_CTRL_2_CLK] = &gcc_qupv3_wrap2_ibi_ctrl_2_clk.clkr, + [GCC_QUPV3_WRAP2_IBI_CTRL_3_CLK] = &gcc_qupv3_wrap2_ibi_ctrl_3_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_WRAP2_S5_CLK] = &gcc_qupv3_wrap2_s5_clk.clkr, + [GCC_QUPV3_WRAP2_S5_CLK_SRC] = &gcc_qupv3_wrap2_s5_clk_src.clkr, + [GCC_QUPV3_WRAP2_S6_CLK] = &gcc_qupv3_wrap2_s6_clk.clkr, + [GCC_QUPV3_WRAP2_S6_CLK_SRC] = &gcc_qupv3_wrap2_s6_clk_src.clkr, + [GCC_QUPV3_WRAP2_S7_CLK] = &gcc_qupv3_wrap2_s7_clk.clkr, + [GCC_QUPV3_WRAP2_S7_CLK_SRC] = &gcc_qupv3_wrap2_s7_clk_src.clkr, + [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_IBI_2_AHB_CLK] = &gcc_qupv3_wrap_2_ibi_2_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_IBI_3_AHB_CLK] = &gcc_qupv3_wrap_2_ibi_3_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_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, +}; + +static struct gdsc *gcc_sm8750_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_sm8750_resets[] = { + [GCC_CAMERA_BCR] = { 0x26000 }, + [GCC_DISPLAY_BCR] = { 0x27000 }, + [GCC_EVA_BCR] = { 0x9f000 }, + [GCC_EVA_AXI0_CLK_ARES] = { 0x9f008, 2 }, + [GCC_EVA_AXI0C_CLK_ARES] = { 0x9f018, 2 }, + [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_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_BCR] = { 0x32000 }, + [GCC_VIDEO_AXI0_CLK_ARES] = { 0x32018, 2 }, + [GCC_VIDEO_AXI1_CLK_ARES] = { 0x32028, 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_wrap2_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s7_clk_src), +}; + +static const struct regmap_config gcc_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1f41f0, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_sm8750_desc = { + .config = &gcc_sm8750_regmap_config, + .clks = gcc_sm8750_clocks, + .num_clks = ARRAY_SIZE(gcc_sm8750_clocks), + .resets = gcc_sm8750_resets, + .num_resets = ARRAY_SIZE(gcc_sm8750_resets), + .gdscs = gcc_sm8750_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_sm8750_gdscs), +}; + +static const struct of_device_id gcc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-gcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_sm8750_match_table); + +static int gcc_sm8750_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + regmap = qcom_cc_map(pdev, &gcc_sm8750_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, + ARRAY_SIZE(gcc_dfs_clocks)); + if (ret) + return ret; + + /* + * Keep clocks always enabled: + * gcc_cam_bist_mclk_ahb_clk + * gcc_camera_ahb_clk + * gcc_camera_xo_clk + * gcc_disp_ahb_clk + * gcc_eva_ahb_clk + * gcc_eva_xo_clk + * gcc_gpu_cfg_ahb_clk + * gcc_video_ahb_clk + * gcc_video_xo_clk + * gcc_pcie_rscc_cfg_ahb_clk + * gcc_pcie_rscc_xo_clk + */ + qcom_branch_set_clk_en(regmap, 0xa0004); + qcom_branch_set_clk_en(regmap, 0x26004); + qcom_branch_set_clk_en(regmap, 0x26034); + qcom_branch_set_clk_en(regmap, 0x27004); + qcom_branch_set_clk_en(regmap, 0x9f004); + qcom_branch_set_clk_en(regmap, 0x9f01c); + qcom_branch_set_clk_en(regmap, 0x71004); + qcom_branch_set_clk_en(regmap, 0x32004); + qcom_branch_set_clk_en(regmap, 0x32038); + regmap_update_bits(regmap, 0x52010, BIT(20), BIT(20)); + regmap_update_bits(regmap, 0x52010, BIT(21), BIT(21)); + + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); + + return qcom_cc_really_probe(&pdev->dev, &gcc_sm8750_desc, regmap); +} + +static struct platform_driver gcc_sm8750_driver = { + .probe = gcc_sm8750_probe, + .driver = { + .name = "gcc-sm8750", + .of_match_table = gcc_sm8750_match_table, + }, +}; + +static int __init gcc_sm8750_init(void) +{ + return platform_driver_register(&gcc_sm8750_driver); +} +subsys_initcall(gcc_sm8750_init); + +static void __exit gcc_sm8750_exit(void) +{ + platform_driver_unregister(&gcc_sm8750_driver); +} +module_exit(gcc_sm8750_exit); + +MODULE_DESCRIPTION("QTI GCC SM8750 Driver"); +MODULE_LICENSE("GPL"); From 806761852608ebc4d924c2e1c031fb72dcb33ed0 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 4 Dec 2024 11:37:20 -0800 Subject: [PATCH 48/81] clk: qcom: Add TCSR clock driver for SM8750 The TCSR clock controller found on SM8750 provides refclks for PCIE, USB and UFS. Add clock driver for it. Signed-off-by: Melody Olvera Reviewed-by: Dmitry Baryshkov Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20241204-sm8750_master_clks-v3-8-1a8f31a53a86@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 8 ++ drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/tcsrcc-sm8750.c | 141 +++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 drivers/clk/qcom/tcsrcc-sm8750.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 42f05fa27f29a..199e88d3d66eb 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1274,6 +1274,14 @@ config SM_TCSRCC_8650 Support for the TCSR clock controller on SM8650 devices. Say Y if you want to use peripheral devices such as SD/UFS. +config SM_TCSRCC_8750 + tristate "SM8750 TCSR Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the TCSR clock controller on SM8750 devices. + Say Y if you want to use peripheral devices such as UFS/USB/PCIe. + config SA_VIDEOCC_8775P tristate "SA8775P Video Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index beb2f4d7ee84d..cd103a9996a79 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -159,6 +159,7 @@ obj-$(CONFIG_SM_GPUCC_8550) += gpucc-sm8550.o obj-$(CONFIG_SM_GPUCC_8650) += gpucc-sm8650.o obj-$(CONFIG_SM_TCSRCC_8550) += tcsrcc-sm8550.o obj-$(CONFIG_SM_TCSRCC_8650) += tcsrcc-sm8650.o +obj-$(CONFIG_SM_TCSRCC_8750) += tcsrcc-sm8750.o obj-$(CONFIG_SM_VIDEOCC_7150) += videocc-sm7150.o obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o obj-$(CONFIG_SM_VIDEOCC_8250) += videocc-sm8250.o diff --git a/drivers/clk/qcom/tcsrcc-sm8750.c b/drivers/clk/qcom/tcsrcc-sm8750.c new file mode 100644 index 0000000000000..242e320986ef6 --- /dev/null +++ b/drivers/clk/qcom/tcsrcc-sm8750.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#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 = 0x0, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x0, + .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_ufs_clkref_en = { + .halt_reg = 0x1000, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1000, + .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 = 0x2000, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x2000, + .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_branch tcsr_usb3_clkref_en = { + .halt_reg = 0x3000, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x3000, + .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_regmap *tcsr_cc_sm8750_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_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x3000, + .fast_io = true, +}; + +static const struct qcom_cc_desc tcsr_cc_sm8750_desc = { + .config = &tcsr_cc_sm8750_regmap_config, + .clks = tcsr_cc_sm8750_clocks, + .num_clks = ARRAY_SIZE(tcsr_cc_sm8750_clocks), +}; + +static const struct of_device_id tcsr_cc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-tcsr" }, + { } +}; +MODULE_DEVICE_TABLE(of, tcsr_cc_sm8750_match_table); + +static int tcsr_cc_sm8750_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &tcsr_cc_sm8750_desc); +} + +static struct platform_driver tcsr_cc_sm8750_driver = { + .probe = tcsr_cc_sm8750_probe, + .driver = { + .name = "tcsr_cc-sm8750", + .of_match_table = tcsr_cc_sm8750_match_table, + }, +}; + +static int __init tcsr_cc_sm8750_init(void) +{ + return platform_driver_register(&tcsr_cc_sm8750_driver); +} +subsys_initcall(tcsr_cc_sm8750_init); + +static void __exit tcsr_cc_sm8750_exit(void) +{ + platform_driver_unregister(&tcsr_cc_sm8750_driver); +} +module_exit(tcsr_cc_sm8750_exit); + +MODULE_DESCRIPTION("QTI TCSR_CC SM8750 Driver"); +MODULE_LICENSE("GPL"); From 4f1a62e2b3961946a924c093bc2bdd44a2a46c9d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 6 Jan 2025 14:44:29 +0100 Subject: [PATCH 49/81] dt-bindings: clock: qcom,sm8550-dispcc: Add SM8750 DISPCC Add bindings for the Qualcomm SM8750 Display Clock Controller (DISPCC). Bindings are similar to existing SM8550 and SM8650 (same clock inputs), but the clock hierarchy is quite different and these are not compatible devices. The binding header was copied from downstream sources, so I retained original copyrights. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250106-sm8750-dispcc-v2-1-6f42beda6317@linaro.org Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm8550-dispcc.yaml | 4 +- .../dt-bindings/clock/qcom,sm8750-dispcc.h | 112 ++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 include/dt-bindings/clock/qcom,sm8750-dispcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml index c57d55a9293c2..30e4b46315752 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml @@ -12,11 +12,12 @@ maintainers: description: | Qualcomm display clock control module provides the clocks, resets and power - domains on SM8550. + domains on SM8550, SM8650, SM8750 and few other platforms. See also: - include/dt-bindings/clock/qcom,sm8550-dispcc.h - include/dt-bindings/clock/qcom,sm8650-dispcc.h + - include/dt-bindings/clock/qcom,sm8750-dispcc.h - include/dt-bindings/clock/qcom,x1e80100-dispcc.h properties: @@ -25,6 +26,7 @@ properties: - qcom,sar2130p-dispcc - qcom,sm8550-dispcc - qcom,sm8650-dispcc + - qcom,sm8750-dispcc - qcom,x1e80100-dispcc clocks: diff --git a/include/dt-bindings/clock/qcom,sm8750-dispcc.h b/include/dt-bindings/clock/qcom,sm8750-dispcc.h new file mode 100644 index 0000000000000..dafb5069c96a0 --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8750-dispcc.h @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2022, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2024, Linaro Ltd. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_SM8750_DISP_CC_H +#define _DT_BINDINGS_CLK_QCOM_SM8750_DISP_CC_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_BYTE0_CLK 8 +#define DISP_CC_MDSS_BYTE0_CLK_SRC 9 +#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 10 +#define DISP_CC_MDSS_BYTE0_INTF_CLK 11 +#define DISP_CC_MDSS_BYTE1_CLK 12 +#define DISP_CC_MDSS_BYTE1_CLK_SRC 13 +#define DISP_CC_MDSS_BYTE1_DIV_CLK_SRC 14 +#define DISP_CC_MDSS_BYTE1_INTF_CLK 15 +#define DISP_CC_MDSS_DPTX0_AUX_CLK 16 +#define DISP_CC_MDSS_DPTX0_AUX_CLK_SRC 17 +#define DISP_CC_MDSS_DPTX0_CRYPTO_CLK 18 +#define DISP_CC_MDSS_DPTX0_LINK_CLK 19 +#define DISP_CC_MDSS_DPTX0_LINK_CLK_SRC 20 +#define DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC 21 +#define DISP_CC_MDSS_DPTX0_LINK_INTF_CLK 22 +#define DISP_CC_MDSS_DPTX0_PIXEL0_CLK 23 +#define DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC 24 +#define DISP_CC_MDSS_DPTX0_PIXEL1_CLK 25 +#define DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC 26 +#define DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK 27 +#define DISP_CC_MDSS_DPTX1_AUX_CLK 28 +#define DISP_CC_MDSS_DPTX1_AUX_CLK_SRC 29 +#define DISP_CC_MDSS_DPTX1_CRYPTO_CLK 30 +#define DISP_CC_MDSS_DPTX1_LINK_CLK 31 +#define DISP_CC_MDSS_DPTX1_LINK_CLK_SRC 32 +#define DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC 33 +#define DISP_CC_MDSS_DPTX1_LINK_INTF_CLK 34 +#define DISP_CC_MDSS_DPTX1_PIXEL0_CLK 35 +#define DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC 36 +#define DISP_CC_MDSS_DPTX1_PIXEL1_CLK 37 +#define DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC 38 +#define DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK 39 +#define DISP_CC_MDSS_DPTX2_AUX_CLK 40 +#define DISP_CC_MDSS_DPTX2_AUX_CLK_SRC 41 +#define DISP_CC_MDSS_DPTX2_CRYPTO_CLK 42 +#define DISP_CC_MDSS_DPTX2_LINK_CLK 43 +#define DISP_CC_MDSS_DPTX2_LINK_CLK_SRC 44 +#define DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC 45 +#define DISP_CC_MDSS_DPTX2_LINK_INTF_CLK 46 +#define DISP_CC_MDSS_DPTX2_PIXEL0_CLK 47 +#define DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC 48 +#define DISP_CC_MDSS_DPTX2_PIXEL1_CLK 49 +#define DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC 50 +#define DISP_CC_MDSS_DPTX3_AUX_CLK 51 +#define DISP_CC_MDSS_DPTX3_AUX_CLK_SRC 52 +#define DISP_CC_MDSS_DPTX3_CRYPTO_CLK 53 +#define DISP_CC_MDSS_DPTX3_LINK_CLK 54 +#define DISP_CC_MDSS_DPTX3_LINK_CLK_SRC 55 +#define DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC 56 +#define DISP_CC_MDSS_DPTX3_LINK_INTF_CLK 57 +#define DISP_CC_MDSS_DPTX3_PIXEL0_CLK 58 +#define DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC 59 +#define DISP_CC_MDSS_ESC0_CLK 60 +#define DISP_CC_MDSS_ESC0_CLK_SRC 61 +#define DISP_CC_MDSS_ESC1_CLK 62 +#define DISP_CC_MDSS_ESC1_CLK_SRC 63 +#define DISP_CC_MDSS_MDP1_CLK 64 +#define DISP_CC_MDSS_MDP_CLK 65 +#define DISP_CC_MDSS_MDP_CLK_SRC 66 +#define DISP_CC_MDSS_MDP_LUT1_CLK 67 +#define DISP_CC_MDSS_MDP_LUT_CLK 68 +#define DISP_CC_MDSS_NON_GDSC_AHB_CLK 69 +#define DISP_CC_MDSS_PCLK0_CLK 70 +#define DISP_CC_MDSS_PCLK0_CLK_SRC 71 +#define DISP_CC_MDSS_PCLK1_CLK 72 +#define DISP_CC_MDSS_PCLK1_CLK_SRC 73 +#define DISP_CC_MDSS_PCLK2_CLK 74 +#define DISP_CC_MDSS_PCLK2_CLK_SRC 75 +#define DISP_CC_MDSS_RSCC_AHB_CLK 76 +#define DISP_CC_MDSS_RSCC_VSYNC_CLK 77 +#define DISP_CC_MDSS_VSYNC1_CLK 78 +#define DISP_CC_MDSS_VSYNC_CLK 79 +#define DISP_CC_MDSS_VSYNC_CLK_SRC 80 +#define DISP_CC_OSC_CLK 81 +#define DISP_CC_OSC_CLK_SRC 82 +#define DISP_CC_PLL0 83 +#define DISP_CC_PLL1 84 +#define DISP_CC_PLL2 85 +#define DISP_CC_SLEEP_CLK 86 +#define DISP_CC_SLEEP_CLK_SRC 87 +#define DISP_CC_XO_CLK 88 +#define DISP_CC_XO_CLK_SRC 89 + +/* 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 + +/* DISP_CC GDSCR */ +#define MDSS_GDSC 0 +#define MDSS_INT2_GDSC 1 + +#endif From 1adc528937c62324f319ca02d6827a865beafd0b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 6 Jan 2025 14:44:30 +0100 Subject: [PATCH 50/81] clk: qcom: clk-alpha-pll: Add Pongo PLL Add support for Pongo type of PLL clocks, used in Qualcomm SM8750 SoC. Notable difference comparing to other PLLs is the need for calibration for internally generated clock followed by wait_for_pll(). This is done in configure call and at this time clocks are not yet registered, thus wait_for_pll() cannot use clk_hw_get_name. Locking during this calibration requires much more time, thus increase the timeout in wait_for_pll(). Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250106-sm8750-dispcc-v2-2-6f42beda6317@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-alpha-pll.c | 165 ++++++++++++++++++++++++++++++- drivers/clk/qcom/clk-alpha-pll.h | 6 ++ 2 files changed, 170 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 9c0cc1e5789da..9a65d14acf71c 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -58,6 +58,7 @@ #define PLL_TEST_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U]) #define PLL_TEST_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U1]) #define PLL_TEST_CTL_U2(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U2]) +#define PLL_TEST_CTL_U3(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U3]) #define PLL_STATUS(p) ((p)->offset + (p)->regs[PLL_OFF_STATUS]) #define PLL_OPMODE(p) ((p)->offset + (p)->regs[PLL_OFF_OPMODE]) #define PLL_FRAC(p) ((p)->offset + (p)->regs[PLL_OFF_FRAC]) @@ -197,6 +198,23 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL_U1] = 0x34, [PLL_OFF_TEST_CTL_U2] = 0x38, }, + [CLK_ALPHA_PLL_TYPE_PONGO_ELU] = { + [PLL_OFF_OPMODE] = 0x04, + [PLL_OFF_STATE] = 0x08, + [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, + [PLL_OFF_TEST_CTL_U1] = 0x34, + [PLL_OFF_TEST_CTL_U2] = 0x38, + [PLL_OFF_TEST_CTL_U3] = 0x3c, + }, [CLK_ALPHA_PLL_TYPE_TAYCAN_ELU] = { [PLL_OFF_OPMODE] = 0x04, [PLL_OFF_STATE] = 0x08, @@ -337,6 +355,12 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); #define LUCID_EVO_PLL_CAL_L_VAL_SHIFT 16 #define LUCID_OLE_PLL_RINGOSC_CAL_L_VAL_SHIFT 24 +/* PONGO ELU PLL specific setting and offsets */ +#define PONGO_PLL_OUT_MASK GENMASK(1, 0) +#define PONGO_PLL_L_VAL_MASK GENMASK(11, 0) +#define PONGO_XO_PRESENT BIT(10) +#define PONGO_CLOCK_SELECT BIT(12) + /* ZONDA PLL specific */ #define ZONDA_PLL_OUT_MASK 0xf #define ZONDA_STAY_IN_CFA BIT(16) @@ -366,7 +390,8 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse, if (ret) return ret; - for (count = 200; count > 0; count--) { + /* Pongo PLLs using a 32KHz reference can take upwards of 1500us to lock. */ + for (count = 1500; count > 0; count--) { ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val); if (ret) return ret; @@ -2510,6 +2535,144 @@ const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops = { }; EXPORT_SYMBOL_GPL(clk_alpha_pll_reset_lucid_evo_ops); +static int alpha_pll_pongo_elu_prepare(struct clk_hw *hw) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + struct regmap *regmap = pll->clkr.regmap; + int ret; + + /* Enable PLL intially to one-time calibrate against XO. */ + regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN); + regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); + regmap_update_bits(regmap, PLL_MODE(pll), PONGO_XO_PRESENT, PONGO_XO_PRESENT); + + /* Set regmap for wait_for_pll() */ + pll->clkr.regmap = regmap; + ret = wait_for_pll_enable_lock(pll); + if (ret) { + /* Reverse calibration - disable PLL output */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); + return ret; + } + + /* Disable PLL after one-time calibration. */ + regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); + + /* Select internally generated clock. */ + regmap_update_bits(regmap, PLL_MODE(pll), PONGO_CLOCK_SELECT, + PONGO_CLOCK_SELECT); + + return 0; +} + +static int alpha_pll_pongo_elu_enable(struct clk_hw *hw) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + struct regmap *regmap = pll->clkr.regmap; + int ret; + + /* Check if PLL is already enabled */ + if (trion_pll_is_enabled(pll, regmap)) + return 0; + + ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); + if (ret) + return ret; + + /* Set operation mode to RUN */ + regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN); + + ret = wait_for_pll_enable_lock(pll); + if (ret) + return ret; + + /* Enable the global PLL outputs */ + ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL); + if (ret) + return ret; + + /* Ensure that the write above goes through before returning. */ + mb(); + + return ret; +} + +static void alpha_pll_pongo_elu_disable(struct clk_hw *hw) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + struct regmap *regmap = pll->clkr.regmap; + int ret; + + /* Disable the global PLL output */ + ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); + if (ret) + return; + + /* Place the PLL mode in STANDBY */ + regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); +} + +static unsigned long alpha_pll_pongo_elu_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + struct regmap *regmap = pll->clkr.regmap; + u32 l; + + if (regmap_read(regmap, PLL_L_VAL(pll), &l)) + return 0; + + l &= PONGO_PLL_L_VAL_MASK; + + return alpha_pll_calc_rate(parent_rate, l, 0, pll_alpha_width(pll)); +} + +const struct clk_ops clk_alpha_pll_pongo_elu_ops = { + .prepare = alpha_pll_pongo_elu_prepare, + .enable = alpha_pll_pongo_elu_enable, + .disable = alpha_pll_pongo_elu_disable, + .recalc_rate = alpha_pll_pongo_elu_recalc_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_pongo_elu_ops); + +void clk_pongo_elu_pll_configure(struct clk_alpha_pll *pll, + struct regmap *regmap, + const struct alpha_pll_config *config) +{ + u32 val; + + regmap_update_bits(regmap, PLL_USER_CTL(pll), PONGO_PLL_OUT_MASK, + PONGO_PLL_OUT_MASK); + + if (trion_pll_is_enabled(pll, regmap)) + return; + + if (regmap_read(regmap, PLL_L_VAL(pll), &val)) + return; + val &= PONGO_PLL_L_VAL_MASK; + if (val) + return; + + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); + 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); + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val); + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val); + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U2(pll), config->config_ctl_hi2_val); + clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), + config->user_ctl_val | PONGO_PLL_OUT_MASK); + clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val); + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val); + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val); + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val); + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U2(pll), config->test_ctl_hi2_val); + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U3(pll), config->test_ctl_hi3_val); + + /* Disable PLL output */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); +} +EXPORT_SYMBOL_GPL(clk_pongo_elu_pll_configure); + void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config) { diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 87bd469d9c2c2..79aca85252622 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -27,6 +27,7 @@ enum { CLK_ALPHA_PLL_TYPE_ZONDA_OLE, CLK_ALPHA_PLL_TYPE_LUCID_EVO, CLK_ALPHA_PLL_TYPE_LUCID_OLE, + CLK_ALPHA_PLL_TYPE_PONGO_ELU, CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, CLK_ALPHA_PLL_TYPE_DEFAULT_EVO, @@ -53,6 +54,7 @@ enum { PLL_OFF_TEST_CTL_U, PLL_OFF_TEST_CTL_U1, PLL_OFF_TEST_CTL_U2, + PLL_OFF_TEST_CTL_U3, PLL_OFF_STATE, PLL_OFF_STATUS, PLL_OFF_OPMODE, @@ -138,6 +140,7 @@ struct alpha_pll_config { u32 test_ctl_hi_mask; u32 test_ctl_hi1_val; u32 test_ctl_hi2_val; + u32 test_ctl_hi3_val; u32 main_output_mask; u32 aux_output_mask; u32 aux2_output_mask; @@ -196,6 +199,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; #define clk_alpha_pll_postdiv_lucid_ole_ops clk_alpha_pll_postdiv_lucid_evo_ops #define clk_alpha_pll_postdiv_taycan_elu_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 @@ -222,6 +226,8 @@ void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regma const struct alpha_pll_config *config); void clk_lucid_ole_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); +void clk_pongo_elu_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config); #define clk_taycan_elu_pll_configure(pll, regmap, config) \ clk_lucid_evo_pll_configure(pll, regmap, config) From f1080d8dab0f1f83c47850a71c32833c768e3666 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 6 Jan 2025 14:44:31 +0100 Subject: [PATCH 51/81] clk: qcom: dispcc-sm8750: Add SM8750 Display clock controller Add driver for Display clock controller (DISPCC) in Qualcomm SM8750. The device has several differences against SM8650, including new Pongo PLLs and different clock parents, thus no compatibility or driver re-usage. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250106-sm8750-dispcc-v2-3-6f42beda6317@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 11 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/dispcc-sm8750.c | 1963 ++++++++++++++++++++++++++++++ 3 files changed, 1975 insertions(+) create mode 100644 drivers/clk/qcom/dispcc-sm8750.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 199e88d3d66eb..42c257e4c433f 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1040,6 +1040,17 @@ config SM_DISPCC_8550 Say Y if you want to support display devices and functionality such as splash screen. +config SM_DISPCC_8750 + tristate "SM8750 Display Clock Controller" + depends on ARM64 || COMPILE_TEST + depends on SM_GCC_8750 + select QCOM_GDSC + help + Support for the display clock controller on Qualcomm Technologies, Inc + SM8750 devices. + Say Y if you want to support display devices and functionality such as + splash screen. + config SM_GCC_4450 tristate "SM4450 Global Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index cd103a9996a79..1b749da9c13a6 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -133,6 +133,7 @@ obj-$(CONFIG_SM_DISPCC_7150) += dispcc-sm7150.o obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o obj-$(CONFIG_SM_DISPCC_8450) += dispcc-sm8450.o obj-$(CONFIG_SM_DISPCC_8550) += dispcc-sm8550.o +obj-$(CONFIG_SM_DISPCC_8750) += dispcc-sm8750.o obj-$(CONFIG_SM_GCC_4450) += gcc-sm4450.o obj-$(CONFIG_SM_GCC_6115) += gcc-sm6115.o obj-$(CONFIG_SM_GCC_6125) += gcc-sm6125.o diff --git a/drivers/clk/qcom/dispcc-sm8750.c b/drivers/clk/qcom/dispcc-sm8750.c new file mode 100644 index 0000000000000..0358dff91da5d --- /dev/null +++ b/drivers/clk/qcom/dispcc-sm8750.c @@ -0,0 +1,1963 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023-2024, Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#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 "reset.h" +#include "gdsc.h" + +/* Need to match the order of clocks in DT binding */ +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_AHB_CLK, + DT_SLEEP_CLK, + + DT_DSI0_PHY_PLL_OUT_BYTECLK, + DT_DSI0_PHY_PLL_OUT_DSICLK, + DT_DSI1_PHY_PLL_OUT_BYTECLK, + DT_DSI1_PHY_PLL_OUT_DSICLK, + + DT_DP0_PHY_PLL_LINK_CLK, + DT_DP0_PHY_PLL_VCO_DIV_CLK, + DT_DP1_PHY_PLL_LINK_CLK, + DT_DP1_PHY_PLL_VCO_DIV_CLK, + DT_DP2_PHY_PLL_LINK_CLK, + DT_DP2_PHY_PLL_VCO_DIV_CLK, + DT_DP3_PHY_PLL_LINK_CLK, + DT_DP3_PHY_PLL_VCO_DIV_CLK, +}; + +#define DISP_CC_MISC_CMD 0xF000 + +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, + P_SLEEP_CLK, +}; + +static const struct pll_vco pongo_elu_vco[] = { + { 38400000, 38400000, 0 }, +}; + +static const struct pll_vco taycan_elu_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +static struct alpha_pll_config disp_cc_pll0_config = { + .l = 0xd, + .alpha = 0x6492, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll disp_cc_pll0 = { + .offset = 0x0, + .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 = "disp_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_elu_ops, + }, + }, +}; + +static struct alpha_pll_config disp_cc_pll1_config = { + .l = 0x1f, + .alpha = 0x4000, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll disp_cc_pll1 = { + .offset = 0x1000, + .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 = "disp_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 alpha_pll_config disp_cc_pll2_config = { + .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 = 0x00008000, + .test_ctl_hi_val = 0x0080c496, + .test_ctl_hi1_val = 0x40100180, + .test_ctl_hi2_val = 0x441001bc, + .test_ctl_hi3_val = 0x002003d8, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00e50302, +}; + +static struct clk_alpha_pll disp_cc_pll2 = { + .offset = 0x2000, + .vco_table = pongo_elu_vco, + .num_vco = ARRAY_SIZE(pongo_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_PONGO_ELU], + .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_elu_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 clk_parent_data disp_cc_parent_data_0_ao[] = { + { .index = DT_BI_TCXO_AO }, +}; + +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 parent_map disp_cc_parent_map_11[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_11[] = { + { .index = DT_SLEEP_CLK }, +}; + +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 = 0x80c0, + .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_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_esync1_clk_src = { + .cmd_rcgr = 0x80d8, + .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_byte2_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0), + F(75000000, P_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { + .cmd_rcgr = 0x8360, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_7, + .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, + .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 = 0x8180, + .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, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = { + .cmd_rcgr = 0x819c, + .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, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_aux_clk_src = { + .cmd_rcgr = 0x8234, + .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 = 0x81e8, + .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 = 0x8204, + .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 = 0x821c, + .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 = 0x8298, + .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_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_link_clk_src = { + .cmd_rcgr = 0x827c, + .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 = 0x824c, + .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 = 0x8264, + .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 = 0x82fc, + .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_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_link_clk_src = { + .cmd_rcgr = 0x82b0, + .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 = 0x82cc, + .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 = 0x82e4, + .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 = 0x8348, + .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_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_link_clk_src = { + .cmd_rcgr = 0x832c, + .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 = 0x8314, + .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 = 0x81b8, + .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 = 0x81d0, + .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(575000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { + .cmd_rcgr = 0x8150, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_9, + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, + .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, + /* + * TODO: Downstream does not manage the clock directly, but + * places votes via new hardware block called "cesta". + * It is not clear whether such approach should be taken instead + * of manual control. + */ + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { + .cmd_rcgr = 0x8108, + .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, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { + .cmd_rcgr = 0x8120, + .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, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk2_clk_src = { + .cmd_rcgr = 0x8138, + .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 = 0x8168, + .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_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 = 0x80f0, + .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_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_sleep_clk_src = { + .cmd_rcgr = 0xe064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_11, + .freq_tbl = ftbl_disp_cc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_sleep_clk_src", + .parent_data = disp_cc_parent_data_11, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_11), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_xo_clk_src = { + .cmd_rcgr = 0xe044, + .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_xo_clk_src", + .parent_data = disp_cc_parent_data_0_ao, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0_ao), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { + .reg = 0x8198, + .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 = 0x81b4, + .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 = 0x8200, + .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 = 0x8294, + .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 = 0x82c8, + .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 = 0x8344, + .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 = 0x80b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b8, + .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 = 0x80bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80bc, + .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", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .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 = 0x80b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b0, + .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_byte0_clk = { + .halt_reg = 0x8034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "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 = 0x8038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8038, + .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 = 0x803c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x803c, + .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 = 0x8040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8040, + .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 = 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_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 = 0x8058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8058, + .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 = 0x804c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x804c, + .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 = 0x8054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8054, + .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 = 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_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 = 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_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 = 0x8050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8050, + .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 = 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_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 = 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_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 = 0x8070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8070, + .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 = 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_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 = 0x8068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8068, + .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 = 0x806c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x806c, + .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 = 0x8074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8074, + .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 = 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_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 = 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_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 = 0x808c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x808c, + .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 = 0x8090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8090, + .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 = 0x8084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8084, + .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 = 0x8088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8088, + .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 = 0x80a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a8, + .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 = 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_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 = 0x80a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a0, + .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 = 0x80a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a4, + .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 = 0x809c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x809c, + .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 = 0x8044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8044, + .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 = 0x8048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8048, + .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, + .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, + .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_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 = 0x8030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8030, + .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 = 0x80b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b4, + .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 mdss_gdsc = { + .gdscr = 0x9000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "mdss_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE, +}; + +static struct gdsc mdss_int2_gdsc = { + .gdscr = 0xb000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "mdss_int2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *disp_cc_sm8750_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_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_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, + [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr, + [DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr, +}; + +static const struct qcom_reset_map disp_cc_sm8750_resets[] = { + [DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, + [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, + [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, +}; + +static struct gdsc *disp_cc_sm8750_gdscs[] = { + [MDSS_GDSC] = &mdss_gdsc, + [MDSS_INT2_GDSC] = &mdss_int2_gdsc, +}; + +static const struct regmap_config disp_cc_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x11014, + .fast_io = true, +}; + +static struct qcom_cc_desc disp_cc_sm8750_desc = { + .config = &disp_cc_sm8750_regmap_config, + .clks = disp_cc_sm8750_clocks, + .num_clks = ARRAY_SIZE(disp_cc_sm8750_clocks), + .resets = disp_cc_sm8750_resets, + .num_resets = ARRAY_SIZE(disp_cc_sm8750_resets), + .gdscs = disp_cc_sm8750_gdscs, + .num_gdscs = ARRAY_SIZE(disp_cc_sm8750_gdscs), +}; + +static const struct of_device_id disp_cc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-dispcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, disp_cc_sm8750_match_table); + +static int disp_cc_sm8750_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; + + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return ret; + + regmap = qcom_cc_map(pdev, &disp_cc_sm8750_desc); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + goto err_put_rpm; + } + + clk_taycan_elu_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); + clk_taycan_elu_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config); + clk_pongo_elu_pll_configure(&disp_cc_pll2, regmap, &disp_cc_pll2_config); + + /* Enable clock gating for MDP clocks */ + regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10); + + /* Keep some clocks always-on */ + qcom_branch_set_clk_en(regmap, 0xe07c); /* DISP_CC_SLEEP_CLK */ + qcom_branch_set_clk_en(regmap, 0xe05c); /* DISP_CC_XO_CLK */ + qcom_branch_set_clk_en(regmap, 0xc00c); /* DISP_CC_MDSS_RSCC_AHB_CLK */ + qcom_branch_set_clk_en(regmap, 0xc008); /* DISP_CC_MDSS_RSCC_VSYNC_CLK */ + + ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8750_desc, regmap); + if (ret) + goto err_put_rpm; + + pm_runtime_put(&pdev->dev); + + return 0; + +err_put_rpm: + pm_runtime_put_sync(&pdev->dev); + + return ret; +} + +static struct platform_driver disp_cc_sm8750_driver = { + .probe = disp_cc_sm8750_probe, + .driver = { + .name = "disp_cc-sm8750", + .of_match_table = disp_cc_sm8750_match_table, + }, +}; + +module_platform_driver(disp_cc_sm8750_driver); + +MODULE_DESCRIPTION("QTI DISPCC SM8750 Driver"); +MODULE_LICENSE("GPL"); From c0f1cbf795095c21b92a46fa1dc47a7b787ce538 Mon Sep 17 00:00:00 2001 From: Luo Jie Date: Fri, 3 Jan 2025 15:31:34 +0800 Subject: [PATCH 52/81] dt-bindings: clock: qcom: Add CMN PLL clock controller for IPQ SoC The CMN PLL controller provides clocks to networking hardware blocks and to GCC on Qualcomm IPQ9574 SoC. It receives input clock from the on-chip Wi-Fi, and produces output clocks at fixed rates. These output rates are predetermined, and are unrelated to the input clock rate. The primary purpose of CMN PLL is to supply clocks to the networking hardware such as PPE (packet process engine), PCS and the externally connected switch or PHY device. The CMN PLL block also outputs fixed rate clocks to GCC, such as 24 MHZ as XO clock and 32 KHZ as sleep clock supplied to GCC. Signed-off-by: Luo Jie Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250103-qcom_ipq_cmnpll-v8-1-c89fb4d4849d@quicinc.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,ipq9574-cmn-pll.yaml | 77 +++++++++++++++++++ include/dt-bindings/clock/qcom,ipq-cmn-pll.h | 22 ++++++ 2 files changed, 99 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml create mode 100644 include/dt-bindings/clock/qcom,ipq-cmn-pll.h diff --git a/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml new file mode 100644 index 0000000000000..f869b3739be85 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,ipq9574-cmn-pll.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm CMN PLL Clock Controller on IPQ SoC + +maintainers: + - Bjorn Andersson + - Luo Jie + +description: + The CMN (or common) PLL clock controller expects a reference + input clock. This reference clock is from the on-board Wi-Fi. + The CMN PLL supplies a number of fixed rate output clocks to + the devices providing networking functions and to GCC. These + networking hardware include PPE (packet process engine), PCS + and the externally connected switch or PHY devices. The CMN + PLL block also outputs fixed rate clocks to GCC. The PLL's + primary function is to enable fixed rate output clocks for + networking hardware functions used with the IPQ SoC. + +properties: + compatible: + enum: + - qcom,ipq9574-cmn-pll + + reg: + maxItems: 1 + + clocks: + items: + - description: The reference clock. The supported clock rates include + 25000000, 31250000, 40000000, 48000000, 50000000 and 96000000 HZ. + - description: The AHB clock + - description: The SYS clock + description: + The reference clock is the source clock of CMN PLL, which is from the + Wi-Fi. The AHB and SYS clocks must be enabled to access CMN PLL + clock registers. + + clock-names: + items: + - const: ref + - const: ahb + - const: sys + + "#clock-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - "#clock-cells" + +additionalProperties: false + +examples: + - | + #include + #include + + cmn_pll: clock-controller@9b000 { + compatible = "qcom,ipq9574-cmn-pll"; + reg = <0x0009b000 0x800>; + clocks = <&cmn_pll_ref_clk>, + <&gcc GCC_CMN_12GPLL_AHB_CLK>, + <&gcc GCC_CMN_12GPLL_SYS_CLK>; + clock-names = "ref", "ahb", "sys"; + #clock-cells = <1>; + assigned-clocks = <&cmn_pll CMN_PLL_CLK>; + assigned-clock-rates-u64 = /bits/ 64 <12000000000>; + }; +... diff --git a/include/dt-bindings/clock/qcom,ipq-cmn-pll.h b/include/dt-bindings/clock/qcom,ipq-cmn-pll.h new file mode 100644 index 0000000000000..936e92b3b62c0 --- /dev/null +++ b/include/dt-bindings/clock/qcom,ipq-cmn-pll.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_IPQ_CMN_PLL_H +#define _DT_BINDINGS_CLK_QCOM_IPQ_CMN_PLL_H + +/* CMN PLL core clock. */ +#define CMN_PLL_CLK 0 + +/* The output clocks from CMN PLL of IPQ9574. */ +#define XO_24MHZ_CLK 1 +#define SLEEP_32KHZ_CLK 2 +#define PCS_31P25MHZ_CLK 3 +#define NSS_1200MHZ_CLK 4 +#define PPE_353MHZ_CLK 5 +#define ETH0_50MHZ_CLK 6 +#define ETH1_50MHZ_CLK 7 +#define ETH2_50MHZ_CLK 8 +#define ETH_25MHZ_CLK 9 +#endif From f81715a4c87c3b75ca2640bb61b6c66506061a64 Mon Sep 17 00:00:00 2001 From: Luo Jie Date: Fri, 3 Jan 2025 15:31:35 +0800 Subject: [PATCH 53/81] clk: qcom: Add CMN PLL clock controller driver for IPQ SoC The CMN PLL clock controller supplies clocks to the hardware blocks that together make up the Ethernet function on Qualcomm IPQ SoCs and to GCC. The driver is initially supported for IPQ9574 SoC. The CMN PLL clock controller expects a reference input clock from the on-board Wi-Fi block acting as clock source. The input reference clock needs to be configured to one of the supported clock rates. The controller supplies a number of fixed-rate output clocks. For the IPQ9574, there is one output clock of 353 MHZ to PPE (Packet Process Engine) hardware block, three 50 MHZ output clocks and an additional 25 MHZ output clock supplied to the connected Ethernet devices. The PLL also supplies a 24 MHZ clock as XO and a 32 KHZ sleep clock to GCC, and one 31.25 MHZ clock to PCS. Signed-off-by: Luo Jie Acked-by: Konrad Dybcio Link: https://lore.kernel.org/r/20250103-qcom_ipq_cmnpll-v8-2-c89fb4d4849d@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/ipq-cmn-pll.c | 435 +++++++++++++++++++++++++++++++++ 3 files changed, 445 insertions(+) create mode 100644 drivers/clk/qcom/ipq-cmn-pll.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 42c257e4c433f..2daff198aeb3f 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -199,6 +199,15 @@ config IPQ_APSS_6018 Say Y if you want to support CPU frequency scaling on ipq based devices. +config IPQ_CMN_PLL + tristate "IPQ CMN PLL Clock Controller" + help + Support for CMN PLL clock controller on IPQ platform. The + CMN PLL consumes the AHB/SYS clocks from GCC and supplies + the output clocks to the networking hardware and GCC blocks. + Say Y or M if you want to support CMN PLL clock on the IPQ + based devices. + config IPQ_GCC_4019 tristate "IPQ4019 Global Clock Controller" help diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 1b749da9c13a6..6665049cb8c89 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_CLK_X1P42100_GPUCC) += gpucc-x1p42100.o obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o +obj-$(CONFIG_IPQ_CMN_PLL) += ipq-cmn-pll.o obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o obj-$(CONFIG_IPQ_GCC_5018) += gcc-ipq5018.o obj-$(CONFIG_IPQ_GCC_5332) += gcc-ipq5332.o diff --git a/drivers/clk/qcom/ipq-cmn-pll.c b/drivers/clk/qcom/ipq-cmn-pll.c new file mode 100644 index 0000000000000..432d4c4b7aa6a --- /dev/null +++ b/drivers/clk/qcom/ipq-cmn-pll.c @@ -0,0 +1,435 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +/* + * CMN PLL block expects the reference clock from on-board Wi-Fi block, + * and supplies fixed rate clocks as output to the networking hardware + * blocks and to GCC. The networking related blocks include PPE (packet + * process engine), the externally connected PHY or switch devices, and + * the PCS. + * + * On the IPQ9574 SoC, there are three clocks with 50 MHZ and one clock + * with 25 MHZ which are output from the CMN PLL to Ethernet PHY (or switch), + * and one clock with 353 MHZ to PPE. The other fixed rate output clocks + * are supplied to GCC (24 MHZ as XO and 32 KHZ as sleep clock), and to PCS + * with 31.25 MHZ. + * + * +---------+ + * | GCC | + * +--+---+--+ + * AHB CLK| |SYS CLK + * V V + * +-------+---+------+ + * | +-------------> eth0-50mhz + * REF CLK | IPQ9574 | + * -------->+ +-------------> eth1-50mhz + * | CMN PLL block | + * | +-------------> eth2-50mhz + * | | + * +----+----+----+---+-------------> eth-25mhz + * | | | + * V V V + * GCC PCS NSS/PPE + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define CMN_PLL_REFCLK_SRC_SELECTION 0x28 +#define CMN_PLL_REFCLK_SRC_DIV GENMASK(9, 8) + +#define CMN_PLL_LOCKED 0x64 +#define CMN_PLL_CLKS_LOCKED BIT(8) + +#define CMN_PLL_POWER_ON_AND_RESET 0x780 +#define CMN_ANA_EN_SW_RSTN BIT(6) + +#define CMN_PLL_REFCLK_CONFIG 0x784 +#define CMN_PLL_REFCLK_EXTERNAL BIT(9) +#define CMN_PLL_REFCLK_DIV GENMASK(8, 4) +#define CMN_PLL_REFCLK_INDEX GENMASK(3, 0) + +#define CMN_PLL_CTRL 0x78c +#define CMN_PLL_CTRL_LOCK_DETECT_EN BIT(15) + +#define CMN_PLL_DIVIDER_CTRL 0x794 +#define CMN_PLL_DIVIDER_CTRL_FACTOR GENMASK(9, 0) + +/** + * struct cmn_pll_fixed_output_clk - CMN PLL output clocks information + * @id: Clock specifier to be supplied + * @name: Clock name to be registered + * @rate: Clock rate + */ +struct cmn_pll_fixed_output_clk { + unsigned int id; + const char *name; + unsigned long rate; +}; + +/** + * struct clk_cmn_pll - CMN PLL hardware specific data + * @regmap: hardware regmap. + * @hw: handle between common and hardware-specific interfaces + */ +struct clk_cmn_pll { + struct regmap *regmap; + struct clk_hw hw; +}; + +#define CLK_PLL_OUTPUT(_id, _name, _rate) { \ + .id = _id, \ + .name = _name, \ + .rate = _rate, \ +} + +#define to_clk_cmn_pll(_hw) container_of(_hw, struct clk_cmn_pll, hw) + +static const struct regmap_config ipq_cmn_pll_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x7fc, + .fast_io = true, +}; + +static const struct cmn_pll_fixed_output_clk ipq9574_output_clks[] = { + CLK_PLL_OUTPUT(XO_24MHZ_CLK, "xo-24mhz", 24000000UL), + CLK_PLL_OUTPUT(SLEEP_32KHZ_CLK, "sleep-32khz", 32000UL), + CLK_PLL_OUTPUT(PCS_31P25MHZ_CLK, "pcs-31p25mhz", 31250000UL), + CLK_PLL_OUTPUT(NSS_1200MHZ_CLK, "nss-1200mhz", 1200000000UL), + CLK_PLL_OUTPUT(PPE_353MHZ_CLK, "ppe-353mhz", 353000000UL), + CLK_PLL_OUTPUT(ETH0_50MHZ_CLK, "eth0-50mhz", 50000000UL), + CLK_PLL_OUTPUT(ETH1_50MHZ_CLK, "eth1-50mhz", 50000000UL), + CLK_PLL_OUTPUT(ETH2_50MHZ_CLK, "eth2-50mhz", 50000000UL), + CLK_PLL_OUTPUT(ETH_25MHZ_CLK, "eth-25mhz", 25000000UL), +}; + +/* + * CMN PLL has the single parent clock, which supports the several + * possible parent clock rates, each parent clock rate is reflected + * by the specific reference index value in the hardware. + */ +static int ipq_cmn_pll_find_freq_index(unsigned long parent_rate) +{ + int index = -EINVAL; + + switch (parent_rate) { + case 25000000: + index = 3; + break; + case 31250000: + index = 4; + break; + case 40000000: + index = 6; + break; + case 48000000: + case 96000000: + /* + * Parent clock rate 48 MHZ and 96 MHZ take the same value + * of reference clock index. 96 MHZ needs the source clock + * divider to be programmed as 2. + */ + index = 7; + break; + case 50000000: + index = 8; + break; + default: + break; + } + + return index; +} + +static unsigned long clk_cmn_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw); + u32 val, factor; + + /* + * The value of CMN_PLL_DIVIDER_CTRL_FACTOR is automatically adjusted + * by HW according to the parent clock rate. + */ + regmap_read(cmn_pll->regmap, CMN_PLL_DIVIDER_CTRL, &val); + factor = FIELD_GET(CMN_PLL_DIVIDER_CTRL_FACTOR, val); + + return parent_rate * 2 * factor; +} + +static int clk_cmn_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + int ret; + + /* Validate the rate of the single parent clock. */ + ret = ipq_cmn_pll_find_freq_index(req->best_parent_rate); + + return ret < 0 ? ret : 0; +} + +/* + * This function is used to initialize the CMN PLL to enable the fixed + * rate output clocks. It is expected to be configured once. + */ +static int clk_cmn_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw); + int ret, index; + u32 val; + + /* + * Configure the reference input clock selection as per the given + * parent clock. The output clock rates are always of fixed value. + */ + index = ipq_cmn_pll_find_freq_index(parent_rate); + if (index < 0) + return index; + + ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG, + CMN_PLL_REFCLK_INDEX, + FIELD_PREP(CMN_PLL_REFCLK_INDEX, index)); + if (ret) + return ret; + + /* + * Update the source clock rate selection and source clock + * divider as 2 when the parent clock rate is 96 MHZ. + */ + if (parent_rate == 96000000) { + ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG, + CMN_PLL_REFCLK_DIV, + FIELD_PREP(CMN_PLL_REFCLK_DIV, 2)); + if (ret) + return ret; + + ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_SRC_SELECTION, + CMN_PLL_REFCLK_SRC_DIV, + FIELD_PREP(CMN_PLL_REFCLK_SRC_DIV, 0)); + if (ret) + return ret; + } + + /* Enable PLL locked detect. */ + ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_CTRL, + CMN_PLL_CTRL_LOCK_DETECT_EN); + if (ret) + return ret; + + /* + * Reset the CMN PLL block to ensure the updated configurations + * take effect. + */ + ret = regmap_clear_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET, + CMN_ANA_EN_SW_RSTN); + if (ret) + return ret; + + usleep_range(1000, 1200); + ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET, + CMN_ANA_EN_SW_RSTN); + if (ret) + return ret; + + /* Stability check of CMN PLL output clocks. */ + return regmap_read_poll_timeout(cmn_pll->regmap, CMN_PLL_LOCKED, val, + (val & CMN_PLL_CLKS_LOCKED), + 100, 100 * USEC_PER_MSEC); +} + +static const struct clk_ops clk_cmn_pll_ops = { + .recalc_rate = clk_cmn_pll_recalc_rate, + .determine_rate = clk_cmn_pll_determine_rate, + .set_rate = clk_cmn_pll_set_rate, +}; + +static struct clk_hw *ipq_cmn_pll_clk_hw_register(struct platform_device *pdev) +{ + struct clk_parent_data pdata = { .index = 0 }; + struct device *dev = &pdev->dev; + struct clk_init_data init = {}; + struct clk_cmn_pll *cmn_pll; + struct regmap *regmap; + void __iomem *base; + int ret; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return ERR_CAST(base); + + regmap = devm_regmap_init_mmio(dev, base, &ipq_cmn_pll_regmap_config); + if (IS_ERR(regmap)) + return ERR_CAST(regmap); + + cmn_pll = devm_kzalloc(dev, sizeof(*cmn_pll), GFP_KERNEL); + if (!cmn_pll) + return ERR_PTR(-ENOMEM); + + init.name = "cmn_pll"; + init.parent_data = &pdata; + init.num_parents = 1; + init.ops = &clk_cmn_pll_ops; + + cmn_pll->hw.init = &init; + cmn_pll->regmap = regmap; + + ret = devm_clk_hw_register(dev, &cmn_pll->hw); + if (ret) + return ERR_PTR(ret); + + return &cmn_pll->hw; +} + +static int ipq_cmn_pll_register_clks(struct platform_device *pdev) +{ + const struct cmn_pll_fixed_output_clk *fixed_clk; + struct clk_hw_onecell_data *hw_data; + struct device *dev = &pdev->dev; + struct clk_hw *cmn_pll_hw; + unsigned int num_clks; + struct clk_hw *hw; + int ret, i; + + fixed_clk = ipq9574_output_clks; + num_clks = ARRAY_SIZE(ipq9574_output_clks); + + hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks + 1), + GFP_KERNEL); + if (!hw_data) + return -ENOMEM; + + /* + * Register the CMN PLL clock, which is the parent clock of + * the fixed rate output clocks. + */ + cmn_pll_hw = ipq_cmn_pll_clk_hw_register(pdev); + if (IS_ERR(cmn_pll_hw)) + return PTR_ERR(cmn_pll_hw); + + /* Register the fixed rate output clocks. */ + for (i = 0; i < num_clks; i++) { + hw = clk_hw_register_fixed_rate_parent_hw(dev, fixed_clk[i].name, + cmn_pll_hw, 0, + fixed_clk[i].rate); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto unregister_fixed_clk; + } + + hw_data->hws[fixed_clk[i].id] = hw; + } + + /* + * Provide the CMN PLL clock. The clock rate of CMN PLL + * is configured to 12 GHZ by DT property assigned-clock-rates-u64. + */ + hw_data->hws[CMN_PLL_CLK] = cmn_pll_hw; + hw_data->num = num_clks + 1; + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data); + if (ret) + goto unregister_fixed_clk; + + platform_set_drvdata(pdev, hw_data); + + return 0; + +unregister_fixed_clk: + while (i > 0) + clk_hw_unregister(hw_data->hws[fixed_clk[--i].id]); + + return ret; +} + +static int ipq_cmn_pll_clk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int ret; + + ret = devm_pm_runtime_enable(dev); + if (ret) + return ret; + + ret = devm_pm_clk_create(dev); + if (ret) + return ret; + + /* + * To access the CMN PLL registers, the GCC AHB & SYS clocks + * of CMN PLL block need to be enabled. + */ + ret = pm_clk_add(dev, "ahb"); + if (ret) + return dev_err_probe(dev, ret, "Fail to add AHB clock\n"); + + ret = pm_clk_add(dev, "sys"); + if (ret) + return dev_err_probe(dev, ret, "Fail to add SYS clock\n"); + + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; + + /* Register CMN PLL clock and fixed rate output clocks. */ + ret = ipq_cmn_pll_register_clks(pdev); + pm_runtime_put(dev); + if (ret) + return dev_err_probe(dev, ret, + "Fail to register CMN PLL clocks\n"); + + return 0; +} + +static void ipq_cmn_pll_clk_remove(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *hw_data = platform_get_drvdata(pdev); + int i; + + /* + * The clock with index CMN_PLL_CLK is unregistered by + * device management. + */ + for (i = 0; i < hw_data->num; i++) { + if (i != CMN_PLL_CLK) + clk_hw_unregister(hw_data->hws[i]); + } +} + +static const struct dev_pm_ops ipq_cmn_pll_pm_ops = { + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) +}; + +static const struct of_device_id ipq_cmn_pll_clk_ids[] = { + { .compatible = "qcom,ipq9574-cmn-pll", }, + { } +}; +MODULE_DEVICE_TABLE(of, ipq_cmn_pll_clk_ids); + +static struct platform_driver ipq_cmn_pll_clk_driver = { + .probe = ipq_cmn_pll_clk_probe, + .remove = ipq_cmn_pll_clk_remove, + .driver = { + .name = "ipq_cmn_pll", + .of_match_table = ipq_cmn_pll_clk_ids, + .pm = &ipq_cmn_pll_pm_ops, + }, +}; +module_platform_driver(ipq_cmn_pll_clk_driver); + +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPQ CMN PLL Driver"); +MODULE_LICENSE("GPL"); From 2b5add606ceac9fe4ea84ecd34351427b5602893 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 24 Dec 2024 12:12:13 +0200 Subject: [PATCH 54/81] dt-bindings: clock: qcom,mmcc: support LVDS PLL input for apq8064 APQ8064 / MSM8960 have separate LVDS PLL driving the LVDS / LCDC clock. Add corresponding input to clock controller bindings. Signed-off-by: Dmitry Baryshkov Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20241224-apq8064-fix-mmcc-v1-1-c95d2e2bf143@linaro.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/clock/qcom,mmcc.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml b/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml index aa35a40648ba8..59ac288ca5f12 100644 --- a/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml @@ -78,6 +78,7 @@ allOf: then: properties: clocks: + minItems: 8 items: - description: Board PXO source - description: PLL 3 clock @@ -87,8 +88,10 @@ allOf: - description: DSI phy instance 2 dsi clock - description: DSI phy instance 2 byte clock - description: HDMI phy PLL clock + - description: LVDS PLL clock clock-names: + minItems: 8 items: - const: pxo - const: pll3 @@ -98,6 +101,7 @@ allOf: - const: dsi2pll - const: dsi2pllbyte - const: hdmipll + - const: lvdspll - if: properties: From 0a0693fb2642604b4e14390dbf792f36e3485aaa Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 24 Dec 2024 12:12:14 +0200 Subject: [PATCH 55/81] dt-bindings: clock: qcom,mmcc-msm8960: add LCDC-related clocks APQ8064 / MSM8960 have separate LVDS / LCDC clock, driving the MDP4 LCD controller. Add corresponding indices to clock controller bindings. Signed-off-by: Dmitry Baryshkov Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20241224-apq8064-fix-mmcc-v1-2-c95d2e2bf143@linaro.org Signed-off-by: Bjorn Andersson --- include/dt-bindings/clock/qcom,mmcc-msm8960.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dt-bindings/clock/qcom,mmcc-msm8960.h b/include/dt-bindings/clock/qcom,mmcc-msm8960.h index 81714fc859c50..717431d735c18 100644 --- a/include/dt-bindings/clock/qcom,mmcc-msm8960.h +++ b/include/dt-bindings/clock/qcom,mmcc-msm8960.h @@ -133,5 +133,7 @@ #define VCAP_CLK 124 #define VCAP_NPL_CLK 125 #define PLL15 126 +#define DSI2_PIXEL_LVDS_SRC 127 +#define LVDS_CLK 128 #endif From a34d21d89c85e8bb72ecd83b7cde2cba1aa718f4 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 24 Dec 2024 12:12:15 +0200 Subject: [PATCH 56/81] clk: qcom: rcg: add 1/1 pixel clock ratio LVDS clocks require 1:1 ration support in the table used by clk_rcg_pixel_ops. Add corresponding divider to the table. Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20241224-apq8064-fix-mmcc-v1-3-c95d2e2bf143@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rcg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c index 88845baa7f842..987141c91fe0b 100644 --- a/drivers/clk/qcom/clk-rcg.c +++ b/drivers/clk/qcom/clk-rcg.c @@ -597,6 +597,7 @@ struct frac_entry { }; static const struct frac_entry pixel_table[] = { + { 1, 1 }, { 1, 2 }, { 1, 3 }, { 3, 16 }, From 672daf24866bf002d0a7f2dca61e770a570e8cc3 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 24 Dec 2024 12:12:16 +0200 Subject: [PATCH 57/81] clk: qcom: mmcc-msm8960: handle LVDS clock On APQ8064 the DSI2_PIXEL_SRC clock can be used either to drive the second DSI host or to drive the LCDC controller. Add LVDS PLL as possible source to the clock and LVDS output clock. The DSI2_PIXEL_SRC clock has separate path to be used for the LVDS clock. To represent both DSI and LVDS clocks properly, add intermediate clock which toggles the enable bit and make DSI2_PIXEL_CLK clock just check for the HALT bit. Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20241224-apq8064-fix-mmcc-v1-4-c95d2e2bf143@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/mmcc-msm8960.c | 61 ++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c index 3f41249c5ae43..20d1c43f35d99 100644 --- a/drivers/clk/qcom/mmcc-msm8960.c +++ b/drivers/clk/qcom/mmcc-msm8960.c @@ -37,6 +37,7 @@ enum { P_DSI2_PLL_DSICLK, P_DSI1_PLL_BYTECLK, P_DSI2_PLL_BYTECLK, + P_LVDS_PLL, }; #define F_MN(f, s, _m, _n) { .freq = f, .src = s, .m = _m, .n = _n } @@ -143,6 +144,20 @@ static const struct clk_parent_data mmcc_pxo_dsi2_dsi1[] = { { .fw_name = "dsi1pll", .name = "dsi1pll" }, }; +static const struct parent_map mmcc_pxo_dsi2_dsi1_lvds_map[] = { + { P_PXO, 0 }, + { P_DSI2_PLL_DSICLK, 1 }, + { P_LVDS_PLL, 2 }, + { P_DSI1_PLL_DSICLK, 3 }, +}; + +static const struct clk_parent_data mmcc_pxo_dsi2_dsi1_lvds[] = { + { .fw_name = "pxo", .name = "pxo_board" }, + { .fw_name = "dsi2pll", .name = "dsi2pll" }, + { .fw_name = "lvdspll", .name = "mpd4_lvds_pll" }, + { .fw_name = "dsi1pll", .name = "dsi1pll" }, +}; + static const struct parent_map mmcc_pxo_dsi1_dsi2_byte_map[] = { { P_PXO, 0 }, { P_DSI1_PLL_BYTECLK, 1 }, @@ -2439,26 +2454,42 @@ static struct clk_rcg dsi2_pixel_src = { }, .s = { .src_sel_shift = 0, - .parent_map = mmcc_pxo_dsi2_dsi1_map, + .parent_map = mmcc_pxo_dsi2_dsi1_lvds_map, }, .clkr = { .enable_reg = 0x0094, .enable_mask = BIT(2), .hw.init = &(struct clk_init_data){ .name = "dsi2_pixel_src", - .parent_data = mmcc_pxo_dsi2_dsi1, - .num_parents = ARRAY_SIZE(mmcc_pxo_dsi2_dsi1), + .parent_data = mmcc_pxo_dsi2_dsi1_lvds, + .num_parents = ARRAY_SIZE(mmcc_pxo_dsi2_dsi1_lvds), .ops = &clk_rcg_pixel_ops, }, }, }; +static struct clk_branch dsi2_pixel_lvds_src = { + .clkr = { + .enable_reg = 0x0094, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "dsi2_pixel_lvds_src", + .parent_hws = (const struct clk_hw*[]){ + &dsi2_pixel_src.clkr.hw + }, + .num_parents = 1, + .ops = &clk_branch_simple_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + static struct clk_branch dsi2_pixel_clk = { .halt_reg = 0x01d0, .halt_bit = 19, .clkr = { .enable_reg = 0x0094, - .enable_mask = BIT(0), + .enable_mask = 0, .hw.init = &(struct clk_init_data){ .name = "mdp_pclk2_clk", .parent_hws = (const struct clk_hw*[]){ @@ -2471,6 +2502,24 @@ static struct clk_branch dsi2_pixel_clk = { }, }; +static struct clk_branch lvds_clk = { + .halt_reg = 0x024c, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x0264, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "mdp_lvds_clk", + .parent_hws = (const struct clk_hw*[]){ + &dsi2_pixel_lvds_src.clkr.hw + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + static struct clk_branch gfx2d0_ahb_clk = { .hwcg_reg = 0x0038, .hwcg_bit = 28, @@ -2799,6 +2848,8 @@ static struct clk_regmap *mmcc_msm8960_clks[] = { [CSIPHY1_TIMER_CLK] = &csiphy1_timer_clk.clkr, [CSIPHY0_TIMER_CLK] = &csiphy0_timer_clk.clkr, [PLL2] = &pll2.clkr, + [DSI2_PIXEL_LVDS_SRC] = &dsi2_pixel_lvds_src.clkr, + [LVDS_CLK] = &lvds_clk.clkr, }; static const struct qcom_reset_map mmcc_msm8960_resets[] = { @@ -2983,6 +3034,8 @@ static struct clk_regmap *mmcc_apq8064_clks[] = { [VCAP_CLK] = &vcap_clk.clkr, [VCAP_NPL_CLK] = &vcap_npl_clk.clkr, [PLL15] = &pll15.clkr, + [DSI2_PIXEL_LVDS_SRC] = &dsi2_pixel_lvds_src.clkr, + [LVDS_CLK] = &lvds_clk.clkr, }; static const struct qcom_reset_map mmcc_apq8064_resets[] = { From bf6aa2d6935cc86b5eee67cdb8edef53fb6374cd Mon Sep 17 00:00:00 2001 From: Richard Acayan Date: Wed, 18 Dec 2024 18:17:31 -0500 Subject: [PATCH 58/81] dt-bindings: clock: qcom,sdm845-camcc: add sdm670 compatible The camera clocks on SDM670 and SDM845 have no significant differences that would require a change in the clock controller driver. The only difference is the clock frequency at each level of the power domains, which is not specified in the clock driver. There should still be a compatible specific to the SoC, so add the compatible for SDM670 with the SDM845 compatible as fallback. Link: https://android.googlesource.com/kernel/msm/+/d4dc50c0a9291bd99895d4844f973421c047d267/drivers/clk/qcom/camcc-sdm845.c#2048 Suggested-by: Vladimir Zapolskiy Suggested-by: Konrad Dybcio Link: https://lore.kernel.org/linux-arm-msm/7d26a62b-b898-4737-bd53-f49821e3b471@linaro.org Signed-off-by: Richard Acayan Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20241218231729.270137-8-mailingradian@gmail.com Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/clock/qcom,sdm845-camcc.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,sdm845-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sdm845-camcc.yaml index 810b852ae3719..fa95c3a1ba3aa 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sdm845-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sdm845-camcc.yaml @@ -20,7 +20,11 @@ allOf: properties: compatible: - const: qcom,sdm845-camcc + oneOf: + - items: + - const: qcom,sdm670-camcc + - const: qcom,sdm845-camcc + - const: qcom,sdm845-camcc clocks: items: From 5051b61d769ecc02b218499c35bee4cc1c38b7dc Mon Sep 17 00:00:00 2001 From: Manikanta Mylavarapu Date: Tue, 17 Dec 2024 17:09:08 +0530 Subject: [PATCH 59/81] clk: qcom: ipq5424: remove apss_dbg clock The gcc_apss_dbg clk is access protected by trust zone, and accessing it results in a kernel crash. Therefore remove the gcc_apss_dbg_clk from the gcc driver. Signed-off-by: Manikanta Mylavarapu Link: https://lore.kernel.org/r/20241217113909.3522305-2-quic_mmanikan@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-ipq5424.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c index 88a7d5b2e751a..5f42ac6c8cdc1 100644 --- a/drivers/clk/qcom/gcc-ipq5424.c +++ b/drivers/clk/qcom/gcc-ipq5424.c @@ -1097,24 +1097,6 @@ static struct clk_branch gcc_adss_pwm_clk = { }, }; -static struct clk_branch gcc_apss_dbg_clk = { - .halt_reg = 0x2402c, - .halt_check = BRANCH_HALT_VOTED, - .clkr = { - .enable_reg = 0x2402c, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "gcc_apss_dbg_clk", - .parent_hws = (const struct clk_hw*[]) { - &gcc_qdss_dap_sync_clk_src.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_cnoc_pcie0_1lane_s_clk = { .halt_reg = 0x31088, .halt_check = BRANCH_HALT, @@ -2785,7 +2767,6 @@ static struct clk_branch gcc_pcie3_rchng_clk = { static struct clk_regmap *gcc_ipq5424_clocks[] = { [GCC_ADSS_PWM_CLK] = &gcc_adss_pwm_clk.clkr, [GCC_ADSS_PWM_CLK_SRC] = &gcc_adss_pwm_clk_src.clkr, - [GCC_APSS_DBG_CLK] = &gcc_apss_dbg_clk.clkr, [GCC_CNOC_PCIE0_1LANE_S_CLK] = &gcc_cnoc_pcie0_1lane_s_clk.clkr, [GCC_CNOC_PCIE1_1LANE_S_CLK] = &gcc_cnoc_pcie1_1lane_s_clk.clkr, [GCC_CNOC_PCIE2_2LANE_S_CLK] = &gcc_cnoc_pcie2_2lane_s_clk.clkr, From 46e6075287e68e1d3d0ea8ecda610064636e0854 Mon Sep 17 00:00:00 2001 From: Manikanta Mylavarapu Date: Tue, 17 Dec 2024 17:09:09 +0530 Subject: [PATCH 60/81] dt-bindings: clock: qcom: gcc-ipq5424: remove apss_dbg clock macro The gcc_apss_dbg clk is access protected by trust zone, and accessing it results in a kernel crash. Therefore remove the gcc_apss_dbg_clk macro. Acked-by: Krzysztof Kozlowski Signed-off-by: Manikanta Mylavarapu Link: https://lore.kernel.org/r/20241217113909.3522305-3-quic_mmanikan@quicinc.com Signed-off-by: Bjorn Andersson --- include/dt-bindings/clock/qcom,ipq5424-gcc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/dt-bindings/clock/qcom,ipq5424-gcc.h b/include/dt-bindings/clock/qcom,ipq5424-gcc.h index 755ce7a71c7cd..9f14680052a0a 100644 --- a/include/dt-bindings/clock/qcom,ipq5424-gcc.h +++ b/include/dt-bindings/clock/qcom,ipq5424-gcc.h @@ -12,7 +12,6 @@ #define GPLL2 2 #define GPLL2_OUT_MAIN 3 #define GCC_SLEEP_CLK_SRC 4 -#define GCC_APSS_DBG_CLK 5 #define GCC_USB0_EUD_AT_CLK 6 #define GCC_PCIE0_AXI_M_CLK_SRC 7 #define GCC_PCIE0_AXI_M_CLK 8 From a8b56cb27d47ecba7b26041c05fe423130ee7a24 Mon Sep 17 00:00:00 2001 From: Manikanta Mylavarapu Date: Tue, 10 Dec 2024 12:11:09 +0530 Subject: [PATCH 61/81] dt-bindings: clock: qcom: gcc-ipq5424: add gcc_xo_clk macro The GCC_XO_CLK is required for the functionality of the WiFi copy engine block. Therefore, add the GCC_XO_CLK macro. Signed-off-by: Manikanta Mylavarapu Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20241210064110.130466-2-quic_mmanikan@quicinc.com Signed-off-by: Bjorn Andersson --- include/dt-bindings/clock/qcom,ipq5424-gcc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/clock/qcom,ipq5424-gcc.h b/include/dt-bindings/clock/qcom,ipq5424-gcc.h index 9f14680052a0a..c15ad16923bde 100644 --- a/include/dt-bindings/clock/qcom,ipq5424-gcc.h +++ b/include/dt-bindings/clock/qcom,ipq5424-gcc.h @@ -151,5 +151,6 @@ #define GCC_PCIE3_RCHNG_CLK_SRC 142 #define GCC_PCIE3_RCHNG_CLK 143 #define GCC_IM_SLEEP_CLK 144 +#define GCC_XO_CLK 145 #endif From d966ee051ebf97e973ea9e84a7f98ab1906510a2 Mon Sep 17 00:00:00 2001 From: Manikanta Mylavarapu Date: Tue, 10 Dec 2024 12:11:10 +0530 Subject: [PATCH 62/81] clk: qcom: ipq5424: add gcc_xo_clk The gcc_xo_clk is required for the functionality of the WiFi copy engine block. Therefore, add the gcc_xo_clk in gcc driver. Signed-off-by: Manikanta Mylavarapu Link: https://lore.kernel.org/r/20241210064110.130466-3-quic_mmanikan@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-ipq5424.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c index 5f42ac6c8cdc1..92b133baec01f 100644 --- a/drivers/clk/qcom/gcc-ipq5424.c +++ b/drivers/clk/qcom/gcc-ipq5424.c @@ -325,6 +325,24 @@ static struct clk_rcg2 gcc_xo_clk_src = { }, }; +static struct clk_branch gcc_xo_clk = { + .halt_reg = 0x34018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x34018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_fixed_factor gcc_xo_div4_clk_src = { .mult = 1, .div = 4, @@ -2901,6 +2919,7 @@ static struct clk_regmap *gcc_ipq5424_clocks[] = { [GCC_QPIC_CLK_SRC] = &gcc_qpic_clk_src.clkr, [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr, [GCC_XO_CLK_SRC] = &gcc_xo_clk_src.clkr, + [GCC_XO_CLK] = &gcc_xo_clk.clkr, [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, [GCC_QDSS_AT_CLK] = &gcc_qdss_at_clk.clkr, [GPLL0] = &gpll0.clkr, From d26c4ad3fa53e76a602a9974ade171c8399f2a29 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Tue, 7 Jan 2025 17:55:23 +0200 Subject: [PATCH 63/81] clk: qcom: gcc-x1e80100: Do not turn off usb_2 controller GDSC Allowing the usb_2 controller GDSC to be turned off during system suspend renders the controller unable to resume. So use PWRSTS_RET_ON instead in order to make sure this the GDSC doesn't go down. Fixes: 161b7c401f4b ("clk: qcom: Add Global Clock controller (GCC) driver for X1E80100") Cc: stable@vger.kernel.org # 6.8 Signed-off-by: Abel Vesa Reviewed-by: Johan Hovold Tested-by: Johan Hovold Link: https://lore.kernel.org/r/20250107-x1e80100-clk-gcc-fix-usb2-gdsc-pwrsts-v1-1-e15d1a5e7d80@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-x1e80100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index 8ea25aa25dff0..7288af845434d 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -6083,7 +6083,7 @@ static struct gdsc gcc_usb20_prim_gdsc = { .pd = { .name = "gcc_usb20_prim_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; From cef0523dd2ff65cc95cb747a348ce018f22f4d95 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski Date: Mon, 18 Nov 2024 13:15:19 +0300 Subject: [PATCH 64/81] clk: qcom: clk-rcg2: document calc_rate function Update calc_rate docs to reflect, that pre_div is not pure divisor, but a register value, and requires conversion. Signed-off-by: Dzmitry Sankouski Link: https://lore.kernel.org/r/20241118-starqltechn_integration_upstream-v8-1-ac8e36a3aa65@gmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rcg2.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index bf6406f5279a4..4da70be280cef 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -148,12 +148,21 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index) return update_config(rcg); } -/* - * Calculate m/n:d rate +/** + * calc_rate() - Calculate rate based on m/n:d values + * + * @rate: Parent rate. + * @m: Multiplier. + * @n: Divisor. + * @mode: Use zero to ignore m/n calculation. + * @hid_div: Pre divisor register value. Pre divisor value + * relates to hid_div as pre_div = (hid_div + 1) / 2. + * + * Return calculated rate according to formula: * * parent_rate m * rate = ----------- x --- - * hid_div n + * pre_div n */ static unsigned long calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div) From faddad527c82714dede83d932b4d31f7e38c1766 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski Date: Mon, 18 Nov 2024 13:15:20 +0300 Subject: [PATCH 65/81] clk: qcom: clk-rcg2: split __clk_rcg2_configure function __clk_rcg2_configure function does 2 things - configures parent and mnd values. In order to be able to add new clock options, we should split. Move __clk_rcg2_configure logic on 2 functions: - __clk_rcg2_configure_parent which configures clock parent - __clk_rcg2_configure_mnd which configures mnd values __clk_rcg2_configure delegates to mentioned functions. Signed-off-by: Dzmitry Sankouski Link: https://lore.kernel.org/r/20241118-starqltechn_integration_upstream-v8-2-ac8e36a3aa65@gmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rcg2.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 4da70be280cef..5dbee86782d51 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -402,16 +402,26 @@ static int clk_rcg2_fm_determine_rate(struct clk_hw *hw, return _freq_tbl_fm_determine_rate(hw, rcg->freq_multi_tbl, req); } -static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f, - u32 *_cfg) +static int __clk_rcg2_configure_parent(struct clk_rcg2 *rcg, u8 src, u32 *_cfg) { - u32 cfg, mask, d_val, not2d_val, n_minus_m; struct clk_hw *hw = &rcg->clkr.hw; - int ret, index = qcom_find_src_index(hw, rcg->parent_map, f->src); + int index = qcom_find_src_index(hw, rcg->parent_map, src); if (index < 0) return index; + *_cfg &= ~CFG_SRC_SEL_MASK; + *_cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT; + + return 0; +} + +static int __clk_rcg2_configure_mnd(struct clk_rcg2 *rcg, const struct freq_tbl *f, + u32 *_cfg) +{ + u32 cfg, mask, d_val, not2d_val, n_minus_m; + int ret; + if (rcg->mnd_width && f->n) { mask = BIT(rcg->mnd_width) - 1; ret = regmap_update_bits(rcg->clkr.regmap, @@ -440,9 +450,8 @@ static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f, } mask = BIT(rcg->hid_width) - 1; - mask |= CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK; + mask |= CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK; cfg = f->pre_div << CFG_SRC_DIV_SHIFT; - cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT; if (rcg->mnd_width && f->n && (f->m != f->n)) cfg |= CFG_MODE_DUAL_EDGE; if (rcg->hw_clk_ctrl) @@ -454,6 +463,22 @@ static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f, return 0; } +static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f, + u32 *_cfg) +{ + int ret; + + ret = __clk_rcg2_configure_parent(rcg, f->src, _cfg); + if (ret) + return ret; + + ret = __clk_rcg2_configure_mnd(rcg, f, _cfg); + if (ret) + return ret; + + return 0; +} + static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) { u32 cfg; From 898b72fa44f5739d22016ec5ff6697ba4ac4464d Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski Date: Mon, 18 Nov 2024 13:15:21 +0300 Subject: [PATCH 66/81] clk: qcom: gcc-sdm845: Add general purpose clock ops SDM845 has "General Purpose" clocks that can be muxed to SoC pins to clock various external devices. Those clocks may be used as e.g. PWM sources for external peripherals. GPCLK can in theory have arbitrary value depending on the use case, so the concept of frequency tables, used in rcg2 clock driver, is not efficient, because it allows only defined frequencies. Introduce clk_rcg2_gp_ops, which automatically calculate clock mnd values for arbitrary clock rate. The calculation done as follows: - upon determine rate request, we calculate m/n/pre_div as follows: - find parent(from our client's assigned-clock-parent) rate - find scaled rates by dividing rates on its greatest common divisor - assign requested scaled rate to m - factorize scaled parent rate, put multipliers to n till max value (determined by mnd_width) - validate calculated values with *_width: - if doesn't fit, delete divisor and multiplier by 2 until fit - return determined rate Limitations: - The driver doesn't select a parent clock (it may be selected by client in device tree with assigned-clocks, assigned-clock-parents properties) Signed-off-by: Dzmitry Sankouski Link: https://lore.kernel.org/r/20241118-starqltechn_integration_upstream-v8-3-ac8e36a3aa65@gmail.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c | 146 ++++++++++++++++++++++++++++++++++ drivers/clk/qcom/gcc-sdm845.c | 11 +-- 3 files changed, 150 insertions(+), 8 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index 80f1f4fcd52a6..4fbdf4880d030 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -189,6 +189,7 @@ struct clk_rcg2_gfx3d { container_of(to_clk_rcg2(_hw), struct clk_rcg2_gfx3d, rcg) extern const struct clk_ops clk_rcg2_ops; +extern const struct clk_ops clk_rcg2_gp_ops; extern const struct clk_ops clk_rcg2_floor_ops; extern const struct clk_ops clk_rcg2_fm_ops; extern const struct clk_ops clk_rcg2_mux_closest_ops; diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 5dbee86782d51..8001fd9faf9d1 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -8,11 +8,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -32,6 +34,7 @@ #define CFG_REG 0x4 #define CFG_SRC_DIV_SHIFT 0 +#define CFG_SRC_DIV_LENGTH 8 #define CFG_SRC_SEL_SHIFT 8 #define CFG_SRC_SEL_MASK (0x7 << CFG_SRC_SEL_SHIFT) #define CFG_MODE_SHIFT 12 @@ -148,6 +151,17 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index) return update_config(rcg); } +/** + * convert_to_reg_val() - Convert divisor values to hardware values. + * + * @f: Frequency table with pure m/n/pre_div parameters. + */ +static void convert_to_reg_val(struct freq_tbl *f) +{ + f->pre_div *= 2; + f->pre_div -= 1; +} + /** * calc_rate() - Calculate rate based on m/n:d values * @@ -402,6 +416,90 @@ static int clk_rcg2_fm_determine_rate(struct clk_hw *hw, return _freq_tbl_fm_determine_rate(hw, rcg->freq_multi_tbl, req); } +/** + * clk_rcg2_split_div() - Split multiplier that doesn't fit in n neither in pre_div. + * + * @multiplier: Multiplier to split between n and pre_div. + * @pre_div: Pointer to pre divisor value. + * @n: Pointer to n divisor value. + * @pre_div_max: Pre divisor maximum value. + */ +static inline void clk_rcg2_split_div(int multiplier, unsigned int *pre_div, + u16 *n, unsigned int pre_div_max) +{ + *n = mult_frac(multiplier * *n, *pre_div, pre_div_max); + *pre_div = pre_div_max; +} + +static void clk_rcg2_calc_mnd(u64 parent_rate, u64 rate, struct freq_tbl *f, + unsigned int mnd_max, unsigned int pre_div_max) +{ + int i = 2; + unsigned int pre_div = 1; + unsigned long rates_gcd, scaled_parent_rate; + u16 m, n = 1, n_candidate = 1, n_max; + + rates_gcd = gcd(parent_rate, rate); + m = div64_u64(rate, rates_gcd); + scaled_parent_rate = div64_u64(parent_rate, rates_gcd); + while (scaled_parent_rate > (mnd_max + m) * pre_div_max) { + // we're exceeding divisor's range, trying lower scale. + if (m > 1) { + m--; + scaled_parent_rate = mult_frac(scaled_parent_rate, m, (m + 1)); + } else { + // cannot lower scale, just set max divisor values. + f->n = mnd_max + m; + f->pre_div = pre_div_max; + f->m = m; + return; + } + } + + n_max = m + mnd_max; + + while (scaled_parent_rate > 1) { + while (scaled_parent_rate % i == 0) { + n_candidate *= i; + if (n_candidate < n_max) + n = n_candidate; + else if (pre_div * i < pre_div_max) + pre_div *= i; + else + clk_rcg2_split_div(i, &pre_div, &n, pre_div_max); + + scaled_parent_rate /= i; + } + i++; + } + + f->m = m; + f->n = n; + f->pre_div = pre_div > 1 ? pre_div : 0; +} + +static int clk_rcg2_determine_gp_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + struct freq_tbl f_tbl = {}, *f = &f_tbl; + int mnd_max = BIT(rcg->mnd_width) - 1; + int hid_max = BIT(rcg->hid_width) - 1; + struct clk_hw *parent; + u64 parent_rate; + + parent = clk_hw_get_parent(hw); + parent_rate = clk_get_rate(parent->clk); + if (!parent_rate) + return -EINVAL; + + clk_rcg2_calc_mnd(parent_rate, req->rate, f, mnd_max, hid_max / 2); + convert_to_reg_val(f); + req->rate = calc_rate(parent_rate, f->m, f->n, f->n, f->pre_div); + + return 0; +} + static int __clk_rcg2_configure_parent(struct clk_rcg2 *rcg, u8 src, u32 *_cfg) { struct clk_hw *hw = &rcg->clkr.hw; @@ -499,6 +597,26 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) return update_config(rcg); } +static int clk_rcg2_configure_gp(struct clk_rcg2 *rcg, const struct freq_tbl *f) +{ + u32 cfg; + int ret; + + ret = regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg); + if (ret) + return ret; + + ret = __clk_rcg2_configure_mnd(rcg, f, &cfg); + if (ret) + return ret; + + ret = regmap_write(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), cfg); + if (ret) + return ret; + + return update_config(rcg); +} + static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate, enum freq_policy policy) { @@ -552,6 +670,22 @@ static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate, return __clk_rcg2_set_rate(hw, rate, CEIL); } +static int clk_rcg2_set_gp_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + int mnd_max = BIT(rcg->mnd_width) - 1; + int hid_max = BIT(rcg->hid_width) - 1; + struct freq_tbl f_tbl = {}, *f = &f_tbl; + int ret; + + clk_rcg2_calc_mnd(parent_rate, rate, f, mnd_max, hid_max / 2); + convert_to_reg_val(f); + ret = clk_rcg2_configure_gp(rcg, f); + + return ret; +} + static int clk_rcg2_set_floor_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -679,6 +813,18 @@ const struct clk_ops clk_rcg2_ops = { }; EXPORT_SYMBOL_GPL(clk_rcg2_ops); +const struct clk_ops clk_rcg2_gp_ops = { + .is_enabled = clk_rcg2_is_enabled, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .determine_rate = clk_rcg2_determine_gp_rate, + .set_rate = clk_rcg2_set_gp_rate, + .get_duty_cycle = clk_rcg2_get_duty_cycle, + .set_duty_cycle = clk_rcg2_set_duty_cycle, +}; +EXPORT_SYMBOL_GPL(clk_rcg2_gp_ops); + const struct clk_ops clk_rcg2_floor_ops = { .is_enabled = clk_rcg2_is_enabled, .get_parent = clk_rcg2_get_parent, diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index dc3aa7014c3ed..0def0fc0e0095 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -284,11 +284,6 @@ static struct clk_rcg2 gcc_sdm670_cpuss_rbcpr_clk_src = { }; static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { - F(19200000, P_BI_TCXO, 1, 0, 0), - F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), - F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), - F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), - F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), { } }; @@ -302,7 +297,7 @@ static struct clk_rcg2 gcc_gp1_clk_src = { .name = "gcc_gp1_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_gp_ops, }, }; @@ -316,7 +311,7 @@ static struct clk_rcg2 gcc_gp2_clk_src = { .name = "gcc_gp2_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_gp_ops, }, }; @@ -330,7 +325,7 @@ static struct clk_rcg2 gcc_gp3_clk_src = { .name = "gcc_gp3_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_gp_ops, }, }; From b51adc77557a15c1598bd70365bee253d16a306b Mon Sep 17 00:00:00 2001 From: Rohit Visavalia Date: Mon, 6 Jan 2025 20:40:37 -0800 Subject: [PATCH 67/81] dt-bindings: clock: xilinx: Convert VCU bindings to dtschema Convert AMD (Xilinx) VCU bindings to yaml format. Additional changes: - move xlnx_vcu DT binding to clock from soc following commit a2fe7baa27a4 ("clk: xilinx: move xlnx_vcu clock driver from soc") - corrected clock sequence as per xilinx device-tree generator Signed-off-by: Rohit Visavalia Link: https://lore.kernel.org/r/20250107044038.100945-2-rohit.visavalia@amd.com Reviewed-by: Krzysztof Kozlowski Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/xlnx,vcu.yaml | 55 +++++++++++++++++++ .../bindings/soc/xilinx/xlnx,vcu.txt | 26 --------- 2 files changed, 55 insertions(+), 26 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/xlnx,vcu.yaml delete mode 100644 Documentation/devicetree/bindings/soc/xilinx/xlnx,vcu.txt diff --git a/Documentation/devicetree/bindings/clock/xlnx,vcu.yaml b/Documentation/devicetree/bindings/clock/xlnx,vcu.yaml new file mode 100644 index 0000000000000..02d27d11a452d --- /dev/null +++ b/Documentation/devicetree/bindings/clock/xlnx,vcu.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/xlnx,vcu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# +title: LogicoreIP designed compatible with Xilinx ZYNQ family. + +maintainers: + - Rohit Visavalia + +description: + LogicoreIP design to provide the isolation between processing system + and programmable logic. Also provides the list of register set to configure + the frequency. + +properties: + compatible: + items: + - enum: + - xlnx,vcu + - xlnx,vcu-logicoreip-1.0 + + reg: + maxItems: 1 + + clocks: + items: + - description: pll ref clocksource + - description: aclk + + clock-names: + items: + - const: pll_ref + - const: aclk + +required: + - reg + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + fpga { + #address-cells = <2>; + #size-cells = <2>; + xlnx_vcu: vcu@a0040000 { + compatible = "xlnx,vcu-logicoreip-1.0"; + reg = <0x0 0xa0040000 0x0 0x1000>; + clocks = <&si570_1>, <&clkc 71>; + clock-names = "pll_ref", "aclk"; + }; + }; diff --git a/Documentation/devicetree/bindings/soc/xilinx/xlnx,vcu.txt b/Documentation/devicetree/bindings/soc/xilinx/xlnx,vcu.txt deleted file mode 100644 index 2417b13ba4688..0000000000000 --- a/Documentation/devicetree/bindings/soc/xilinx/xlnx,vcu.txt +++ /dev/null @@ -1,26 +0,0 @@ -LogicoreIP designed compatible with Xilinx ZYNQ family. -------------------------------------------------------- - -General concept ---------------- - -LogicoreIP design to provide the isolation between processing system -and programmable logic. Also provides the list of register set to configure -the frequency. - -Required properties: -- compatible: shall be one of: - "xlnx,vcu" - "xlnx,vcu-logicoreip-1.0" -- reg : The base offset and size of the VCU_PL_SLCR register space. -- clocks: phandle for aclk and pll_ref clocksource -- clock-names: The identification string, "aclk", is always required for - the axi clock. "pll_ref" is required for pll. -Example: - - xlnx_vcu: vcu@a0040000 { - compatible = "xlnx,vcu-logicoreip-1.0"; - reg = <0x0 0xa0040000 0x0 0x1000>; - clocks = <&si570_1>, <&clkc 71>; - clock-names = "pll_ref", "aclk"; - }; From b00b08a59674eacc77848d852d7c37de485add81 Mon Sep 17 00:00:00 2001 From: Rohit Visavalia Date: Mon, 6 Jan 2025 20:40:38 -0800 Subject: [PATCH 68/81] dt-bindings: clock: xilinx: Add reset GPIO for VCU It is marked as optional as some of the ZynqMP designs are having vcu_reset (reset pin of VCU IP) driven by proc_sys_reset, proc_sys_reset is another PL IP driven by the PS pl_reset. So, here the VCU reset is not driven by axi_gpio or PS GPIO so there will be no GPIO entry. Signed-off-by: Rohit Visavalia Link: https://lore.kernel.org/r/20250107044038.100945-3-rohit.visavalia@amd.com Reviewed-by: Krzysztof Kozlowski Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/xlnx,vcu.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/xlnx,vcu.yaml b/Documentation/devicetree/bindings/clock/xlnx,vcu.yaml index 02d27d11a452d..19dc923e2ee94 100644 --- a/Documentation/devicetree/bindings/clock/xlnx,vcu.yaml +++ b/Documentation/devicetree/bindings/clock/xlnx,vcu.yaml @@ -33,6 +33,9 @@ properties: - const: pll_ref - const: aclk + reset-gpios: + maxItems: 1 + required: - reg - clocks @@ -49,6 +52,7 @@ examples: xlnx_vcu: vcu@a0040000 { compatible = "xlnx,vcu-logicoreip-1.0"; reg = <0x0 0xa0040000 0x0 0x1000>; + reset-gpios = <&gpio 78 GPIO_ACTIVE_HIGH>; clocks = <&si570_1>, <&clkc 71>; clock-names = "pll_ref", "aclk"; }; From 7681f64e6404edbca2f67501c98d596e5c307993 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Mon, 6 Jan 2025 13:59:37 +0530 Subject: [PATCH 69/81] clk: clocking-wizard: calculate dividers fractional parts Calculate dividers fractional parts to optimally modulate output frequency. Clocking wizard supports having multiplier m and divisors d and o. Currently the fractional parts of m and o are not utilised. For the pixel clock usecases a higher accuracy is needed.. Adding support for m and o to have fractional values. Co-developed-by: Anatoliy Klymenko Signed-off-by: Anatoliy Klymenko Signed-off-by: Shubhrajyoti Datta Tested-by: Anatoliy Klymenko Link: https://lore.kernel.org/r/20250106082937.29555-1-shubhrajyoti.datta@amd.com Signed-off-by: Stephen Boyd --- drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 121 ++++++++++++--------- 1 file changed, 69 insertions(+), 52 deletions(-) diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index b2233d3ff9a99..bbf7714480e7b 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -52,6 +52,8 @@ #define WZRD_CLKFBOUT_MULT_SHIFT 8 #define WZRD_CLKFBOUT_MULT_MASK (0xff << WZRD_CLKFBOUT_MULT_SHIFT) +#define WZRD_CLKFBOUT_MULT_FRAC_MASK GENMASK(25, 16) +#define WZRD_CLKFBOUT_O_MASK GENMASK(7, 0) #define WZRD_CLKFBOUT_L_SHIFT 0 #define WZRD_CLKFBOUT_H_SHIFT 8 #define WZRD_CLKFBOUT_L_MASK GENMASK(7, 0) @@ -87,14 +89,14 @@ #define DIV_O 0x01 #define DIV_ALL 0x03 -#define WZRD_M_MIN 2 -#define WZRD_M_MAX 128 -#define WZRD_D_MIN 1 -#define WZRD_D_MAX 106 -#define WZRD_VCO_MIN 800000000 -#define WZRD_VCO_MAX 1600000000 -#define WZRD_O_MIN 1 -#define WZRD_O_MAX 128 +#define WZRD_M_MIN 2ULL +#define WZRD_M_MAX 128ULL +#define WZRD_D_MIN 1ULL +#define WZRD_D_MAX 106ULL +#define WZRD_VCO_MIN 800000000ULL +#define WZRD_VCO_MAX 1600000000ULL +#define WZRD_O_MIN 2ULL +#define WZRD_O_MAX 128ULL #define VER_WZRD_M_MIN 4 #define VER_WZRD_M_MAX 432 #define VER_WZRD_D_MIN 1 @@ -153,8 +155,10 @@ struct clk_wzrd { * @flags: clk_wzrd divider flags * @table: array of value/divider pairs, last entry should have div = 0 * @m: value of the multiplier + * @m_frac: fractional value of the multiplier * @d: value of the common divider * @o: value of the leaf divider + * @o_frac: value of the fractional leaf divider * @lock: register lock */ struct clk_wzrd_divider { @@ -166,8 +170,10 @@ struct clk_wzrd_divider { u8 flags; const struct clk_div_table *table; u32 m; + u32 m_frac; u32 d; u32 o; + u32 o_frac; spinlock_t *lock; /* divider lock */ }; @@ -372,38 +378,40 @@ static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); - u64 vco_freq, freq, diff, vcomin, vcomax; - u32 m, d, o; - u32 mmin, mmax, dmin, dmax, omin, omax; + u64 vco_freq, freq, diff, vcomin, vcomax, best_diff = -1ULL; + u64 m, d, o; + u64 mmin, mmax, dmin, dmax, omin, omax, mdmin, mdmax; - mmin = WZRD_M_MIN; - mmax = WZRD_M_MAX; + mmin = WZRD_M_MIN << 3; + mmax = WZRD_M_MAX << 3; dmin = WZRD_D_MIN; dmax = WZRD_D_MAX; - omin = WZRD_O_MIN; - omax = WZRD_O_MAX; - vcomin = WZRD_VCO_MIN; - vcomax = WZRD_VCO_MAX; + omin = WZRD_O_MIN << 3; + omax = WZRD_O_MAX << 3; + vcomin = WZRD_VCO_MIN << 3; + vcomax = WZRD_VCO_MAX << 3; for (m = mmin; m <= mmax; m++) { - for (d = dmin; d <= dmax; d++) { - vco_freq = DIV_ROUND_CLOSEST((parent_rate * m), d); - if (vco_freq >= vcomin && vco_freq <= vcomax) { - for (o = omin; o <= omax; o++) { - freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o); - diff = abs(freq - rate); - - if (diff < WZRD_MIN_ERR) { - divider->m = m; - divider->d = d; - divider->o = o; - return 0; - } - } + mdmin = max(dmin, div64_u64(parent_rate * m + vcomax / 2, vcomax)); + mdmax = min(dmax, div64_u64(parent_rate * m + vcomin / 2, vcomin)); + for (d = mdmin; d <= mdmax; d++) { + vco_freq = DIV_ROUND_CLOSEST_ULL((parent_rate * m), d); + o = DIV_ROUND_CLOSEST_ULL(vco_freq, rate); + if (o < omin || o > omax) + continue; + freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o); + diff = freq - rate; + if (diff < best_diff) { + best_diff = diff; + divider->m = m >> 3; + divider->m_frac = (m - (divider->m << 3)) * 125; + divider->d = d; + divider->o = o >> 3; + divider->o_frac = (o - (divider->o << 3)) * 125; } } } - return -EBUSY; + return best_diff < WZRD_MIN_ERR ? 0 : -EBUSY; } static int clk_wzrd_reconfig(struct clk_wzrd_divider *divider, void __iomem *div_addr) @@ -496,33 +504,22 @@ static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); - unsigned long vco_freq, rate_div, clockout0_div; void __iomem *div_addr; - u32 reg, pre, f; + u32 reg; int err; err = clk_wzrd_get_divisors(hw, rate, parent_rate); if (err) return err; - vco_freq = DIV_ROUND_CLOSEST(parent_rate * divider->m, divider->d); - rate_div = DIV_ROUND_CLOSEST_ULL((vco_freq * WZRD_FRAC_POINTS), rate); - - clockout0_div = div_u64(rate_div, WZRD_FRAC_POINTS); - - pre = DIV_ROUND_CLOSEST_ULL(vco_freq * WZRD_FRAC_POINTS, rate); - f = (pre - (clockout0_div * WZRD_FRAC_POINTS)); - f &= WZRD_CLKOUT_FRAC_MASK; - - reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, clockout0_div) | - FIELD_PREP(WZRD_CLKOUT0_FRAC_MASK, f); + reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, divider->o) | + FIELD_PREP(WZRD_CLKOUT0_FRAC_MASK, divider->o_frac); writel(reg, divider->base + WZRD_CLK_CFG_REG(0, 2)); - /* Set divisor and clear phase offset */ reg = FIELD_PREP(WZRD_CLKFBOUT_MULT_MASK, divider->m) | + FIELD_PREP(WZRD_CLKFBOUT_MULT_FRAC_MASK, divider->m_frac) | FIELD_PREP(WZRD_DIVCLK_DIVIDE_MASK, divider->d); writel(reg, divider->base + WZRD_CLK_CFG_REG(0, 0)); - writel(divider->o, divider->base + WZRD_CLK_CFG_REG(0, 2)); writel(0, divider->base + WZRD_CLK_CFG_REG(0, 3)); div_addr = divider->base + WZRD_DR_INIT_REG_OFFSET; return clk_wzrd_reconfig(divider, div_addr); @@ -564,18 +561,19 @@ static unsigned long clk_wzrd_recalc_rate_all(struct clk_hw *hw, unsigned long parent_rate) { struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); - u32 m, d, o, div, reg, f; + u32 m, d, o, reg, f, mf; + u64 mul; reg = readl(divider->base + WZRD_CLK_CFG_REG(0, 0)); d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg); m = FIELD_GET(WZRD_CLKFBOUT_MULT_MASK, reg); + mf = FIELD_GET(WZRD_CLKFBOUT_MULT_FRAC_MASK, reg); reg = readl(divider->base + WZRD_CLK_CFG_REG(0, 2)); o = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg); f = FIELD_GET(WZRD_CLKOUT0_FRAC_MASK, reg); - div = DIV_ROUND_CLOSEST(d * (WZRD_FRAC_POINTS * o + f), WZRD_FRAC_POINTS); - return divider_recalc_rate(hw, parent_rate * m, div, divider->table, - divider->flags, divider->width); + mul = m * 1000 + mf; + return DIV_ROUND_CLOSEST_ULL(parent_rate * mul, d * (o * 1000 + f)); } static unsigned long clk_wzrd_recalc_rate_all_ver(struct clk_hw *hw, @@ -646,6 +644,25 @@ static unsigned long clk_wzrd_recalc_rate_all_ver(struct clk_hw *hw, static long clk_wzrd_round_rate_all(struct clk_hw *hw, unsigned long rate, unsigned long *prate) +{ + struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); + u32 m, d, o; + int err; + + err = clk_wzrd_get_divisors(hw, rate, *prate); + if (err) + return err; + + m = divider->m; + d = divider->d; + o = divider->o; + + rate = div_u64(*prate * (m * 1000 + divider->m_frac), d * (o * 1000 + divider->o_frac)); + return rate; +} + +static long clk_wzrd_ver_round_rate_all(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) { struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); unsigned long int_freq; @@ -678,7 +695,7 @@ static const struct clk_ops clk_wzrd_ver_divider_ops = { }; static const struct clk_ops clk_wzrd_ver_div_all_ops = { - .round_rate = clk_wzrd_round_rate_all, + .round_rate = clk_wzrd_ver_round_rate_all, .set_rate = clk_wzrd_dynamic_all_ver, .recalc_rate = clk_wzrd_recalc_rate_all_ver, }; From f760a4bb5e927a133dcd75f7b69ccae2a331e42c Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Mon, 9 Dec 2024 23:19:12 +0530 Subject: [PATCH 70/81] clk: qcom: gcc-sdm845: Do not use shared clk_ops for QUPs Similar to the earlier fixes meant for sm8x50 and x1e platforms, we have to stop using the shared clk ops for sdm845 QUPs as well. As Stephen Boyd pointed out in earlier fixes, there wasn't a problem to mark QUP clks shared until we started parking shared RCGs at clk registration time in commit 01a0a6cc8cfd ("clk: qcom: Park shared RCGs upon registration"). Parking at init is actually harmful to the UART when earlycon is used. If the device is pumping out data while the frequency changes and we see garbage on the serial console until the driver can probe and actually set a proper frequency. This patch reverts the QUP clk sharing ops part of commit 06391eddb60a ("clk: qcom: Add Global Clock controller (GCC) driver for SDM845"), so that the QUPs on sdm845 don't get parked during clk registration and break UART operations. Fixes: 01a0a6cc8cfd ("clk: qcom: Park shared RCGs upon registration") Signed-off-by: Amit Pundir Link: https://lore.kernel.org/r/20241209174912.2526928-1-amit.pundir@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sdm845.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index 0def0fc0e0095..6d0f9cede5cfe 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -449,7 +449,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { .name = "gcc_qupv3_wrap0_s0_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { @@ -465,7 +465,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { .name = "gcc_qupv3_wrap0_s1_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { @@ -481,7 +481,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { .name = "gcc_qupv3_wrap0_s2_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { @@ -497,7 +497,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { .name = "gcc_qupv3_wrap0_s3_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { @@ -513,7 +513,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { .name = "gcc_qupv3_wrap0_s4_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { @@ -529,7 +529,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { .name = "gcc_qupv3_wrap0_s5_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { @@ -545,7 +545,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = { .name = "gcc_qupv3_wrap0_s6_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { @@ -561,7 +561,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = { .name = "gcc_qupv3_wrap0_s7_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { @@ -577,7 +577,7 @@ 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), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { @@ -593,7 +593,7 @@ 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), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { @@ -609,7 +609,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { .name = "gcc_qupv3_wrap1_s2_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { @@ -625,7 +625,7 @@ 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), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { @@ -641,7 +641,7 @@ 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), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { @@ -657,7 +657,7 @@ 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), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { @@ -673,7 +673,7 @@ 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), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { @@ -689,7 +689,7 @@ 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), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { From 030de8eafdcbc3d6c087bddb5450aea2b29520e5 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Thu, 12 Dec 2024 00:25:50 +0000 Subject: [PATCH 71/81] dt-bindings: clock: Add Qualcomm SM6115 LPASS clock controller SM6115 (and its derivatives or similar SoCs) has an LPASS clock controller block which provides audio-related resets. Add bindings for it. Cc: Konrad Dybcio Cc: Konrad Dybcio Cc: Srinivas Kandagatla Reviewed-by: Krzysztof Kozlowski Signed-off-by: Konrad Dybcio [alexey.klimov slightly changed the commit message] Signed-off-by: Alexey Klimov Link: https://lore.kernel.org/r/20241212002551.2902954-2-alexey.klimov@linaro.org [bjorn: Adjusted Konrad's address] Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm6115-lpasscc.yaml | 46 +++++++++++++++++++ .../dt-bindings/clock/qcom,sm6115-lpasscc.h | 15 ++++++ 2 files changed, 61 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sm6115-lpasscc.yaml create mode 100644 include/dt-bindings/clock/qcom,sm6115-lpasscc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm6115-lpasscc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm6115-lpasscc.yaml new file mode 100644 index 0000000000000..8cbab3fbb6601 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sm6115-lpasscc.yaml @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sm6115-lpasscc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm LPASS Core & Audio Clock Controller on SM6115 + +maintainers: + - Konrad Dybcio + - Srinivas Kandagatla + +description: | + Qualcomm LPASS core and audio clock controllers provide audio-related resets + on SM6115 and its derivatives. + + See also:: + include/dt-bindings/clock/qcom,sm6115-lpasscc.h + +properties: + compatible: + enum: + - qcom,sm6115-lpassaudiocc + - qcom,sm6115-lpasscc + + reg: + maxItems: 1 + + '#reset-cells': + const: 1 + +required: + - compatible + - reg + - '#reset-cells' + +additionalProperties: false + +examples: + - | + lpass_audiocc: clock-controller@a6a9000 { + compatible = "qcom,sm6115-lpassaudiocc"; + reg = <0x0a6a9000 0x1000>; + #reset-cells = <1>; + }; +... diff --git a/include/dt-bindings/clock/qcom,sm6115-lpasscc.h b/include/dt-bindings/clock/qcom,sm6115-lpasscc.h new file mode 100644 index 0000000000000..799274517c9ab --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm6115-lpasscc.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2023, Linaro Ltd. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_LPASSCC_SM6115_H +#define _DT_BINDINGS_CLK_QCOM_LPASSCC_SM6115_H + +/* LPASS CC */ +#define LPASS_SWR_TX_CONFIG_CGCR 0 + +/* LPASS_AUDIO CC */ +#define LPASS_AUDIO_SWR_RX_CGCR 0 + +#endif From b076b995e225b0e9c345b015a182352221334c3e Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Thu, 12 Dec 2024 00:25:51 +0000 Subject: [PATCH 72/81] clk: qcom: Add SM6115 LPASSCC SM6115 (and its derivatives or similar SoCs) has an LPASS clock controller block which provides audio-related resets. Add the required code to support them. [alexey.klimov] fixed compilation errors after rebase, slightly changed the commit message Cc: Konrad Dybcio Cc: Konrad Dybcio Cc: Srinivas Kandagatla Signed-off-by: Konrad Dybcio Signed-off-by: Alexey Klimov Link: https://lore.kernel.org/r/20241212002551.2902954-3-alexey.klimov@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 9 ++++ drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/lpasscc-sm6115.c | 85 +++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 drivers/clk/qcom/lpasscc-sm6115.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 2daff198aeb3f..f2e207e36907b 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1278,6 +1278,15 @@ config SM_GPUCC_8650 Say Y if you want to support graphics controller devices and functionality such as 3D graphics. +config SM_LPASSCC_6115 + tristate "SM6115 Low Power Audio Subsystem (LPASS) Clock Controller" + depends on ARM64 || COMPILE_TEST + select SM_GCC_6115 + help + Support for the LPASS clock controller on SM6115 devices. + Say Y if you want to toggle LPASS-adjacent resets within + this clock controller to reset the LPASS subsystem. + config SM_TCSRCC_8550 tristate "SM8550 TCSR Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 6665049cb8c89..0db2f98bcb3e0 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -159,6 +159,7 @@ obj-$(CONFIG_SM_GPUCC_8350) += gpucc-sm8350.o obj-$(CONFIG_SM_GPUCC_8450) += gpucc-sm8450.o obj-$(CONFIG_SM_GPUCC_8550) += gpucc-sm8550.o obj-$(CONFIG_SM_GPUCC_8650) += gpucc-sm8650.o +obj-$(CONFIG_SM_LPASSCC_6115) += lpasscc-sm6115.o obj-$(CONFIG_SM_TCSRCC_8550) += tcsrcc-sm8550.o obj-$(CONFIG_SM_TCSRCC_8650) += tcsrcc-sm8650.o obj-$(CONFIG_SM_TCSRCC_8750) += tcsrcc-sm8750.o diff --git a/drivers/clk/qcom/lpasscc-sm6115.c b/drivers/clk/qcom/lpasscc-sm6115.c new file mode 100644 index 0000000000000..8ffdab71b9483 --- /dev/null +++ b/drivers/clk/qcom/lpasscc-sm6115.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022, 2023 Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "reset.h" + +static const struct qcom_reset_map lpass_audiocc_sm6115_resets[] = { + [LPASS_AUDIO_SWR_RX_CGCR] = { .reg = 0x98, .bit = 1, .udelay = 500 }, +}; + +static struct regmap_config lpass_audiocc_sm6115_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .name = "lpass-audio-csr", + .max_register = 0x1000, +}; + +static const struct qcom_cc_desc lpass_audiocc_sm6115_reset_desc = { + .config = &lpass_audiocc_sm6115_regmap_config, + .resets = lpass_audiocc_sm6115_resets, + .num_resets = ARRAY_SIZE(lpass_audiocc_sm6115_resets), +}; + +static const struct qcom_reset_map lpasscc_sm6115_resets[] = { + [LPASS_SWR_TX_CONFIG_CGCR] = { .reg = 0x100, .bit = 1, .udelay = 500 }, +}; + +static struct regmap_config lpasscc_sm6115_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .name = "lpass-tcsr", + .max_register = 0x1000, +}; + +static const struct qcom_cc_desc lpasscc_sm6115_reset_desc = { + .config = &lpasscc_sm6115_regmap_config, + .resets = lpasscc_sm6115_resets, + .num_resets = ARRAY_SIZE(lpasscc_sm6115_resets), +}; + +static const struct of_device_id lpasscc_sm6115_match_table[] = { + { + .compatible = "qcom,sm6115-lpassaudiocc", + .data = &lpass_audiocc_sm6115_reset_desc, + }, { + .compatible = "qcom,sm6115-lpasscc", + .data = &lpasscc_sm6115_reset_desc, + }, + { }, +}; +MODULE_DEVICE_TABLE(of, lpasscc_sm6115_match_table); + +static int lpasscc_sm6115_probe(struct platform_device *pdev) +{ + const struct qcom_cc_desc *desc = of_device_get_match_data(&pdev->dev); + + return qcom_cc_probe_by_index(pdev, 0, desc); +} + +static struct platform_driver lpasscc_sm6115_driver = { + .probe = lpasscc_sm6115_probe, + .driver = { + .name = "lpasscc-sm6115", + .of_match_table = lpasscc_sm6115_match_table, + }, +}; + +module_platform_driver(lpasscc_sm6115_driver); + +MODULE_DESCRIPTION("QTI LPASSCC SM6115 Driver"); +MODULE_LICENSE("GPL"); From 2e1c78bf674024375de6eea33e113acc3473d2e2 Mon Sep 17 00:00:00 2001 From: Varadarajan Narayanan Date: Fri, 13 Dec 2024 16:28:07 +0530 Subject: [PATCH 73/81] dt-bindings: interconnect: Add Qualcomm IPQ5424 support Add master/slave ids for Qualcomm IPQ5424 Network-On-Chip interfaces. This will be used by the gcc-ipq5424 driver for providing interconnect services using the icc-clk framework. Signed-off-by: Varadarajan Narayanan Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20241213105808.674620-1-quic_varada@quicinc.com Signed-off-by: Bjorn Andersson --- .../dt-bindings/interconnect/qcom,ipq5424.h | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 include/dt-bindings/interconnect/qcom,ipq5424.h diff --git a/include/dt-bindings/interconnect/qcom,ipq5424.h b/include/dt-bindings/interconnect/qcom,ipq5424.h new file mode 100644 index 0000000000000..a770356112eed --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,ipq5424.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +#ifndef INTERCONNECT_QCOM_IPQ5424_H +#define INTERCONNECT_QCOM_IPQ5424_H + +#define MASTER_ANOC_PCIE0 0 +#define SLAVE_ANOC_PCIE0 1 +#define MASTER_CNOC_PCIE0 2 +#define SLAVE_CNOC_PCIE0 3 +#define MASTER_ANOC_PCIE1 4 +#define SLAVE_ANOC_PCIE1 5 +#define MASTER_CNOC_PCIE1 6 +#define SLAVE_CNOC_PCIE1 7 +#define MASTER_ANOC_PCIE2 8 +#define SLAVE_ANOC_PCIE2 9 +#define MASTER_CNOC_PCIE2 10 +#define SLAVE_CNOC_PCIE2 11 +#define MASTER_ANOC_PCIE3 12 +#define SLAVE_ANOC_PCIE3 13 +#define MASTER_CNOC_PCIE3 14 +#define SLAVE_CNOC_PCIE3 15 +#define MASTER_CNOC_USB 16 +#define SLAVE_CNOC_USB 17 + +#endif /* INTERCONNECT_QCOM_IPQ5424_H */ From 170f3d2c065ecb9757ed4e155e463aa25fd1eef9 Mon Sep 17 00:00:00 2001 From: Varadarajan Narayanan Date: Fri, 13 Dec 2024 16:28:08 +0530 Subject: [PATCH 74/81] clk: qcom: ipq5424: Use icc-clk for enabling NoC related clocks Use the icc-clk framework to enable few clocks to be able to create paths and use the peripherals connected on those NoCs. Signed-off-by: Varadarajan Narayanan Link: https://lore.kernel.org/r/20241213105808.674620-2-quic_varada@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-ipq5424.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c index 92b133baec01f..d5b218b76e291 100644 --- a/drivers/clk/qcom/gcc-ipq5424.c +++ b/drivers/clk/qcom/gcc-ipq5424.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -12,6 +13,7 @@ #include #include +#include #include #include "clk-alpha-pll.h" @@ -3230,6 +3232,20 @@ static const struct qcom_reset_map gcc_ipq5424_resets[] = { [GCC_QUSB2_1_PHY_BCR] = { 0x3C030, 0 }, }; +#define IPQ_APPS_ID 5424 /* some unique value */ + +static const struct qcom_icc_hws_data icc_ipq5424_hws[] = { + { MASTER_ANOC_PCIE0, SLAVE_ANOC_PCIE0, GCC_ANOC_PCIE0_1LANE_M_CLK }, + { MASTER_CNOC_PCIE0, SLAVE_CNOC_PCIE0, GCC_CNOC_PCIE0_1LANE_S_CLK }, + { MASTER_ANOC_PCIE1, SLAVE_ANOC_PCIE1, GCC_ANOC_PCIE1_1LANE_M_CLK }, + { MASTER_CNOC_PCIE1, SLAVE_CNOC_PCIE1, GCC_CNOC_PCIE1_1LANE_S_CLK }, + { MASTER_ANOC_PCIE2, SLAVE_ANOC_PCIE2, GCC_ANOC_PCIE2_2LANE_M_CLK }, + { MASTER_CNOC_PCIE2, SLAVE_CNOC_PCIE2, GCC_CNOC_PCIE2_2LANE_S_CLK }, + { MASTER_ANOC_PCIE3, SLAVE_ANOC_PCIE3, GCC_ANOC_PCIE3_2LANE_M_CLK }, + { MASTER_CNOC_PCIE3, SLAVE_CNOC_PCIE3, GCC_CNOC_PCIE3_2LANE_S_CLK }, + { MASTER_CNOC_USB, SLAVE_CNOC_USB, GCC_CNOC_USB_CLK }, +}; + static const struct of_device_id gcc_ipq5424_match_table[] = { { .compatible = "qcom,ipq5424-gcc" }, { } @@ -3260,6 +3276,8 @@ static const struct qcom_cc_desc gcc_ipq5424_desc = { .num_resets = ARRAY_SIZE(gcc_ipq5424_resets), .clk_hws = gcc_ipq5424_hws, .num_clk_hws = ARRAY_SIZE(gcc_ipq5424_hws), + .icc_hws = icc_ipq5424_hws, + .num_icc_hws = ARRAY_SIZE(icc_ipq5424_hws), }; static int gcc_ipq5424_probe(struct platform_device *pdev) @@ -3272,6 +3290,7 @@ static struct platform_driver gcc_ipq5424_driver = { .driver = { .name = "qcom,gcc-ipq5424", .of_match_table = gcc_ipq5424_match_table, + .sync_state = icc_sync_state, }, }; From 40106d4facbf0bd788126b2b82b25447b1b508d6 Mon Sep 17 00:00:00 2001 From: Daniil Titov Date: Tue, 31 Dec 2024 17:00:49 +0100 Subject: [PATCH 75/81] dt-bindings: clock: qcom,rpmcc: Add MSM8937 compatible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the qcom,rpmcc-msm8937 compatible. Signed-off-by: Daniil Titov Signed-off-by: Barnabás Czémán Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20241231-rpmcc-v1-1-1212df9b2042@mainlining.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml index 02fcffe93f1aa..e58f43b1ab602 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml @@ -33,6 +33,7 @@ properties: - qcom,rpmcc-msm8916 - qcom,rpmcc-msm8917 - qcom,rpmcc-msm8936 + - qcom,rpmcc-msm8937 - qcom,rpmcc-msm8953 - qcom,rpmcc-msm8974 - qcom,rpmcc-msm8976 @@ -110,6 +111,7 @@ allOf: - qcom,rpmcc-msm8916 - qcom,rpmcc-msm8917 - qcom,rpmcc-msm8936 + - qcom,rpmcc-msm8937 - qcom,rpmcc-msm8953 - qcom,rpmcc-msm8974 - qcom,rpmcc-msm8976 From 19024d7c5ddd90afd49b04967c7d922587c91728 Mon Sep 17 00:00:00 2001 From: Daniil Titov Date: Tue, 31 Dec 2024 17:00:50 +0100 Subject: [PATCH 76/81] clk: qcom: smd-rpm: Add clocks for MSM8937 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MSM8937 has mostly the same rpm clocks as MSM8953, but lacks RF_CLK3 and IPA_CLK. Signed-off-by: Daniil Titov Signed-off-by: Barnabás Czémán Link: https://lore.kernel.org/r/20241231-rpmcc-v1-2-1212df9b2042@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-smd-rpm.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index b8cd9f7301194..2d0d450dbd055 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -695,6 +695,32 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8936 = { .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks), }; +static struct clk_smd_rpm *msm8937_clks[] = { + [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, + [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, + [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, + [RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1, + [RPM_SMD_BB_CLK1_A] = &clk_smd_rpm_bb_clk1_a, + [RPM_SMD_BB_CLK2] = &clk_smd_rpm_bb_clk2, + [RPM_SMD_BB_CLK2_A] = &clk_smd_rpm_bb_clk2_a, + [RPM_SMD_RF_CLK2] = &clk_smd_rpm_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &clk_smd_rpm_rf_clk2_a, + [RPM_SMD_DIV_CLK2] = &clk_smd_rpm_div_clk2, + [RPM_SMD_DIV_A_CLK2] = &clk_smd_rpm_div_clk2_a, + [RPM_SMD_BB_CLK1_PIN] = &clk_smd_rpm_bb_clk1_pin, + [RPM_SMD_BB_CLK1_A_PIN] = &clk_smd_rpm_bb_clk1_a_pin, + [RPM_SMD_BB_CLK2_PIN] = &clk_smd_rpm_bb_clk2_pin, + [RPM_SMD_BB_CLK2_A_PIN] = &clk_smd_rpm_bb_clk2_a_pin, +}; + +static const struct rpm_smd_clk_desc rpm_clk_msm8937 = { + .clks = msm8937_clks, + .num_clks = ARRAY_SIZE(msm8937_clks), + .icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks), +}; + static struct clk_smd_rpm *msm8974_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, @@ -1211,6 +1237,7 @@ static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, { .compatible = "qcom,rpmcc-msm8917", .data = &rpm_clk_msm8917 }, { .compatible = "qcom,rpmcc-msm8936", .data = &rpm_clk_msm8936 }, + { .compatible = "qcom,rpmcc-msm8937", .data = &rpm_clk_msm8937 }, { .compatible = "qcom,rpmcc-msm8953", .data = &rpm_clk_msm8953 }, { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 }, { .compatible = "qcom,rpmcc-msm8976", .data = &rpm_clk_msm8976 }, From ec2514d5379ddbe4191f81d99c8fe6a235d0e802 Mon Sep 17 00:00:00 2001 From: Daniil Titov Date: Tue, 31 Dec 2024 17:00:51 +0100 Subject: [PATCH 77/81] dt-bindings: clock: qcom,rpmcc: Add MSM8940 compatible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the qcom,rpmcc-msm8940 compatible. Signed-off-by: Daniil Titov Signed-off-by: Barnabás Czémán Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20241231-rpmcc-v1-3-1212df9b2042@mainlining.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml index e58f43b1ab602..be3835e2e0430 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml @@ -34,6 +34,7 @@ properties: - qcom,rpmcc-msm8917 - qcom,rpmcc-msm8936 - qcom,rpmcc-msm8937 + - qcom,rpmcc-msm8940 - qcom,rpmcc-msm8953 - qcom,rpmcc-msm8974 - qcom,rpmcc-msm8976 @@ -112,6 +113,7 @@ allOf: - qcom,rpmcc-msm8917 - qcom,rpmcc-msm8936 - qcom,rpmcc-msm8937 + - qcom,rpmcc-msm8940 - qcom,rpmcc-msm8953 - qcom,rpmcc-msm8974 - qcom,rpmcc-msm8976 From 0ee878729f0bbe3a206002c02d31e7d964958d8f Mon Sep 17 00:00:00 2001 From: Daniil Titov Date: Tue, 31 Dec 2024 17:00:52 +0100 Subject: [PATCH 78/81] clk: qcom: smd-rpm: Add clocks for MSM8940 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MSM8940 has mostly the same rpm clocks as MSM8953, but lacks RF_CLK3. Signed-off-by: Daniil Titov Signed-off-by: Barnabás Czémán Link: https://lore.kernel.org/r/20241231-rpmcc-v1-4-1212df9b2042@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-smd-rpm.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 2d0d450dbd055..29ef08a9d50b4 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -721,6 +721,34 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8937 = { .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks), }; +static struct clk_smd_rpm *msm8940_clks[] = { + [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, + [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, + [RPM_SMD_IPA_CLK] = &clk_smd_rpm_ipa_clk, + [RPM_SMD_IPA_A_CLK] = &clk_smd_rpm_ipa_a_clk, + [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, + [RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1, + [RPM_SMD_BB_CLK1_A] = &clk_smd_rpm_bb_clk1_a, + [RPM_SMD_BB_CLK2] = &clk_smd_rpm_bb_clk2, + [RPM_SMD_BB_CLK2_A] = &clk_smd_rpm_bb_clk2_a, + [RPM_SMD_RF_CLK2] = &clk_smd_rpm_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &clk_smd_rpm_rf_clk2_a, + [RPM_SMD_DIV_CLK2] = &clk_smd_rpm_div_clk2, + [RPM_SMD_DIV_A_CLK2] = &clk_smd_rpm_div_clk2_a, + [RPM_SMD_BB_CLK1_PIN] = &clk_smd_rpm_bb_clk1_pin, + [RPM_SMD_BB_CLK1_A_PIN] = &clk_smd_rpm_bb_clk1_a_pin, + [RPM_SMD_BB_CLK2_PIN] = &clk_smd_rpm_bb_clk2_pin, + [RPM_SMD_BB_CLK2_A_PIN] = &clk_smd_rpm_bb_clk2_a_pin, +}; + +static const struct rpm_smd_clk_desc rpm_clk_msm8940 = { + .clks = msm8940_clks, + .num_clks = ARRAY_SIZE(msm8940_clks), + .icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks), +}; + static struct clk_smd_rpm *msm8974_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, @@ -1238,6 +1266,7 @@ static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8917", .data = &rpm_clk_msm8917 }, { .compatible = "qcom,rpmcc-msm8936", .data = &rpm_clk_msm8936 }, { .compatible = "qcom,rpmcc-msm8937", .data = &rpm_clk_msm8937 }, + { .compatible = "qcom,rpmcc-msm8940", .data = &rpm_clk_msm8940 }, { .compatible = "qcom,rpmcc-msm8953", .data = &rpm_clk_msm8953 }, { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 }, { .compatible = "qcom,rpmcc-msm8976", .data = &rpm_clk_msm8976 }, From 7ec95ff9abf499b4775148db92528feb4e8ff1ee Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 2 Jan 2025 16:32:07 +0000 Subject: [PATCH 79/81] dt-bindings: clock: move qcom,x1e80100-camcc to its own file Add an x1e80100 camcc binding. x1e80100 has two power-domain parents unlike other similar camcc controllers. Differentiate the new structure into a unique camcc definition. Other similar camcc controller setups can then be easily added to this one. Suggested-by: Krzysztof Kozlowski Reviewed-by: Krzysztof Kozlowski Signed-off-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20250102-b4-linux-next-24-11-18-dtsi-x1e80100-camss-v3-2-cb66d55d20cc@linaro.org Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sm8450-camcc.yaml | 2 - .../bindings/clock/qcom,x1e80100-camcc.yaml | 74 +++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml index 0766f66c7dc4f..b88b6c9b399a4 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml @@ -19,7 +19,6 @@ 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,x1e80100-camcc.h properties: compatible: @@ -29,7 +28,6 @@ properties: - qcom,sm8475-camcc - qcom,sm8550-camcc - qcom,sm8650-camcc - - qcom,x1e80100-camcc clocks: items: diff --git a/Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml new file mode 100644 index 0000000000000..5bbbaa15a2609 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,x1e80100-camcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Camera Clock & Reset Controller on x1e80100 + +maintainers: + - Bryan O'Donoghue + +description: | + Qualcomm camera clock control module provides the clocks, resets and power + domains on x1e80100. + + See also: + include/dt-bindings/clock/qcom,x1e80100-camcc.h + +allOf: + - $ref: qcom,gcc.yaml# + +properties: + compatible: + enum: + - qcom,x1e80100-camcc + + reg: + maxItems: 1 + + clocks: + items: + - description: Camera AHB clock from GCC + - description: Board XO source + - description: Board active XO source + - description: Sleep clock source + + power-domains: + items: + - description: A phandle to the MXC power-domain + - description: A phandle to the MMCX power-domain + + required-opps: + maxItems: 1 + description: + A phandle to an OPP node describing MMCX performance points. + +required: + - compatible + - clocks + - power-domains + - required-opps + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + clock-controller@ade0000 { + compatible = "qcom,x1e80100-camcc"; + reg = <0xade0000 0x20000>; + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&rpmhcc RPMH_CXO_CLK>, + <&rpmhcc RPMH_CXO_CLK_A>, + <&sleep_clk>; + power-domains = <&rpmhpd RPMHPD_MXC>, + <&rpmhpd RPMHPD_MMCX>; + required-opps = <&rpmhpd_opp_low_svs>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; +... From 5e419033b5cb20f9150bfec15dc6cdf10049e654 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Tue, 7 Jan 2025 11:47:28 +0100 Subject: [PATCH 80/81] clk: qcom: Select CLK_X1E80100_GCC in config CLK_X1P42100_GPUCC Commit 99c21c7ca642 ("clk: qcom: Add X1P42100 GPUCC driver") adds the config definition CLK_X1P42100_GPUCC. This config definition selects the non-existing config CLK_X1E8010_GCC. Note that the config for the X1E80100 Global Clock Controller is CLK_X1E80100_GCC. Assuming this was just a minor typo in the number, i.e., 8010 instead of 80100, change the definition to select the existing config CLK_X1E80100_GCC, similarly to the definitions for three configs CLK_X1E80100_{CAMCC,DISPCC,GPUCC}. Fixes: 99c21c7ca642 ("clk: qcom: Add X1P42100 GPUCC driver") Signed-off-by: Lukas Bulwahn Link: https://lore.kernel.org/r/20250107104728.23098-1-lukas.bulwahn@redhat.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index f2e207e36907b..69bbf62ba3cd7 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -67,7 +67,7 @@ config CLK_X1E80100_TCSRCC config CLK_X1P42100_GPUCC tristate "X1P42100 Graphics Clock Controller" depends on ARM64 || COMPILE_TEST - select CLK_X1E8010_GCC + select CLK_X1E80100_GCC help Support for the graphics clock controller on X1P42100 devices. Say Y if you want to support graphics controller devices and From 087b4083d3f9d202266debc6b684b0662c96f51b Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 25 Oct 2024 11:56:20 +0100 Subject: [PATCH 81/81] clk: sunxi-ng: h616: Reparent CPU clock during frequency changes The H616 user manual recommends to re-parent the CPU clock during frequency changes of the PLL, and recommends PLL_PERI0(1X), which runs at 600 MHz. Also it asks to disable and then re-enable the PLL lock bit, after the factor changes have been applied. Add clock notifiers for the PLL and the CPU mux clock, using the existing notifier callbacks, and tell them to use mux 4 (the PLL_PERI0(1X) source), and bit 29 (the LOCK_ENABLE) bit. The existing code already follows the correct algorithms. Signed-off-by: Andre Przywara Link: https://lore.kernel.org/r/20241025105620.1891596-1-andre.przywara@arm.com Tested-by: Evgeny Boger Reviewed-by: Chen-Yu Tsai Signed-off-by: Stephen Boyd --- drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 28 ++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c index b001d0c03534f..6469098d6a2bf 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c @@ -1107,11 +1107,24 @@ static const u32 usb2_clk_regs[] = { SUN50I_H616_USB3_CLK_REG, }; +static struct ccu_mux_nb sun50i_h616_cpu_nb = { + .common = &cpux_clk.common, + .cm = &cpux_clk.mux, + .delay_us = 1, /* manual doesn't really say */ + .bypass_index = 4, /* PLL_PERI0@600MHz, as recommended by manual */ +}; + +static struct ccu_pll_nb sun50i_h616_pll_cpu_nb = { + .common = &pll_cpux_clk.common, + .enable = BIT(29), /* LOCK_ENABLE */ + .lock = BIT(28), +}; + static int sun50i_h616_ccu_probe(struct platform_device *pdev) { void __iomem *reg; u32 val; - int i; + int ret, i; reg = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(reg)) @@ -1166,7 +1179,18 @@ static int sun50i_h616_ccu_probe(struct platform_device *pdev) val |= BIT(24); writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG); - return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h616_ccu_desc); + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h616_ccu_desc); + if (ret) + return ret; + + /* Reparent CPU during CPU PLL rate changes */ + ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, + &sun50i_h616_cpu_nb); + + /* Re-lock the CPU PLL after any rate changes */ + ccu_pll_notifier_register(&sun50i_h616_pll_cpu_nb); + + return 0; } static const struct of_device_id sun50i_h616_ccu_ids[] = {