diff options
Diffstat (limited to 'drivers/clk')
136 files changed, 13817 insertions, 528 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 3c3e0b969020..983ef4f36d8c 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -495,6 +495,7 @@ source "drivers/clk/starfive/Kconfig" source "drivers/clk/sunxi/Kconfig" source "drivers/clk/sunxi-ng/Kconfig" source "drivers/clk/tegra/Kconfig" +source "drivers/clk/thead/Kconfig" source "drivers/clk/stm32/Kconfig" source "drivers/clk/ti/Kconfig" source "drivers/clk/uniphier/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 4abe16c8ccdf..f793a16cad40 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -127,6 +127,7 @@ obj-y += starfive/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-y += sunxi-ng/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ +obj-$(CONFIG_ARCH_THEAD) += thead/ obj-y += ti/ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ obj-$(CONFIG_ARCH_U8500) += ux500/ diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 1bb51a058872..11ae28430dad 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -7,9 +7,6 @@ config QCOM_GDSC bool select PM_GENERIC_DOMAINS if PM -config QCOM_RPMCC - bool - menuconfig COMMON_CLK_QCOM tristate "Support for Qualcomm's clock controllers" depends on OF @@ -17,6 +14,8 @@ menuconfig COMMON_CLK_QCOM select RATIONAL select REGMAP_MMIO select RESET_CONTROLLER + select INTERCONNECT + select INTERCONNECT_CLK if COMMON_CLK_QCOM @@ -65,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_QCM2290_GPUCC + tristate "QCM2290 Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCM_GCC_2290 + help + Support for the graphics clock controller on QCM2290 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config QCOM_A53PLL tristate "MSM8916 A53 PLL" help @@ -113,7 +121,6 @@ config QCOM_CLK_APCS_SDX55 config QCOM_CLK_RPM tristate "RPM based Clock Controller" depends on MFD_QCOM_RPM - select QCOM_RPMCC help The RPM (Resource Power Manager) is a dedicated hardware engine for managing the shared SoC resources in order to keep the lowest power @@ -126,7 +133,6 @@ config QCOM_CLK_RPM config QCOM_CLK_SMD_RPM tristate "RPM over SMD based Clock Controller" depends on QCOM_SMD_RPM - select QCOM_RPMCC help The RPM (Resource Power Manager) is a dedicated hardware engine for managing the shared SoC resources in order to keep the lowest power @@ -249,6 +255,15 @@ config IPQ_GCC_9574 i2c, USB, SD/eMMC, etc. Select this for the root clock of ipq9574. +config IPQ_NSSCC_QCA8K + tristate "QCA8K(QCA8386 or QCA8084) NSS Clock Controller" + depends on MDIO_BUS + help + Support for NSS(Network SubSystem) clock controller on + qca8386/qca8084 chip. + Say Y or M if you want to use network features of switch or + PHY device. Select this for the root clock of qca8k. + config MSM_GCC_8660 tristate "MSM8660 Global Clock Controller" depends on ARM || COMPILE_TEST @@ -803,6 +818,14 @@ config SM_CAMCC_6350 Support for the camera clock controller on SM6350 devices. Say Y if you want to support camera devices and camera functionality. +config SM_CAMCC_7150 + tristate "SM7150 Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select SM_GCC_7150 + help + Support for the camera clock controller on SM7150 devices. + Say Y if you want to support camera devices and camera functionality. + config SM_CAMCC_8250 tristate "SM8250 Camera Clock Controller" depends on ARM64 || COMPILE_TEST @@ -827,6 +850,14 @@ config SM_CAMCC_8550 Support for the camera clock controller on SM8550 devices. Say Y if you want to support camera devices and camera functionality. +config SM_CAMCC_8650 + tristate "SM8650 Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select SM_GCC_8650 + help + Support for the camera clock controller on SM8650 devices. + Say Y if you want to support camera devices and camera functionality. + config SM_DISPCC_6115 tristate "SM6115 Display Clock Controller" depends on ARM64 || COMPILE_TEST @@ -847,6 +878,16 @@ config SM_DISPCC_6125 Say Y if you want to support display devices and functionality such as splash screen +config SM_DISPCC_7150 + tristate "SM7150 Display Clock Controller" + depends on ARM64 || COMPILE_TEST + depends on SM_GCC_7150 + help + Support for the display clock controller on Qualcomm Technologies, Inc + SM7150 devices. + Say Y if you want to support display devices and functionality such as + splash screen. + config SM_DISPCC_8250 tristate "SM8150/SM8250/SM8350 Display Clock Controller" depends on ARM64 || COMPILE_TEST @@ -953,6 +994,7 @@ config SM_GCC_6375 config SM_GCC_7150 tristate "SM7150 Global Clock Controller" + depends on ARM64 || COMPILE_TEST select QCOM_GDSC help Support for the global clock controller on SM7150 devices. @@ -1118,6 +1160,16 @@ 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_VIDEOCC_7150 + tristate "SM7150 Video Clock Controller" + depends on ARM64 || COMPILE_TEST + select SM_GCC_7150 + select QCOM_GDSC + help + Support for the video clock controller on SM7150 devices. + Say Y if you want to support video devices and functionality such as + video encode and decode. + config SM_VIDEOCC_8150 tristate "SM8150 Video Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index dec5b6db6860..0de5fce6113a 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_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_GCC_4019) += gcc-ipq4019.o @@ -36,6 +37,7 @@ obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o obj-$(CONFIG_IPQ_GCC_9574) += gcc-ipq9574.o obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o +obj-$(CONFIG_IPQ_NSSCC_QCA8K) += nsscc-qca8k.o obj-$(CONFIG_MDM_GCC_9607) += gcc-mdm9607.o obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o @@ -106,13 +108,16 @@ obj-$(CONFIG_SDX_GCC_55) += gcc-sdx55.o obj-$(CONFIG_SDX_GCC_65) += gcc-sdx65.o obj-$(CONFIG_SDX_GCC_75) += gcc-sdx75.o obj-$(CONFIG_SM_CAMCC_6350) += camcc-sm6350.o +obj-$(CONFIG_SM_CAMCC_7150) += camcc-sm7150.o obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o obj-$(CONFIG_SM_CAMCC_8450) += camcc-sm8450.o obj-$(CONFIG_SM_CAMCC_8550) += camcc-sm8550.o +obj-$(CONFIG_SM_CAMCC_8650) += camcc-sm8650.o obj-$(CONFIG_SM_DISPCC_6115) += dispcc-sm6115.o obj-$(CONFIG_SM_DISPCC_6125) += dispcc-sm6125.o obj-$(CONFIG_SM_DISPCC_6350) += dispcc-sm6350.o obj-$(CONFIG_SM_DISPCC_6375) += dispcc-sm6375.o +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 @@ -141,6 +146,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_VIDEOCC_7150) += videocc-sm7150.o obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o obj-$(CONFIG_SM_VIDEOCC_8250) += videocc-sm8250.o obj-$(CONFIG_SM_VIDEOCC_8350) += videocc-sm8350.o diff --git a/drivers/clk/qcom/apss-ipq6018.c b/drivers/clk/qcom/apss-ipq6018.c index e6295b832686..c89d126ebac3 100644 --- a/drivers/clk/qcom/apss-ipq6018.c +++ b/drivers/clk/qcom/apss-ipq6018.c @@ -123,7 +123,7 @@ static int apss_ipq6018_probe(struct platform_device *pdev) if (!regmap) return -ENODEV; - ret = qcom_cc_really_probe(pdev, &apss_ipq6018_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &apss_ipq6018_desc, regmap); if (ret) return ret; diff --git a/drivers/clk/qcom/camcc-sc7180.c b/drivers/clk/qcom/camcc-sc7180.c index a78808b22b03..10e924cd533d 100644 --- a/drivers/clk/qcom/camcc-sc7180.c +++ b/drivers/clk/qcom/camcc-sc7180.c @@ -1680,7 +1680,7 @@ static int cam_cc_sc7180_probe(struct platform_device *pdev) clk_agera_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config); clk_fabia_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config); - ret = qcom_cc_really_probe(pdev, &cam_cc_sc7180_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_sc7180_desc, regmap); pm_runtime_put(&pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "Failed to register CAM CC clocks\n"); diff --git a/drivers/clk/qcom/camcc-sc7280.c b/drivers/clk/qcom/camcc-sc7280.c index d89ddb2298e3..accd257632df 100644 --- a/drivers/clk/qcom/camcc-sc7280.c +++ b/drivers/clk/qcom/camcc-sc7280.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/clk-provider.h> @@ -2247,6 +2248,9 @@ static struct clk_branch cam_cc_sleep_clk = { static struct gdsc cam_cc_titan_top_gdsc = { .gdscr = 0xc194, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "cam_cc_titan_top_gdsc", }, @@ -2256,46 +2260,66 @@ static struct gdsc cam_cc_titan_top_gdsc = { static struct gdsc cam_cc_bps_gdsc = { .gdscr = 0x7004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "cam_cc_bps_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = HW_CTRL | RETAIN_FF_ENABLE, }; static struct gdsc cam_cc_ife_0_gdsc = { .gdscr = 0xa004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "cam_cc_ife_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = RETAIN_FF_ENABLE, }; static struct gdsc cam_cc_ife_1_gdsc = { .gdscr = 0xb004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "cam_cc_ife_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = RETAIN_FF_ENABLE, }; static struct gdsc cam_cc_ife_2_gdsc = { .gdscr = 0xb070, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "cam_cc_ife_2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = RETAIN_FF_ENABLE, }; static struct gdsc cam_cc_ipe_0_gdsc = { .gdscr = 0x8004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "cam_cc_ipe_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = HW_CTRL | RETAIN_FF_ENABLE, }; @@ -2457,7 +2481,7 @@ static int cam_cc_sc7280_probe(struct platform_device *pdev) clk_lucid_pll_configure(&cam_cc_pll5, regmap, &cam_cc_pll5_config); clk_lucid_pll_configure(&cam_cc_pll6, regmap, &cam_cc_pll6_config); - return qcom_cc_really_probe(pdev, &cam_cc_sc7280_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &cam_cc_sc7280_desc, regmap); } static struct platform_driver cam_cc_sc7280_driver = { diff --git a/drivers/clk/qcom/camcc-sc8280xp.c b/drivers/clk/qcom/camcc-sc8280xp.c index 8e26ec2def73..479964f91608 100644 --- a/drivers/clk/qcom/camcc-sc8280xp.c +++ b/drivers/clk/qcom/camcc-sc8280xp.c @@ -45,11 +45,11 @@ enum { P_SLEEP_CLK, }; -static struct pll_vco lucid_vco[] = { +static const struct pll_vco lucid_vco[] = { { 249600000, 1800000000, 0 }, }; -static struct pll_vco zonda_vco[] = { +static const struct pll_vco zonda_vco[] = { { 595200000, 3600000000, 0 }, }; @@ -3034,7 +3034,7 @@ static int camcc_sc8280xp_probe(struct platform_device *pdev) /* Keep some clocks always-on */ qcom_branch_set_clk_en(regmap, 0xc1e4); /* CAMCC_GDSC_CLK */ - ret = qcom_cc_really_probe(pdev, &camcc_sc8280xp_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &camcc_sc8280xp_desc, regmap); if (ret) goto err_disable; diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c index 8466d03e0d05..40022a10f8c0 100644 --- a/drivers/clk/qcom/camcc-sdm845.c +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -1735,7 +1735,7 @@ static int cam_cc_sdm845_probe(struct platform_device *pdev) cam_cc_pll_config.l = 0x14; clk_fabia_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll_config); - return qcom_cc_really_probe(pdev, &cam_cc_sdm845_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &cam_cc_sdm845_desc, regmap); } static struct platform_driver cam_cc_sdm845_driver = { diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c index e4e7b308ecf1..f6634cc8663e 100644 --- a/drivers/clk/qcom/camcc-sm6350.c +++ b/drivers/clk/qcom/camcc-sm6350.c @@ -32,7 +32,7 @@ enum { P_CAMCC_PLL3_OUT_MAIN, }; -static struct pll_vco fabia_vco[] = { +static const struct pll_vco fabia_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -1879,7 +1879,7 @@ static int camcc_sm6350_probe(struct platform_device *pdev) clk_agera_pll_configure(&camcc_pll2, regmap, &camcc_pll2_config); clk_fabia_pll_configure(&camcc_pll3, regmap, &camcc_pll3_config); - return qcom_cc_really_probe(pdev, &camcc_sm6350_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &camcc_sm6350_desc, regmap); } static struct platform_driver camcc_sm6350_driver = { diff --git a/drivers/clk/qcom/camcc-sm7150.c b/drivers/clk/qcom/camcc-sm7150.c new file mode 100644 index 000000000000..39033a6bb616 --- /dev/null +++ b/drivers/clk/qcom/camcc-sm7150.c @@ -0,0 +1,2061 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018, 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com> + */ + +#include <linux/clk-provider.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,sm7150-camcc.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_CHIP_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_BI_TCXO_MX, + P_CAMCC_PLL0_OUT_EVEN, + P_CAMCC_PLL0_OUT_MAIN, + P_CAMCC_PLL0_OUT_ODD, + P_CAMCC_PLL1_OUT_EVEN, + P_CAMCC_PLL2_OUT_AUX, + P_CAMCC_PLL2_OUT_EARLY, + P_CAMCC_PLL2_OUT_MAIN, + P_CAMCC_PLL3_OUT_EVEN, + P_CAMCC_PLL4_OUT_EVEN, + P_CHIP_SLEEP_CLK, +}; + +static const struct pll_vco fabia_vco[] = { + { 249600000, 2000000000, 0 }, +}; + +/* 1200MHz configuration */ +static const struct alpha_pll_config camcc_pll0_config = { + .l = 0x3e, + .alpha = 0x8000, + .post_div_mask = 0xff << 8, + .post_div_val = 0x31 << 8, + .test_ctl_val = 0x40000000, +}; + +static struct clk_alpha_pll camcc_pll0 = { + .offset = 0x0, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "camcc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_fixed_factor camcc_pll0_out_even = { + .mult = 1, + .div = 2, + .hw.init = &(const struct clk_init_data) { + .name = "camcc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &camcc_pll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_fixed_factor camcc_pll0_out_odd = { + .mult = 1, + .div = 3, + .hw.init = &(const struct clk_init_data) { + .name = "camcc_pll0_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &camcc_pll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +/* 680MHz configuration */ +static const struct alpha_pll_config camcc_pll1_config = { + .l = 0x23, + .alpha = 0x6aaa, + .post_div_mask = 0xf << 8, + .post_div_val = 0x1 << 8, + .test_ctl_val = 0x40000000, +}; + +static struct clk_alpha_pll camcc_pll1 = { + .offset = 0x1000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "camcc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_fixed_factor camcc_pll1_out_even = { + .mult = 1, + .div = 2, + .hw.init = &(const struct clk_init_data) { + .name = "camcc_pll1_out_even", + .parent_hws = (const struct clk_hw*[]) { + &camcc_pll1.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, +}; + +/* 1920MHz configuration */ +static const struct alpha_pll_config camcc_pll2_config = { + .l = 0x64, + .post_div_val = 0x3 << 8, + .post_div_mask = 0x3 << 8, + .early_output_mask = BIT(3), + .aux_output_mask = BIT(1), + .main_output_mask = BIT(0), + .config_ctl_hi_val = 0x400003d6, + .config_ctl_val = 0x20000954, +}; + +static struct clk_alpha_pll camcc_pll2 = { + .offset = 0x2000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "camcc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_agera_ops, + }, + }, +}; + +static struct clk_fixed_factor camcc_pll2_out_early = { + .mult = 1, + .div = 2, + .hw.init = &(const struct clk_init_data) { + .name = "camcc_pll2_out_early", + .parent_hws = (const struct clk_hw*[]) { + &camcc_pll2.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll_postdiv camcc_pll2_out_aux = { + .offset = 0x2000, + .post_div_shift = 8, + .width = 2, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_pll2_out_aux", + .parent_hws = (const struct clk_hw*[]) { + &camcc_pll2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static struct clk_alpha_pll_postdiv camcc_pll2_out_main = { + .offset = 0x2000, + .post_div_shift = 8, + .width = 2, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_pll2_out_main", + .parent_hws = (const struct clk_hw*[]) { + &camcc_pll2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +/* 760MHz configuration */ +static const struct alpha_pll_config camcc_pll3_config = { + .l = 0x27, + .alpha = 0x9555, + .post_div_mask = 0xf << 8, + .post_div_val = 0x1 << 8, + .test_ctl_val = 0x40000000, +}; + +static struct clk_alpha_pll camcc_pll3 = { + .offset = 0x3000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "camcc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_fixed_factor camcc_pll3_out_even = { + .mult = 1, + .div = 2, + .hw.init = &(const struct clk_init_data) { + .name = "camcc_pll3_out_even", + .parent_hws = (const struct clk_hw*[]) { + &camcc_pll3.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll camcc_pll4 = { + .offset = 0x4000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "camcc_pll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_fixed_factor camcc_pll4_out_even = { + .mult = 1, + .div = 2, + .hw.init = &(const struct clk_init_data) { + .name = "camcc_pll4_out_even", + .parent_hws = (const struct clk_hw*[]) { + &camcc_pll4.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, +}; + +static const struct parent_map camcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAMCC_PLL0_OUT_MAIN, 1 }, + { P_CAMCC_PLL0_OUT_EVEN, 2 }, + { P_CAMCC_PLL0_OUT_ODD, 3 }, + { P_CAMCC_PLL2_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data camcc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &camcc_pll0.clkr.hw }, + { .hw = &camcc_pll0_out_even.hw }, + { .hw = &camcc_pll0_out_odd.hw }, + { .hw = &camcc_pll2_out_main.clkr.hw }, +}; + +static const struct parent_map camcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_CAMCC_PLL0_OUT_MAIN, 1 }, + { P_CAMCC_PLL0_OUT_EVEN, 2 }, + { P_CAMCC_PLL0_OUT_ODD, 3 }, + { P_CAMCC_PLL1_OUT_EVEN, 4 }, + { P_CAMCC_PLL2_OUT_EARLY, 5 }, +}; + +static const struct clk_parent_data camcc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &camcc_pll0.clkr.hw }, + { .hw = &camcc_pll0_out_even.hw }, + { .hw = &camcc_pll0_out_odd.hw }, + { .hw = &camcc_pll1_out_even.hw }, + { .hw = &camcc_pll2_out_early.hw }, +}; + +static const struct parent_map camcc_parent_map_2[] = { + { P_BI_TCXO_MX, 0 }, + { P_CAMCC_PLL2_OUT_AUX, 5 }, +}; + +static const struct clk_parent_data camcc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &camcc_pll2_out_aux.clkr.hw }, +}; + +static const struct parent_map camcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_CAMCC_PLL0_OUT_MAIN, 1 }, + { P_CAMCC_PLL0_OUT_EVEN, 2 }, + { P_CAMCC_PLL0_OUT_ODD, 3 }, + { P_CAMCC_PLL2_OUT_EARLY, 5 }, + { P_CAMCC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data camcc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &camcc_pll0.clkr.hw }, + { .hw = &camcc_pll0_out_even.hw }, + { .hw = &camcc_pll0_out_odd.hw }, + { .hw = &camcc_pll2_out_early.hw }, + { .hw = &camcc_pll4_out_even.hw }, +}; + +static const struct parent_map camcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_CAMCC_PLL3_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data camcc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &camcc_pll3_out_even.hw }, +}; + +static const struct parent_map camcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_CAMCC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data camcc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &camcc_pll4_out_even.hw }, +}; + +static const struct parent_map camcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_CAMCC_PLL1_OUT_EVEN, 4 }, +}; + +static const struct clk_parent_data camcc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &camcc_pll1_out_even.hw }, +}; + +static const struct parent_map camcc_parent_map_7[] = { + { P_CHIP_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data camcc_parent_data_7[] = { + { .index = DT_CHIP_SLEEP_CLK }, +}; + +static const struct parent_map camcc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_CAMCC_PLL0_OUT_ODD, 3 }, +}; + +static const struct clk_parent_data camcc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &camcc_pll0_out_odd.hw }, +}; + +static const struct parent_map camcc_parent_map_9[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data camcc_parent_data_9[] = { + { .index = DT_BI_TCXO_AO }, +}; + +static const struct freq_tbl ftbl_camcc_bps_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAMCC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAMCC_PLL0_OUT_ODD, 2, 0, 0), + F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAMCC_PLL2_OUT_MAIN, 1, 0, 0), + F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_bps_clk_src = { + .cmd_rcgr = 0x7010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_bps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_bps_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_camnoc_axi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(150000000, P_CAMCC_PLL0_OUT_EVEN, 4, 0, 0), + F(240000000, P_CAMCC_PLL2_OUT_MAIN, 2, 0, 0), + F(320000000, P_CAMCC_PLL2_OUT_MAIN, 1.5, 0, 0), + F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0), + F(480000000, P_CAMCC_PLL2_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_camnoc_axi_clk_src = { + .cmd_rcgr = 0xc12c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_camnoc_axi_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_camnoc_axi_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_cci_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_CAMCC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_cci_0_clk_src = { + .cmd_rcgr = 0xc0c4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_cci_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_cci_0_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 camcc_cci_1_clk_src = { + .cmd_rcgr = 0xc0e0, + .mnd_width = 8, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_cci_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_cci_1_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_cphy_rx_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0), + F(384000000, P_CAMCC_PLL2_OUT_EARLY, 2.5, 0, 0), + F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_cphy_rx_clk_src = { + .cmd_rcgr = 0xa064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_1, + .freq_tbl = ftbl_camcc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_cphy_rx_clk_src", + .parent_data = camcc_parent_data_1, + .num_parents = ARRAY_SIZE(camcc_parent_data_1), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_csi0phytimer_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x6004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_csi0phytimer_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 camcc_csi1phytimer_clk_src = { + .cmd_rcgr = 0x6028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_csi1phytimer_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 camcc_csi2phytimer_clk_src = { + .cmd_rcgr = 0x604c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_csi2phytimer_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 camcc_csi3phytimer_clk_src = { + .cmd_rcgr = 0x6070, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_csi3phytimer_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_fast_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(50000000, P_CAMCC_PLL0_OUT_EVEN, 12, 0, 0), + F(100000000, P_CAMCC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAMCC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAMCC_PLL0_OUT_MAIN, 4, 0, 0), + F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_fast_ahb_clk_src = { + .cmd_rcgr = 0x703c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_fast_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_fast_ahb_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_fd_core_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(380000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0), + F(384000000, P_CAMCC_PLL2_OUT_EARLY, 2.5, 0, 0), + F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0), + F(480000000, P_CAMCC_PLL2_OUT_EARLY, 2, 0, 0), + F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_fd_core_clk_src = { + .cmd_rcgr = 0xc09c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_3, + .freq_tbl = ftbl_camcc_fd_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_fd_core_clk_src", + .parent_data = camcc_parent_data_3, + .num_parents = ARRAY_SIZE(camcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_icp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0), + F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_icp_clk_src = { + .cmd_rcgr = 0xc074, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_icp_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_icp_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_ife_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(380000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0), + F(510000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0), + F(637000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0), + F(760000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_ife_0_clk_src = { + .cmd_rcgr = 0xa010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_4, + .freq_tbl = ftbl_camcc_ife_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_0_clk_src", + .parent_data = camcc_parent_data_4, + .num_parents = ARRAY_SIZE(camcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_ife_0_csid_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(75000000, P_CAMCC_PLL0_OUT_EVEN, 8, 0, 0), + F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0), + F(384000000, P_CAMCC_PLL2_OUT_EARLY, 2.5, 0, 0), + F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_ife_0_csid_clk_src = { + .cmd_rcgr = 0xa03c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_1, + .freq_tbl = ftbl_camcc_ife_0_csid_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_0_csid_clk_src", + .parent_data = camcc_parent_data_1, + .num_parents = ARRAY_SIZE(camcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_ife_1_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(380000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0), + F(510000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0), + F(637000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0), + F(760000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_ife_1_clk_src = { + .cmd_rcgr = 0xb010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_5, + .freq_tbl = ftbl_camcc_ife_1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_1_clk_src", + .parent_data = camcc_parent_data_5, + .num_parents = ARRAY_SIZE(camcc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 camcc_ife_1_csid_clk_src = { + .cmd_rcgr = 0xb034, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_1, + .freq_tbl = ftbl_camcc_ife_0_csid_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_1_csid_clk_src", + .parent_data = camcc_parent_data_1, + .num_parents = ARRAY_SIZE(camcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_ife_lite_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(320000000, P_CAMCC_PLL2_OUT_MAIN, 1.5, 0, 0), + F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAMCC_PLL2_OUT_MAIN, 1, 0, 0), + F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_ife_lite_clk_src = { + .cmd_rcgr = 0xc004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_ife_lite_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_lite_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 camcc_ife_lite_csid_clk_src = { + .cmd_rcgr = 0xc020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_1, + .freq_tbl = ftbl_camcc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_lite_csid_clk_src", + .parent_data = camcc_parent_data_1, + .num_parents = ARRAY_SIZE(camcc_parent_data_1), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_ipe_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(340000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0), + F(430000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0), + F(520000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_ipe_0_clk_src = { + .cmd_rcgr = 0x8010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_6, + .freq_tbl = ftbl_camcc_ipe_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_ipe_0_clk_src", + .parent_data = camcc_parent_data_6, + .num_parents = ARRAY_SIZE(camcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 camcc_jpeg_clk_src = { + .cmd_rcgr = 0xc048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_bps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_jpeg_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_lrme_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAMCC_PLL0_OUT_EVEN, 6, 0, 0), + F(240000000, P_CAMCC_PLL2_OUT_MAIN, 2, 0, 0), + F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0), + F(320000000, P_CAMCC_PLL2_OUT_MAIN, 1.5, 0, 0), + F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_lrme_clk_src = { + .cmd_rcgr = 0xc100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_0, + .freq_tbl = ftbl_camcc_lrme_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_lrme_clk_src", + .parent_data = camcc_parent_data_0, + .num_parents = ARRAY_SIZE(camcc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_mclk0_clk_src[] = { + F(19200000, P_BI_TCXO_MX, 1, 0, 0), + F(24000000, P_CAMCC_PLL2_OUT_AUX, 1, 1, 20), + F(34285714, P_CAMCC_PLL2_OUT_AUX, 14, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_mclk0_clk_src = { + .cmd_rcgr = 0x5004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = camcc_parent_map_2, + .freq_tbl = ftbl_camcc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_mclk0_clk_src", + .parent_data = camcc_parent_data_2, + .num_parents = ARRAY_SIZE(camcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 camcc_mclk1_clk_src = { + .cmd_rcgr = 0x5024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = camcc_parent_map_2, + .freq_tbl = ftbl_camcc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_mclk1_clk_src", + .parent_data = camcc_parent_data_2, + .num_parents = ARRAY_SIZE(camcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 camcc_mclk2_clk_src = { + .cmd_rcgr = 0x5044, + .mnd_width = 8, + .hid_width = 5, + .parent_map = camcc_parent_map_2, + .freq_tbl = ftbl_camcc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_mclk2_clk_src", + .parent_data = camcc_parent_data_2, + .num_parents = ARRAY_SIZE(camcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 camcc_mclk3_clk_src = { + .cmd_rcgr = 0x5064, + .mnd_width = 8, + .hid_width = 5, + .parent_map = camcc_parent_map_2, + .freq_tbl = ftbl_camcc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_mclk3_clk_src", + .parent_data = camcc_parent_data_2, + .num_parents = ARRAY_SIZE(camcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_sleep_clk_src[] = { + F(32000, P_CHIP_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_sleep_clk_src = { + .cmd_rcgr = 0xc1a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_7, + .freq_tbl = ftbl_camcc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_sleep_clk_src", + .parent_data = camcc_parent_data_7, + .num_parents = ARRAY_SIZE(camcc_parent_data_7), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_slow_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(80000000, P_CAMCC_PLL0_OUT_ODD, 5, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_slow_ahb_clk_src = { + .cmd_rcgr = 0x7058, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_8, + .freq_tbl = ftbl_camcc_slow_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_slow_ahb_clk_src", + .parent_data = camcc_parent_data_8, + .num_parents = ARRAY_SIZE(camcc_parent_data_8), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_camcc_xo_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 camcc_xo_clk_src = { + .cmd_rcgr = 0xc188, + .mnd_width = 0, + .hid_width = 5, + .parent_map = camcc_parent_map_9, + .freq_tbl = ftbl_camcc_xo_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "camcc_xo_clk_src", + .parent_data = camcc_parent_data_9, + .num_parents = ARRAY_SIZE(camcc_parent_data_9), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch camcc_bps_ahb_clk = { + .halt_reg = 0x7070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_bps_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_bps_areg_clk = { + .halt_reg = 0x7054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_bps_areg_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_bps_axi_clk = { + .halt_reg = 0x7038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_bps_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_camnoc_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_bps_clk = { + .halt_reg = 0x7028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_bps_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_bps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_camnoc_axi_clk = { + .halt_reg = 0xc148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc148, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_camnoc_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_camnoc_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_camnoc_dcd_xo_clk = { + .halt_reg = 0xc150, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc150, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_camnoc_dcd_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_cci_0_clk = { + .halt_reg = 0xc0dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc0dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_cci_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_cci_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_cci_1_clk = { + .halt_reg = 0xc0f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc0f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_cci_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_cci_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_core_ahb_clk = { + .halt_reg = 0xc184, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xc184, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_core_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_cpas_ahb_clk = { + .halt_reg = 0xc124, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc124, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_cpas_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_csi0phytimer_clk = { + .halt_reg = 0x601c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x601c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_csi0phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_csi0phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_csi1phytimer_clk = { + .halt_reg = 0x6040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_csi1phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_csi1phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_csi2phytimer_clk = { + .halt_reg = 0x6064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_csi2phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_csi2phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_csi3phytimer_clk = { + .halt_reg = 0x6088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_csi3phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_csi3phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_csiphy0_clk = { + .halt_reg = 0x6020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_csiphy0_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_csiphy1_clk = { + .halt_reg = 0x6044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_csiphy1_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_csiphy2_clk = { + .halt_reg = 0x6068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_csiphy2_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_csiphy3_clk = { + .halt_reg = 0x608c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x608c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_csiphy3_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_fd_core_clk = { + .halt_reg = 0xc0b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc0b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_fd_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_fd_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_fd_core_uar_clk = { + .halt_reg = 0xc0bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc0bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_fd_core_uar_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_fd_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_icp_ahb_clk = { + .halt_reg = 0xc094, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc094, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_icp_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_icp_clk = { + .halt_reg = 0xc08c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc08c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_icp_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_icp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_0_axi_clk = { + .halt_reg = 0xa080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_0_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_camnoc_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_0_clk = { + .halt_reg = 0xa028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_0_cphy_rx_clk = { + .halt_reg = 0xa07c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa07c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_0_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_0_csid_clk = { + .halt_reg = 0xa054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_0_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_ife_0_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_0_dsp_clk = { + .halt_reg = 0xa038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_0_dsp_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_1_axi_clk = { + .halt_reg = 0xb058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_1_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_camnoc_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_1_clk = { + .halt_reg = 0xb028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_ife_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_1_cphy_rx_clk = { + .halt_reg = 0xb054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_1_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_1_csid_clk = { + .halt_reg = 0xb04c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb04c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_1_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_ife_1_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_1_dsp_clk = { + .halt_reg = 0xb030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_1_dsp_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_ife_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_lite_clk = { + .halt_reg = 0xc01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc01c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_ife_lite_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_lite_cphy_rx_clk = { + .halt_reg = 0xc040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_lite_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ife_lite_csid_clk = { + .halt_reg = 0xc038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ife_lite_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_ife_lite_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ipe_0_ahb_clk = { + .halt_reg = 0x8040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ipe_0_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ipe_0_areg_clk = { + .halt_reg = 0x803c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x803c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ipe_0_areg_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ipe_0_axi_clk = { + .halt_reg = 0x8038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ipe_0_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_camnoc_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ipe_0_clk = { + .halt_reg = 0x8028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ipe_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_ipe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ipe_1_ahb_clk = { + .halt_reg = 0x9028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ipe_1_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ipe_1_areg_clk = { + .halt_reg = 0x9024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ipe_1_areg_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ipe_1_axi_clk = { + .halt_reg = 0x9020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ipe_1_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_camnoc_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_ipe_1_clk = { + .halt_reg = 0x9010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_ipe_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_ipe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_jpeg_clk = { + .halt_reg = 0xc060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_jpeg_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_jpeg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_lrme_clk = { + .halt_reg = 0xc118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_lrme_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_lrme_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_mclk0_clk = { + .halt_reg = 0x501c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x501c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_mclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_mclk1_clk = { + .halt_reg = 0x503c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x503c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_mclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_mclk2_clk = { + .halt_reg = 0x505c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x505c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_mclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_mclk3_clk = { + .halt_reg = 0x507c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x507c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_mclk3_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camcc_sleep_clk = { + .halt_reg = 0xc1bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc1bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "camcc_sleep_clk", + .parent_hws = (const struct clk_hw*[]) { + &camcc_sleep_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc camcc_titan_top_gdsc; + +static struct gdsc camcc_bps_gdsc = { + .gdscr = 0x7004, + .pd = { + .name = "camcc_bps_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camcc_ife_0_gdsc = { + .gdscr = 0xa004, + .pd = { + .name = "camcc_ife_0_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .parent = &camcc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camcc_ife_1_gdsc = { + .gdscr = 0xb004, + .pd = { + .name = "camcc_ife_1_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .parent = &camcc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camcc_ipe_0_gdsc = { + .gdscr = 0x8004, + .pd = { + .name = "camcc_ipe_0_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camcc_ipe_1_gdsc = { + .gdscr = 0x9004, + .pd = { + .name = "camcc_ipe_1_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camcc_titan_top_gdsc = { + .gdscr = 0xc1c4, + .pd = { + .name = "camcc_titan_top_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +struct clk_hw *camcc_sm7150_hws[] = { + [CAMCC_PLL0_OUT_EVEN] = &camcc_pll0_out_even.hw, + [CAMCC_PLL0_OUT_ODD] = &camcc_pll0_out_odd.hw, + [CAMCC_PLL1_OUT_EVEN] = &camcc_pll1_out_even.hw, + [CAMCC_PLL2_OUT_EARLY] = &camcc_pll2_out_early.hw, + [CAMCC_PLL3_OUT_EVEN] = &camcc_pll3_out_even.hw, + [CAMCC_PLL4_OUT_EVEN] = &camcc_pll4_out_even.hw, +}; + +static struct clk_regmap *camcc_sm7150_clocks[] = { + [CAMCC_BPS_AHB_CLK] = &camcc_bps_ahb_clk.clkr, + [CAMCC_BPS_AREG_CLK] = &camcc_bps_areg_clk.clkr, + [CAMCC_BPS_AXI_CLK] = &camcc_bps_axi_clk.clkr, + [CAMCC_BPS_CLK] = &camcc_bps_clk.clkr, + [CAMCC_BPS_CLK_SRC] = &camcc_bps_clk_src.clkr, + [CAMCC_CAMNOC_AXI_CLK] = &camcc_camnoc_axi_clk.clkr, + [CAMCC_CAMNOC_AXI_CLK_SRC] = &camcc_camnoc_axi_clk_src.clkr, + [CAMCC_CAMNOC_DCD_XO_CLK] = &camcc_camnoc_dcd_xo_clk.clkr, + [CAMCC_CCI_0_CLK] = &camcc_cci_0_clk.clkr, + [CAMCC_CCI_0_CLK_SRC] = &camcc_cci_0_clk_src.clkr, + [CAMCC_CCI_1_CLK] = &camcc_cci_1_clk.clkr, + [CAMCC_CCI_1_CLK_SRC] = &camcc_cci_1_clk_src.clkr, + [CAMCC_CORE_AHB_CLK] = &camcc_core_ahb_clk.clkr, + [CAMCC_CPAS_AHB_CLK] = &camcc_cpas_ahb_clk.clkr, + [CAMCC_CPHY_RX_CLK_SRC] = &camcc_cphy_rx_clk_src.clkr, + [CAMCC_CSI0PHYTIMER_CLK] = &camcc_csi0phytimer_clk.clkr, + [CAMCC_CSI0PHYTIMER_CLK_SRC] = &camcc_csi0phytimer_clk_src.clkr, + [CAMCC_CSI1PHYTIMER_CLK] = &camcc_csi1phytimer_clk.clkr, + [CAMCC_CSI1PHYTIMER_CLK_SRC] = &camcc_csi1phytimer_clk_src.clkr, + [CAMCC_CSI2PHYTIMER_CLK] = &camcc_csi2phytimer_clk.clkr, + [CAMCC_CSI2PHYTIMER_CLK_SRC] = &camcc_csi2phytimer_clk_src.clkr, + [CAMCC_CSI3PHYTIMER_CLK] = &camcc_csi3phytimer_clk.clkr, + [CAMCC_CSI3PHYTIMER_CLK_SRC] = &camcc_csi3phytimer_clk_src.clkr, + [CAMCC_CSIPHY0_CLK] = &camcc_csiphy0_clk.clkr, + [CAMCC_CSIPHY1_CLK] = &camcc_csiphy1_clk.clkr, + [CAMCC_CSIPHY2_CLK] = &camcc_csiphy2_clk.clkr, + [CAMCC_CSIPHY3_CLK] = &camcc_csiphy3_clk.clkr, + [CAMCC_FAST_AHB_CLK_SRC] = &camcc_fast_ahb_clk_src.clkr, + [CAMCC_FD_CORE_CLK] = &camcc_fd_core_clk.clkr, + [CAMCC_FD_CORE_CLK_SRC] = &camcc_fd_core_clk_src.clkr, + [CAMCC_FD_CORE_UAR_CLK] = &camcc_fd_core_uar_clk.clkr, + [CAMCC_ICP_AHB_CLK] = &camcc_icp_ahb_clk.clkr, + [CAMCC_ICP_CLK] = &camcc_icp_clk.clkr, + [CAMCC_ICP_CLK_SRC] = &camcc_icp_clk_src.clkr, + [CAMCC_IFE_0_AXI_CLK] = &camcc_ife_0_axi_clk.clkr, + [CAMCC_IFE_0_CLK] = &camcc_ife_0_clk.clkr, + [CAMCC_IFE_0_CLK_SRC] = &camcc_ife_0_clk_src.clkr, + [CAMCC_IFE_0_CPHY_RX_CLK] = &camcc_ife_0_cphy_rx_clk.clkr, + [CAMCC_IFE_0_CSID_CLK] = &camcc_ife_0_csid_clk.clkr, + [CAMCC_IFE_0_CSID_CLK_SRC] = &camcc_ife_0_csid_clk_src.clkr, + [CAMCC_IFE_0_DSP_CLK] = &camcc_ife_0_dsp_clk.clkr, + [CAMCC_IFE_1_AXI_CLK] = &camcc_ife_1_axi_clk.clkr, + [CAMCC_IFE_1_CLK] = &camcc_ife_1_clk.clkr, + [CAMCC_IFE_1_CLK_SRC] = &camcc_ife_1_clk_src.clkr, + [CAMCC_IFE_1_CPHY_RX_CLK] = &camcc_ife_1_cphy_rx_clk.clkr, + [CAMCC_IFE_1_CSID_CLK] = &camcc_ife_1_csid_clk.clkr, + [CAMCC_IFE_1_CSID_CLK_SRC] = &camcc_ife_1_csid_clk_src.clkr, + [CAMCC_IFE_1_DSP_CLK] = &camcc_ife_1_dsp_clk.clkr, + [CAMCC_IFE_LITE_CLK] = &camcc_ife_lite_clk.clkr, + [CAMCC_IFE_LITE_CLK_SRC] = &camcc_ife_lite_clk_src.clkr, + [CAMCC_IFE_LITE_CPHY_RX_CLK] = &camcc_ife_lite_cphy_rx_clk.clkr, + [CAMCC_IFE_LITE_CSID_CLK] = &camcc_ife_lite_csid_clk.clkr, + [CAMCC_IFE_LITE_CSID_CLK_SRC] = &camcc_ife_lite_csid_clk_src.clkr, + [CAMCC_IPE_0_AHB_CLK] = &camcc_ipe_0_ahb_clk.clkr, + [CAMCC_IPE_0_AREG_CLK] = &camcc_ipe_0_areg_clk.clkr, + [CAMCC_IPE_0_AXI_CLK] = &camcc_ipe_0_axi_clk.clkr, + [CAMCC_IPE_0_CLK] = &camcc_ipe_0_clk.clkr, + [CAMCC_IPE_0_CLK_SRC] = &camcc_ipe_0_clk_src.clkr, + [CAMCC_IPE_1_AHB_CLK] = &camcc_ipe_1_ahb_clk.clkr, + [CAMCC_IPE_1_AREG_CLK] = &camcc_ipe_1_areg_clk.clkr, + [CAMCC_IPE_1_AXI_CLK] = &camcc_ipe_1_axi_clk.clkr, + [CAMCC_IPE_1_CLK] = &camcc_ipe_1_clk.clkr, + [CAMCC_JPEG_CLK] = &camcc_jpeg_clk.clkr, + [CAMCC_JPEG_CLK_SRC] = &camcc_jpeg_clk_src.clkr, + [CAMCC_LRME_CLK] = &camcc_lrme_clk.clkr, + [CAMCC_LRME_CLK_SRC] = &camcc_lrme_clk_src.clkr, + [CAMCC_MCLK0_CLK] = &camcc_mclk0_clk.clkr, + [CAMCC_MCLK0_CLK_SRC] = &camcc_mclk0_clk_src.clkr, + [CAMCC_MCLK1_CLK] = &camcc_mclk1_clk.clkr, + [CAMCC_MCLK1_CLK_SRC] = &camcc_mclk1_clk_src.clkr, + [CAMCC_MCLK2_CLK] = &camcc_mclk2_clk.clkr, + [CAMCC_MCLK2_CLK_SRC] = &camcc_mclk2_clk_src.clkr, + [CAMCC_MCLK3_CLK] = &camcc_mclk3_clk.clkr, + [CAMCC_MCLK3_CLK_SRC] = &camcc_mclk3_clk_src.clkr, + [CAMCC_PLL0] = &camcc_pll0.clkr, + [CAMCC_PLL1] = &camcc_pll1.clkr, + [CAMCC_PLL2] = &camcc_pll2.clkr, + [CAMCC_PLL2_OUT_AUX] = &camcc_pll2_out_aux.clkr, + [CAMCC_PLL2_OUT_MAIN] = &camcc_pll2_out_main.clkr, + [CAMCC_PLL3] = &camcc_pll3.clkr, + [CAMCC_PLL4] = &camcc_pll4.clkr, + [CAMCC_SLEEP_CLK] = &camcc_sleep_clk.clkr, + [CAMCC_SLEEP_CLK_SRC] = &camcc_sleep_clk_src.clkr, + [CAMCC_SLOW_AHB_CLK_SRC] = &camcc_slow_ahb_clk_src.clkr, + [CAMCC_XO_CLK_SRC] = &camcc_xo_clk_src.clkr, +}; + +static struct gdsc *camcc_sm7150_gdscs[] = { + [BPS_GDSC] = &camcc_bps_gdsc, + [IFE_0_GDSC] = &camcc_ife_0_gdsc, + [IFE_1_GDSC] = &camcc_ife_1_gdsc, + [IPE_0_GDSC] = &camcc_ipe_0_gdsc, + [IPE_1_GDSC] = &camcc_ipe_1_gdsc, + [TITAN_TOP_GDSC] = &camcc_titan_top_gdsc, +}; + +static const struct regmap_config camcc_sm7150_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xd024, + .fast_io = true, +}; + +static const struct qcom_cc_desc camcc_sm7150_desc = { + .config = &camcc_sm7150_regmap_config, + .clk_hws = camcc_sm7150_hws, + .num_clk_hws = ARRAY_SIZE(camcc_sm7150_hws), + .clks = camcc_sm7150_clocks, + .num_clks = ARRAY_SIZE(camcc_sm7150_clocks), + .gdscs = camcc_sm7150_gdscs, + .num_gdscs = ARRAY_SIZE(camcc_sm7150_gdscs), +}; + +static const struct of_device_id camcc_sm7150_match_table[] = { + { .compatible = "qcom,sm7150-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, camcc_sm7150_match_table); + +static int camcc_sm7150_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &camcc_sm7150_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + clk_fabia_pll_configure(&camcc_pll0, regmap, &camcc_pll0_config); + clk_fabia_pll_configure(&camcc_pll1, regmap, &camcc_pll1_config); + clk_agera_pll_configure(&camcc_pll2, regmap, &camcc_pll2_config); + clk_fabia_pll_configure(&camcc_pll3, regmap, &camcc_pll3_config); + clk_fabia_pll_configure(&camcc_pll4, regmap, &camcc_pll3_config); + + /* Keep some clocks always-on */ + qcom_branch_set_clk_en(regmap, 0xc1a0); /* CAMCC_GDSC_CLK */ + + return qcom_cc_really_probe(&pdev->dev, &camcc_sm7150_desc, regmap); +} + +static struct platform_driver camcc_sm7150_driver = { + .probe = camcc_sm7150_probe, + .driver = { + .name = "camcc-sm7150", + .of_match_table = camcc_sm7150_match_table, + }, +}; + +module_platform_driver(camcc_sm7150_driver); + +MODULE_DESCRIPTION("Qualcomm SM7150 Camera Clock Controller"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c index 9b32c56a5bc5..34d2f17520dc 100644 --- a/drivers/clk/qcom/camcc-sm8250.c +++ b/drivers/clk/qcom/camcc-sm8250.c @@ -32,11 +32,11 @@ enum { P_SLEEP_CLK, }; -static struct pll_vco lucid_vco[] = { +static const struct pll_vco lucid_vco[] = { { 249600000, 2000000000, 0 }, }; -static struct pll_vco zonda_vco[] = { +static const struct pll_vco zonda_vco[] = { { 595200000UL, 3600000000UL, 0 }, }; @@ -2433,7 +2433,7 @@ static int cam_cc_sm8250_probe(struct platform_device *pdev) clk_lucid_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config); clk_lucid_pll_configure(&cam_cc_pll4, regmap, &cam_cc_pll4_config); - return qcom_cc_really_probe(pdev, &cam_cc_sm8250_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &cam_cc_sm8250_desc, regmap); } static struct platform_driver cam_cc_sm8250_driver = { diff --git a/drivers/clk/qcom/camcc-sm8450.c b/drivers/clk/qcom/camcc-sm8450.c index 51338a2884d2..26b78eed15ef 100644 --- a/drivers/clk/qcom/camcc-sm8450.c +++ b/drivers/clk/qcom/camcc-sm8450.c @@ -2839,7 +2839,7 @@ static int cam_cc_sm8450_probe(struct platform_device *pdev) clk_lucid_evo_pll_configure(&cam_cc_pll7, regmap, &cam_cc_pll7_config); clk_lucid_evo_pll_configure(&cam_cc_pll8, regmap, &cam_cc_pll8_config); - return qcom_cc_really_probe(pdev, &cam_cc_sm8450_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &cam_cc_sm8450_desc, regmap); } static struct platform_driver cam_cc_sm8450_driver = { diff --git a/drivers/clk/qcom/camcc-sm8550.c b/drivers/clk/qcom/camcc-sm8550.c index 1ef59a96f664..eac850bb690a 100644 --- a/drivers/clk/qcom/camcc-sm8550.c +++ b/drivers/clk/qcom/camcc-sm8550.c @@ -3540,7 +3540,7 @@ static int cam_cc_sm8550_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0x1419c); /* CAM_CC_GDSC_CLK */ qcom_branch_set_clk_en(regmap, 0x142cc); /* CAM_CC_SLEEP_CLK */ - ret = qcom_cc_really_probe(pdev, &cam_cc_sm8550_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_sm8550_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/camcc-sm8650.c b/drivers/clk/qcom/camcc-sm8650.c new file mode 100644 index 000000000000..a37e52a67ed4 --- /dev/null +++ b/drivers/clk/qcom/camcc-sm8650.c @@ -0,0 +1,3591 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include <linux/clk-provider.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,sm8650-camcc.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_IFACE, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_BI_TCXO_AO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL0_OUT_MAIN, + P_CAM_CC_PLL0_OUT_ODD, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL2_OUT_MAIN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CAM_CC_PLL4_OUT_EVEN, + P_CAM_CC_PLL5_OUT_EVEN, + P_CAM_CC_PLL6_OUT_EVEN, + P_CAM_CC_PLL7_OUT_EVEN, + P_CAM_CC_PLL8_OUT_EVEN, + P_CAM_CC_PLL9_OUT_EVEN, + P_CAM_CC_PLL9_OUT_ODD, + P_CAM_CC_PLL10_OUT_EVEN, + P_SLEEP_CLK, +}; + +static const struct pll_vco lucid_ole_vco[] = { + { 249600000, 2300000000, 0 }, +}; + +static const struct pll_vco rivian_ole_vco[] = { + { 777000000, 1285000000, 0 }, +}; + +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .alpha = 0x8000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00008400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_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 = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_odd = { + .offset = 0x0, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll0_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x31, + .alpha = 0x7aaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll1_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll1_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll1_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll1.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x10000030, + .config_ctl_hi_val = 0x80890263, + .config_ctl_hi1_val = 0x00000217, + .user_ctl_val = 0x00000001, + .user_ctl_hi_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .vco_table = rivian_ole_vco, + .num_vco = ARRAY_SIZE(rivian_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_EVO], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_rivian_evo_ops, + }, + }, +}; + +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x30, + .alpha = 0x8aaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll3_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = { + .offset = 0x3000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll3_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll3_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll3.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x30, + .alpha = 0x8aaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll4 = { + .offset = 0x4000, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll4_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll4_out_even = { + .offset = 0x4000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll4_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll4_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll4_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll4.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll5_config = { + .l = 0x30, + .alpha = 0x8aaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll5 = { + .offset = 0x5000, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll5", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll5_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll5_out_even = { + .offset = 0x5000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll5_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll5_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll5_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll5.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll6_config = { + .l = 0x30, + .alpha = 0x8aaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll6 = { + .offset = 0x6000, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_even = { + .offset = 0x6000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll6_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll7_config = { + .l = 0x30, + .alpha = 0x8aaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll7 = { + .offset = 0x7000, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll7", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll7_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll7_out_even = { + .offset = 0x7000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll7_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll7_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll7_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll7.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll8_config = { + .l = 0x14, + .alpha = 0xd555, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll8 = { + .offset = 0x8000, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll8", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll8_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll8_out_even = { + .offset = 0x8000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll8_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll8_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll8_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll8.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll9_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00008400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll9 = { + .offset = 0x9000, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll9", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll9_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll9_out_even = { + .offset = 0x9000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll9_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll9_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll9_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll9.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll9_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll9_out_odd = { + .offset = 0x9000, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll9_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll9_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll9_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll9.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll10_config = { + .l = 0x30, + .alpha = 0x8aaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000005, +}; + +static struct clk_alpha_pll cam_cc_pll10 = { + .offset = 0xa000, + .vco_table = lucid_ole_vco, + .num_vco = ARRAY_SIZE(lucid_ole_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll10", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_evo_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll10_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll10_out_even = { + .offset = 0xa000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll10_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll10_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll10_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll10.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, + }, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL9_OUT_ODD, 4 }, + { P_CAM_CC_PLL9_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll0.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, + { .hw = &cam_cc_pll0_out_odd.clkr.hw }, + { .hw = &cam_cc_pll9_out_odd.clkr.hw }, + { .hw = &cam_cc_pll9_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 3 }, + { P_CAM_CC_PLL2_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll2.clkr.hw }, + { .hw = &cam_cc_pll2.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL8_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll8_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL3_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll4_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL5_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll5_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL1_OUT_EVEN, 4 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll1_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL6_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL7_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll7_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_9[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL10_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_9[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll10_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_10[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_10[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map cam_cc_parent_map_11_ao[] = { + { P_BI_TCXO_AO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_11_ao[] = { + { .index = DT_BI_TCXO_AO }, +}; + +static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0), + F(400000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0), + F(785000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_bps_clk_src = { + .cmd_rcgr = 0x10050, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_bps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_clk_src", + .parent_data = cam_cc_parent_data_2, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_axi_rt_clk_src[] = { + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_camnoc_axi_rt_clk_src = { + .cmd_rcgr = 0x1325c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_camnoc_axi_rt_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_axi_rt_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cci_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .cmd_rcgr = 0x131cc, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_0_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_cci_1_clk_src = { + .cmd_rcgr = 0x131e8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_1_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_cci_2_clk_src = { + .cmd_rcgr = 0x13204, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { + .cmd_rcgr = 0x1104c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cphy_rx_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cre_clk_src[] = { + F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL9_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cre_clk_src = { + .cmd_rcgr = 0x13144, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x150e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi0phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { + .cmd_rcgr = 0x15104, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi1phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { + .cmd_rcgr = 0x15124, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { + .cmd_rcgr = 0x15144, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi4phytimer_clk_src = { + .cmd_rcgr = 0x15164, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi4phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi5phytimer_clk_src = { + .cmd_rcgr = 0x15184, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi6phytimer_clk_src = { + .cmd_rcgr = 0x151a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi6phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi7phytimer_clk_src = { + .cmd_rcgr = 0x151c4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi7phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_csid_clk_src[] = { + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csid_clk_src = { + .cmd_rcgr = 0x13238, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csid_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { + .cmd_rcgr = 0x10018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_fast_ahb_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_icp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL9_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_clk_src = { + .cmd_rcgr = 0x131a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_icp_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(466000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(594000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(785000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_0_clk_src = { + .cmd_rcgr = 0x11018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_clk_src", + .parent_data = cam_cc_parent_data_3, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_1_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(466000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(594000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(785000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_1_clk_src = { + .cmd_rcgr = 0x12018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_4, + .freq_tbl = ftbl_cam_cc_ife_1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_clk_src", + .parent_data = cam_cc_parent_data_4, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_2_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(466000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(594000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(785000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_2_clk_src = { + .cmd_rcgr = 0x12068, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_ife_2_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_clk_src", + .parent_data = cam_cc_parent_data_5, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .cmd_rcgr = 0x13000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csid_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { + .cmd_rcgr = 0x13028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csid_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ipe_nps_clk_src[] = { + F(475000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(575000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(825000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_nps_clk_src = { + .cmd_rcgr = 0x10094, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_6, + .freq_tbl = ftbl_cam_cc_ipe_nps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_clk_src", + .parent_data = cam_cc_parent_data_6, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_jpeg_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL9_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0x13168, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_jpeg_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24000000, P_CAM_CC_PLL2_OUT_EVEN, 10, 1, 4), + F(68571429, P_CAM_CC_PLL2_OUT_MAIN, 14, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_mclk0_clk_src = { + .cmd_rcgr = 0x15000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk0_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk1_clk_src = { + .cmd_rcgr = 0x1501c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk1_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk2_clk_src = { + .cmd_rcgr = 0x15038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk2_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk3_clk_src = { + .cmd_rcgr = 0x15054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk3_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk4_clk_src = { + .cmd_rcgr = 0x15070, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk4_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk5_clk_src = { + .cmd_rcgr = 0x1508c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk5_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk6_clk_src = { + .cmd_rcgr = 0x150a8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk6_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk7_clk_src = { + .cmd_rcgr = 0x150c4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk7_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_qdss_debug_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(75000000, P_CAM_CC_PLL0_OUT_EVEN, 8, 0, 0), + F(150000000, P_CAM_CC_PLL0_OUT_EVEN, 4, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qdss_debug_clk_src = { + .cmd_rcgr = 0x1329c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_qdss_debug_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_sfe_0_clk_src[] = { + F(466000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + F(594000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + F(785000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_sfe_0_clk_src = { + .cmd_rcgr = 0x1306c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_7, + .freq_tbl = ftbl_cam_cc_sfe_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_0_clk_src", + .parent_data = cam_cc_parent_data_7, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_sfe_1_clk_src[] = { + F(466000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(594000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(785000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_sfe_1_clk_src = { + .cmd_rcgr = 0x130bc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_8, + .freq_tbl = ftbl_cam_cc_sfe_1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_1_clk_src", + .parent_data = cam_cc_parent_data_8, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_sfe_2_clk_src[] = { + F(466000000, P_CAM_CC_PLL10_OUT_EVEN, 1, 0, 0), + F(594000000, P_CAM_CC_PLL10_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL10_OUT_EVEN, 1, 0, 0), + F(785000000, P_CAM_CC_PLL10_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_sfe_2_clk_src = { + .cmd_rcgr = 0x1310c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_9, + .freq_tbl = ftbl_cam_cc_sfe_2_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_2_clk_src", + .parent_data = cam_cc_parent_data_9, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_sleep_clk_src = { + .cmd_rcgr = 0x132f0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_10, + .freq_tbl = ftbl_cam_cc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sleep_clk_src", + .parent_data = cam_cc_parent_data_10, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_10), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { + .cmd_rcgr = 0x10034, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_slow_ahb_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_xo_clk_src[] = { + F(19200000, P_BI_TCXO_AO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_xo_clk_src = { + .cmd_rcgr = 0x132d4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_11_ao, + .freq_tbl = ftbl_cam_cc_xo_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_xo_clk_src", + .parent_data = cam_cc_parent_data_11_ao, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_11_ao), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch cam_cc_bps_ahb_clk = { + .halt_reg = 0x1004c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1004c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_clk = { + .halt_reg = 0x10068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_bps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_fast_ahb_clk = { + .halt_reg = 0x10030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_shift_clk = { + .halt_reg = 0x10078, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x10078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_bps_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_axi_nrt_clk = { + .halt_reg = 0x13284, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13284, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_axi_nrt_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_axi_rt_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_axi_rt_clk = { + .halt_reg = 0x13274, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13274, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_axi_rt_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_axi_rt_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_dcd_xo_clk = { + .halt_reg = 0x13290, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13290, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_dcd_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_xo_clk = { + .halt_reg = 0x13294, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13294, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_0_clk = { + .halt_reg = 0x131e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x131e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_1_clk = { + .halt_reg = 0x13200, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13200, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_2_clk = { + .halt_reg = 0x1321c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1321c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_core_ahb_clk = { + .halt_reg = 0x132d0, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x132d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_core_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ahb_clk = { + .halt_reg = 0x13220, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13220, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_bps_clk = { + .halt_reg = 0x10074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_bps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_bps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_cre_clk = { + .halt_reg = 0x13160, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13160, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_fast_ahb_clk = { + .halt_reg = 0x1322c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1322c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ife_0_clk = { + .halt_reg = 0x1103c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1103c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ife_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ife_1_clk = { + .halt_reg = 0x1203c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1203c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ife_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ife_2_clk = { + .halt_reg = 0x1208c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1208c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ife_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ife_lite_clk = { + .halt_reg = 0x13024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ipe_nps_clk = { + .halt_reg = 0x100b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_ipe_nps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_sbi_clk = { + .halt_reg = 0x10104, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10104, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_sbi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_sfe_0_clk = { + .halt_reg = 0x13090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_sfe_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_sfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_sfe_1_clk = { + .halt_reg = 0x130e0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x130e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_sfe_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_sfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_sfe_2_clk = { + .halt_reg = 0x13130, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13130, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cpas_sfe_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_sfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cre_ahb_clk = { + .halt_reg = 0x13164, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13164, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cre_clk = { + .halt_reg = 0x1315c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1315c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi0phytimer_clk = { + .halt_reg = 0x150f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi0phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi0phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi1phytimer_clk = { + .halt_reg = 0x1511c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1511c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi1phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi1phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi2phytimer_clk = { + .halt_reg = 0x1513c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1513c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi2phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi3phytimer_clk = { + .halt_reg = 0x1515c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1515c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi3phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi4phytimer_clk = { + .halt_reg = 0x1517c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1517c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi4phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi4phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi5phytimer_clk = { + .halt_reg = 0x1519c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1519c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi5phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi6phytimer_clk = { + .halt_reg = 0x151bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x151bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi6phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi6phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi7phytimer_clk = { + .halt_reg = 0x151dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x151dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi7phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi7phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csid_clk = { + .halt_reg = 0x13250, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13250, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csid_csiphy_rx_clk = { + .halt_reg = 0x15100, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15100, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_csiphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy0_clk = { + .halt_reg = 0x150fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy1_clk = { + .halt_reg = 0x15120, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15120, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy2_clk = { + .halt_reg = 0x15140, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15140, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy3_clk = { + .halt_reg = 0x15160, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15160, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy4_clk = { + .halt_reg = 0x15180, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15180, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy5_clk = { + .halt_reg = 0x151a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x151a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy6_clk = { + .halt_reg = 0x151c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x151c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy6_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy7_clk = { + .halt_reg = 0x151e0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x151e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy7_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_ahb_clk = { + .halt_reg = 0x131c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x131c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_clk = { + .halt_reg = 0x131bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x131bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_clk = { + .halt_reg = 0x11030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_fast_ahb_clk = { + .halt_reg = 0x11048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_shift_clk = { + .halt_reg = 0x11064, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x11064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_clk = { + .halt_reg = 0x12030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_fast_ahb_clk = { + .halt_reg = 0x12048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_shift_clk = { + .halt_reg = 0x1204c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1204c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_1_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_2_clk = { + .halt_reg = 0x12080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_2_fast_ahb_clk = { + .halt_reg = 0x12098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12098, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_2_shift_clk = { + .halt_reg = 0x1209c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1209c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_2_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_ahb_clk = { + .halt_reg = 0x13050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_clk = { + .halt_reg = 0x13018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = { + .halt_reg = 0x1304c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1304c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_csid_clk = { + .halt_reg = 0x13040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_ahb_clk = { + .halt_reg = 0x100d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_clk = { + .halt_reg = 0x100ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_fast_ahb_clk = { + .halt_reg = 0x100d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_pps_clk = { + .halt_reg = 0x100bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_pps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_pps_fast_ahb_clk = { + .halt_reg = 0x100d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_pps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_shift_clk = { + .halt_reg = 0x100dc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x100dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_jpeg_1_clk = { + .halt_reg = 0x1318c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1318c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_jpeg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_jpeg_clk = { + .halt_reg = 0x13180, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13180, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_jpeg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk0_clk = { + .halt_reg = 0x15018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk1_clk = { + .halt_reg = 0x15034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk2_clk = { + .halt_reg = 0x15050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk3_clk = { + .halt_reg = 0x1506c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1506c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk4_clk = { + .halt_reg = 0x15088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x15088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk5_clk = { + .halt_reg = 0x150a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk6_clk = { + .halt_reg = 0x150c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk6_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk7_clk = { + .halt_reg = 0x150dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_mclk7_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_mclk7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qdss_debug_clk = { + .halt_reg = 0x132b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x132b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qdss_debug_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qdss_debug_xo_clk = { + .halt_reg = 0x132b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x132b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sbi_clk = { + .halt_reg = 0x100f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sbi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sbi_fast_ahb_clk = { + .halt_reg = 0x10108, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sbi_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sbi_shift_clk = { + .halt_reg = 0x1010c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1010c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sbi_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_0_clk = { + .halt_reg = 0x13084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13084, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_sfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_0_fast_ahb_clk = { + .halt_reg = 0x1309c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1309c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_0_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_0_shift_clk = { + .halt_reg = 0x130a0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x130a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_1_clk = { + .halt_reg = 0x130d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x130d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_sfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_1_fast_ahb_clk = { + .halt_reg = 0x130ec, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x130ec, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_1_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_1_shift_clk = { + .halt_reg = 0x130f0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x130f0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_1_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_2_clk = { + .halt_reg = 0x13124, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13124, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_sfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_2_fast_ahb_clk = { + .halt_reg = 0x1313c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1313c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_2_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sfe_2_shift_clk = { + .halt_reg = 0x13140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x13140, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sfe_2_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_titan_top_shift_clk = { + .halt_reg = 0x1330c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1330c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_titan_top_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc cam_cc_titan_top_gdsc = { + .gdscr = 0x132bc, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_titan_top_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_bps_gdsc = { + .gdscr = 0x10004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_bps_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ife_0_gdsc = { + .gdscr = 0x11004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ife_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ife_1_gdsc = { + .gdscr = 0x12004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ife_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ife_2_gdsc = { + .gdscr = 0x12054, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ife_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ipe_0_gdsc = { + .gdscr = 0x10080, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_sbi_gdsc = { + .gdscr = 0x100e4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_sbi_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_sfe_0_gdsc = { + .gdscr = 0x13058, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_sfe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_sfe_1_gdsc = { + .gdscr = 0x130a8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_sfe_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_sfe_2_gdsc = { + .gdscr = 0x130f8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_sfe_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *cam_cc_sm8650_clocks[] = { + [CAM_CC_BPS_AHB_CLK] = &cam_cc_bps_ahb_clk.clkr, + [CAM_CC_BPS_CLK] = &cam_cc_bps_clk.clkr, + [CAM_CC_BPS_CLK_SRC] = &cam_cc_bps_clk_src.clkr, + [CAM_CC_BPS_FAST_AHB_CLK] = &cam_cc_bps_fast_ahb_clk.clkr, + [CAM_CC_BPS_SHIFT_CLK] = &cam_cc_bps_shift_clk.clkr, + [CAM_CC_CAMNOC_AXI_NRT_CLK] = &cam_cc_camnoc_axi_nrt_clk.clkr, + [CAM_CC_CAMNOC_AXI_RT_CLK] = &cam_cc_camnoc_axi_rt_clk.clkr, + [CAM_CC_CAMNOC_AXI_RT_CLK_SRC] = &cam_cc_camnoc_axi_rt_clk_src.clkr, + [CAM_CC_CAMNOC_DCD_XO_CLK] = &cam_cc_camnoc_dcd_xo_clk.clkr, + [CAM_CC_CAMNOC_XO_CLK] = &cam_cc_camnoc_xo_clk.clkr, + [CAM_CC_CCI_0_CLK] = &cam_cc_cci_0_clk.clkr, + [CAM_CC_CCI_0_CLK_SRC] = &cam_cc_cci_0_clk_src.clkr, + [CAM_CC_CCI_1_CLK] = &cam_cc_cci_1_clk.clkr, + [CAM_CC_CCI_1_CLK_SRC] = &cam_cc_cci_1_clk_src.clkr, + [CAM_CC_CCI_2_CLK] = &cam_cc_cci_2_clk.clkr, + [CAM_CC_CCI_2_CLK_SRC] = &cam_cc_cci_2_clk_src.clkr, + [CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr, + [CAM_CC_CPAS_AHB_CLK] = &cam_cc_cpas_ahb_clk.clkr, + [CAM_CC_CPAS_BPS_CLK] = &cam_cc_cpas_bps_clk.clkr, + [CAM_CC_CPAS_CRE_CLK] = &cam_cc_cpas_cre_clk.clkr, + [CAM_CC_CPAS_FAST_AHB_CLK] = &cam_cc_cpas_fast_ahb_clk.clkr, + [CAM_CC_CPAS_IFE_0_CLK] = &cam_cc_cpas_ife_0_clk.clkr, + [CAM_CC_CPAS_IFE_1_CLK] = &cam_cc_cpas_ife_1_clk.clkr, + [CAM_CC_CPAS_IFE_2_CLK] = &cam_cc_cpas_ife_2_clk.clkr, + [CAM_CC_CPAS_IFE_LITE_CLK] = &cam_cc_cpas_ife_lite_clk.clkr, + [CAM_CC_CPAS_IPE_NPS_CLK] = &cam_cc_cpas_ipe_nps_clk.clkr, + [CAM_CC_CPAS_SBI_CLK] = &cam_cc_cpas_sbi_clk.clkr, + [CAM_CC_CPAS_SFE_0_CLK] = &cam_cc_cpas_sfe_0_clk.clkr, + [CAM_CC_CPAS_SFE_1_CLK] = &cam_cc_cpas_sfe_1_clk.clkr, + [CAM_CC_CPAS_SFE_2_CLK] = &cam_cc_cpas_sfe_2_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CRE_AHB_CLK] = &cam_cc_cre_ahb_clk.clkr, + [CAM_CC_CRE_CLK] = &cam_cc_cre_clk.clkr, + [CAM_CC_CRE_CLK_SRC] = &cam_cc_cre_clk_src.clkr, + [CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr, + [CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr, + [CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr, + [CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr, + [CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr, + [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr, + [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr, + [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_clk_src.clkr, + [CAM_CC_CSI4PHYTIMER_CLK] = &cam_cc_csi4phytimer_clk.clkr, + [CAM_CC_CSI4PHYTIMER_CLK_SRC] = &cam_cc_csi4phytimer_clk_src.clkr, + [CAM_CC_CSI5PHYTIMER_CLK] = &cam_cc_csi5phytimer_clk.clkr, + [CAM_CC_CSI5PHYTIMER_CLK_SRC] = &cam_cc_csi5phytimer_clk_src.clkr, + [CAM_CC_CSI6PHYTIMER_CLK] = &cam_cc_csi6phytimer_clk.clkr, + [CAM_CC_CSI6PHYTIMER_CLK_SRC] = &cam_cc_csi6phytimer_clk_src.clkr, + [CAM_CC_CSI7PHYTIMER_CLK] = &cam_cc_csi7phytimer_clk.clkr, + [CAM_CC_CSI7PHYTIMER_CLK_SRC] = &cam_cc_csi7phytimer_clk_src.clkr, + [CAM_CC_CSID_CLK] = &cam_cc_csid_clk.clkr, + [CAM_CC_CSID_CLK_SRC] = &cam_cc_csid_clk_src.clkr, + [CAM_CC_CSID_CSIPHY_RX_CLK] = &cam_cc_csid_csiphy_rx_clk.clkr, + [CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr, + [CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr, + [CAM_CC_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr, + [CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr, + [CAM_CC_CSIPHY4_CLK] = &cam_cc_csiphy4_clk.clkr, + [CAM_CC_CSIPHY5_CLK] = &cam_cc_csiphy5_clk.clkr, + [CAM_CC_CSIPHY6_CLK] = &cam_cc_csiphy6_clk.clkr, + [CAM_CC_CSIPHY7_CLK] = &cam_cc_csiphy7_clk.clkr, + [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, + [CAM_CC_ICP_AHB_CLK] = &cam_cc_icp_ahb_clk.clkr, + [CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr, + [CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr, + [CAM_CC_IFE_0_CLK] = &cam_cc_ife_0_clk.clkr, + [CAM_CC_IFE_0_CLK_SRC] = &cam_cc_ife_0_clk_src.clkr, + [CAM_CC_IFE_0_FAST_AHB_CLK] = &cam_cc_ife_0_fast_ahb_clk.clkr, + [CAM_CC_IFE_0_SHIFT_CLK] = &cam_cc_ife_0_shift_clk.clkr, + [CAM_CC_IFE_1_CLK] = &cam_cc_ife_1_clk.clkr, + [CAM_CC_IFE_1_CLK_SRC] = &cam_cc_ife_1_clk_src.clkr, + [CAM_CC_IFE_1_FAST_AHB_CLK] = &cam_cc_ife_1_fast_ahb_clk.clkr, + [CAM_CC_IFE_1_SHIFT_CLK] = &cam_cc_ife_1_shift_clk.clkr, + [CAM_CC_IFE_2_CLK] = &cam_cc_ife_2_clk.clkr, + [CAM_CC_IFE_2_CLK_SRC] = &cam_cc_ife_2_clk_src.clkr, + [CAM_CC_IFE_2_FAST_AHB_CLK] = &cam_cc_ife_2_fast_ahb_clk.clkr, + [CAM_CC_IFE_2_SHIFT_CLK] = &cam_cc_ife_2_shift_clk.clkr, + [CAM_CC_IFE_LITE_AHB_CLK] = &cam_cc_ife_lite_ahb_clk.clkr, + [CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr, + [CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr, + [CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr, + [CAM_CC_IPE_NPS_AHB_CLK] = &cam_cc_ipe_nps_ahb_clk.clkr, + [CAM_CC_IPE_NPS_CLK] = &cam_cc_ipe_nps_clk.clkr, + [CAM_CC_IPE_NPS_CLK_SRC] = &cam_cc_ipe_nps_clk_src.clkr, + [CAM_CC_IPE_NPS_FAST_AHB_CLK] = &cam_cc_ipe_nps_fast_ahb_clk.clkr, + [CAM_CC_IPE_PPS_CLK] = &cam_cc_ipe_pps_clk.clkr, + [CAM_CC_IPE_PPS_FAST_AHB_CLK] = &cam_cc_ipe_pps_fast_ahb_clk.clkr, + [CAM_CC_IPE_SHIFT_CLK] = &cam_cc_ipe_shift_clk.clkr, + [CAM_CC_JPEG_1_CLK] = &cam_cc_jpeg_1_clk.clkr, + [CAM_CC_JPEG_CLK] = &cam_cc_jpeg_clk.clkr, + [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr, + [CAM_CC_MCLK0_CLK] = &cam_cc_mclk0_clk.clkr, + [CAM_CC_MCLK0_CLK_SRC] = &cam_cc_mclk0_clk_src.clkr, + [CAM_CC_MCLK1_CLK] = &cam_cc_mclk1_clk.clkr, + [CAM_CC_MCLK1_CLK_SRC] = &cam_cc_mclk1_clk_src.clkr, + [CAM_CC_MCLK2_CLK] = &cam_cc_mclk2_clk.clkr, + [CAM_CC_MCLK2_CLK_SRC] = &cam_cc_mclk2_clk_src.clkr, + [CAM_CC_MCLK3_CLK] = &cam_cc_mclk3_clk.clkr, + [CAM_CC_MCLK3_CLK_SRC] = &cam_cc_mclk3_clk_src.clkr, + [CAM_CC_MCLK4_CLK] = &cam_cc_mclk4_clk.clkr, + [CAM_CC_MCLK4_CLK_SRC] = &cam_cc_mclk4_clk_src.clkr, + [CAM_CC_MCLK5_CLK] = &cam_cc_mclk5_clk.clkr, + [CAM_CC_MCLK5_CLK_SRC] = &cam_cc_mclk5_clk_src.clkr, + [CAM_CC_MCLK6_CLK] = &cam_cc_mclk6_clk.clkr, + [CAM_CC_MCLK6_CLK_SRC] = &cam_cc_mclk6_clk_src.clkr, + [CAM_CC_MCLK7_CLK] = &cam_cc_mclk7_clk.clkr, + [CAM_CC_MCLK7_CLK_SRC] = &cam_cc_mclk7_clk_src.clkr, + [CAM_CC_PLL0] = &cam_cc_pll0.clkr, + [CAM_CC_PLL0_OUT_EVEN] = &cam_cc_pll0_out_even.clkr, + [CAM_CC_PLL0_OUT_ODD] = &cam_cc_pll0_out_odd.clkr, + [CAM_CC_PLL1] = &cam_cc_pll1.clkr, + [CAM_CC_PLL1_OUT_EVEN] = &cam_cc_pll1_out_even.clkr, + [CAM_CC_PLL2] = &cam_cc_pll2.clkr, + [CAM_CC_PLL3] = &cam_cc_pll3.clkr, + [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr, + [CAM_CC_PLL4] = &cam_cc_pll4.clkr, + [CAM_CC_PLL4_OUT_EVEN] = &cam_cc_pll4_out_even.clkr, + [CAM_CC_PLL5] = &cam_cc_pll5.clkr, + [CAM_CC_PLL5_OUT_EVEN] = &cam_cc_pll5_out_even.clkr, + [CAM_CC_PLL6] = &cam_cc_pll6.clkr, + [CAM_CC_PLL6_OUT_EVEN] = &cam_cc_pll6_out_even.clkr, + [CAM_CC_PLL7] = &cam_cc_pll7.clkr, + [CAM_CC_PLL7_OUT_EVEN] = &cam_cc_pll7_out_even.clkr, + [CAM_CC_PLL8] = &cam_cc_pll8.clkr, + [CAM_CC_PLL8_OUT_EVEN] = &cam_cc_pll8_out_even.clkr, + [CAM_CC_PLL9] = &cam_cc_pll9.clkr, + [CAM_CC_PLL9_OUT_EVEN] = &cam_cc_pll9_out_even.clkr, + [CAM_CC_PLL9_OUT_ODD] = &cam_cc_pll9_out_odd.clkr, + [CAM_CC_PLL10] = &cam_cc_pll10.clkr, + [CAM_CC_PLL10_OUT_EVEN] = &cam_cc_pll10_out_even.clkr, + [CAM_CC_QDSS_DEBUG_CLK] = &cam_cc_qdss_debug_clk.clkr, + [CAM_CC_QDSS_DEBUG_CLK_SRC] = &cam_cc_qdss_debug_clk_src.clkr, + [CAM_CC_QDSS_DEBUG_XO_CLK] = &cam_cc_qdss_debug_xo_clk.clkr, + [CAM_CC_SBI_CLK] = &cam_cc_sbi_clk.clkr, + [CAM_CC_SBI_FAST_AHB_CLK] = &cam_cc_sbi_fast_ahb_clk.clkr, + [CAM_CC_SBI_SHIFT_CLK] = &cam_cc_sbi_shift_clk.clkr, + [CAM_CC_SFE_0_CLK] = &cam_cc_sfe_0_clk.clkr, + [CAM_CC_SFE_0_CLK_SRC] = &cam_cc_sfe_0_clk_src.clkr, + [CAM_CC_SFE_0_FAST_AHB_CLK] = &cam_cc_sfe_0_fast_ahb_clk.clkr, + [CAM_CC_SFE_0_SHIFT_CLK] = &cam_cc_sfe_0_shift_clk.clkr, + [CAM_CC_SFE_1_CLK] = &cam_cc_sfe_1_clk.clkr, + [CAM_CC_SFE_1_CLK_SRC] = &cam_cc_sfe_1_clk_src.clkr, + [CAM_CC_SFE_1_FAST_AHB_CLK] = &cam_cc_sfe_1_fast_ahb_clk.clkr, + [CAM_CC_SFE_1_SHIFT_CLK] = &cam_cc_sfe_1_shift_clk.clkr, + [CAM_CC_SFE_2_CLK] = &cam_cc_sfe_2_clk.clkr, + [CAM_CC_SFE_2_CLK_SRC] = &cam_cc_sfe_2_clk_src.clkr, + [CAM_CC_SFE_2_FAST_AHB_CLK] = &cam_cc_sfe_2_fast_ahb_clk.clkr, + [CAM_CC_SFE_2_SHIFT_CLK] = &cam_cc_sfe_2_shift_clk.clkr, + [CAM_CC_SLEEP_CLK_SRC] = &cam_cc_sleep_clk_src.clkr, + [CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, + [CAM_CC_TITAN_TOP_SHIFT_CLK] = &cam_cc_titan_top_shift_clk.clkr, + [CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr, +}; + +static struct gdsc *cam_cc_sm8650_gdscs[] = { + [CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc, + [CAM_CC_BPS_GDSC] = &cam_cc_bps_gdsc, + [CAM_CC_IFE_0_GDSC] = &cam_cc_ife_0_gdsc, + [CAM_CC_IFE_1_GDSC] = &cam_cc_ife_1_gdsc, + [CAM_CC_IFE_2_GDSC] = &cam_cc_ife_2_gdsc, + [CAM_CC_IPE_0_GDSC] = &cam_cc_ipe_0_gdsc, + [CAM_CC_SBI_GDSC] = &cam_cc_sbi_gdsc, + [CAM_CC_SFE_0_GDSC] = &cam_cc_sfe_0_gdsc, + [CAM_CC_SFE_1_GDSC] = &cam_cc_sfe_1_gdsc, + [CAM_CC_SFE_2_GDSC] = &cam_cc_sfe_2_gdsc, +}; + +static const struct qcom_reset_map cam_cc_sm8650_resets[] = { + [CAM_CC_BPS_BCR] = { 0x10000 }, + [CAM_CC_DRV_BCR] = { 0x13310 }, + [CAM_CC_ICP_BCR] = { 0x131a0 }, + [CAM_CC_IFE_0_BCR] = { 0x11000 }, + [CAM_CC_IFE_1_BCR] = { 0x12000 }, + [CAM_CC_IFE_2_BCR] = { 0x12050 }, + [CAM_CC_IPE_0_BCR] = { 0x1007c }, + [CAM_CC_QDSS_DEBUG_BCR] = { 0x13298 }, + [CAM_CC_SBI_BCR] = { 0x100e0 }, + [CAM_CC_SFE_0_BCR] = { 0x13054 }, + [CAM_CC_SFE_1_BCR] = { 0x130a4 }, + [CAM_CC_SFE_2_BCR] = { 0x130f4 }, +}; + +static const struct regmap_config cam_cc_sm8650_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1603c, + .fast_io = true, +}; + +static struct qcom_cc_desc cam_cc_sm8650_desc = { + .config = &cam_cc_sm8650_regmap_config, + .clks = cam_cc_sm8650_clocks, + .num_clks = ARRAY_SIZE(cam_cc_sm8650_clocks), + .resets = cam_cc_sm8650_resets, + .num_resets = ARRAY_SIZE(cam_cc_sm8650_resets), + .gdscs = cam_cc_sm8650_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_sm8650_gdscs), +}; + +static const struct of_device_id cam_cc_sm8650_match_table[] = { + { .compatible = "qcom,sm8650-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_sm8650_match_table); + +static int cam_cc_sm8650_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, &cam_cc_sm8650_desc); + if (IS_ERR(regmap)) { + pm_runtime_put(&pdev->dev); + return PTR_ERR(regmap); + } + + clk_lucid_ole_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll0_config); + clk_lucid_ole_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll1_config); + clk_rivian_evo_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config); + clk_lucid_ole_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config); + clk_lucid_ole_pll_configure(&cam_cc_pll4, regmap, &cam_cc_pll4_config); + clk_lucid_ole_pll_configure(&cam_cc_pll5, regmap, &cam_cc_pll5_config); + clk_lucid_ole_pll_configure(&cam_cc_pll6, regmap, &cam_cc_pll6_config); + clk_lucid_ole_pll_configure(&cam_cc_pll7, regmap, &cam_cc_pll7_config); + clk_lucid_ole_pll_configure(&cam_cc_pll8, regmap, &cam_cc_pll8_config); + clk_lucid_ole_pll_configure(&cam_cc_pll9, regmap, &cam_cc_pll9_config); + clk_lucid_ole_pll_configure(&cam_cc_pll10, regmap, &cam_cc_pll10_config); + + /* Keep clocks always enabled */ + qcom_branch_set_clk_en(regmap, 0x13318); /* CAM_CC_DRV_AHB_CLK */ + qcom_branch_set_clk_en(regmap, 0x13314); /* CAM_CC_DRV_XO_CLK */ + qcom_branch_set_clk_en(regmap, 0x132ec); /* CAM_CC_GDSC_CLK */ + qcom_branch_set_clk_en(regmap, 0x13308); /* CAM_CC_SLEEP_CLK */ + + ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_sm8650_desc, regmap); + + pm_runtime_put(&pdev->dev); + + return ret; +} + +static struct platform_driver cam_cc_sm8650_driver = { + .probe = cam_cc_sm8650_probe, + .driver = { + .name = "camcc-sm8650", + .of_match_table = cam_cc_sm8650_match_table, + }, +}; + +module_platform_driver(cam_cc_sm8650_driver); + +MODULE_DESCRIPTION("QTI CAMCC SM8650 Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-x1e80100.c b/drivers/clk/qcom/camcc-x1e80100.c index 46bb225906bf..85e76c7712ad 100644 --- a/drivers/clk/qcom/camcc-x1e80100.c +++ b/drivers/clk/qcom/camcc-x1e80100.c @@ -2466,7 +2466,7 @@ static int cam_cc_x1e80100_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0x13a9c); /* CAM_CC_GDSC_CLK */ qcom_branch_set_clk_en(regmap, 0x13ab8); /* CAM_CC_SLEEP_CLK */ - ret = qcom_cc_really_probe(pdev, &cam_cc_x1e80100_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_x1e80100_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index d4227909d1fe..08e39334b196 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -93,6 +93,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL] = 0x30, [PLL_OFF_TEST_CTL_U] = 0x34, }, + [CLK_ALPHA_PLL_TYPE_HUAYRA_2290] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_ALPHA_VAL] = 0x08, + [PLL_OFF_USER_CTL] = 0x0c, + [PLL_OFF_CONFIG_CTL] = 0x10, + [PLL_OFF_CONFIG_CTL_U] = 0x14, + [PLL_OFF_CONFIG_CTL_U1] = 0x18, + [PLL_OFF_TEST_CTL] = 0x1c, + [PLL_OFF_TEST_CTL_U] = 0x20, + [PLL_OFF_TEST_CTL_U1] = 0x24, + [PLL_OFF_OPMODE] = 0x28, + [PLL_OFF_STATUS] = 0x38, + }, [CLK_ALPHA_PLL_TYPE_BRAMMO] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, @@ -788,6 +801,40 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate, return clamp(rate, min_freq, max_freq); } +void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config) +{ + u32 val; + + 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_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_L_VAL(pll), config->l); + clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); + clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val); + + /* Set PLL_BYPASSNL */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL); + regmap_read(regmap, PLL_MODE(pll), &val); + + /* Wait 5 us between setting BYPASS and deasserting reset */ + udelay(5); + + /* Take PLL out from reset state */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); + regmap_read(regmap, PLL_MODE(pll), &val); + + /* Wait 50us for PLL_LOCK_DET bit to go high */ + usleep_range(50, 55); + + /* Enable PLL output */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL); +} +EXPORT_SYMBOL_GPL(clk_huayra_2290_pll_configure); + static unsigned long alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a) { diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index c7055b6c42f1..df8f0fe15531 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -16,6 +16,7 @@ enum { CLK_ALPHA_PLL_TYPE_DEFAULT, CLK_ALPHA_PLL_TYPE_HUAYRA, CLK_ALPHA_PLL_TYPE_HUAYRA_APSS, + CLK_ALPHA_PLL_TYPE_HUAYRA_2290, CLK_ALPHA_PLL_TYPE_BRAMMO, CLK_ALPHA_PLL_TYPE_FABIA, CLK_ALPHA_PLL_TYPE_TRION, @@ -194,6 +195,8 @@ extern const struct clk_ops clk_alpha_pll_rivian_evo_ops; void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); +void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config); void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c index c1dba33ac31a..229480c5b075 100644 --- a/drivers/clk/qcom/clk-branch.c +++ b/drivers/clk/qcom/clk-branch.c @@ -191,3 +191,10 @@ const struct clk_ops clk_branch_simple_ops = { .is_enabled = clk_is_enabled_regmap, }; EXPORT_SYMBOL_GPL(clk_branch_simple_ops); + +const struct clk_ops clk_branch2_prepare_ops = { + .prepare = clk_branch2_enable, + .unprepare = clk_branch2_disable, + .is_prepared = clk_is_enabled_regmap, +}; +EXPORT_SYMBOL_GPL(clk_branch2_prepare_ops); diff --git a/drivers/clk/qcom/clk-branch.h b/drivers/clk/qcom/clk-branch.h index f1b3b635ff32..292756435f53 100644 --- a/drivers/clk/qcom/clk-branch.h +++ b/drivers/clk/qcom/clk-branch.h @@ -109,6 +109,7 @@ extern const struct clk_ops clk_branch2_ops; extern const struct clk_ops clk_branch_simple_ops; extern const struct clk_ops clk_branch2_aon_ops; extern const struct clk_ops clk_branch2_mem_ops; +extern const struct clk_ops clk_branch2_prepare_ops; #define to_clk_branch(_hw) \ container_of(to_clk_regmap(_hw), struct clk_branch, clkr) diff --git a/drivers/clk/qcom/clk-cbf-8996.c b/drivers/clk/qcom/clk-cbf-8996.c index 76bf523431b8..f5fd1ff9c6c9 100644 --- a/drivers/clk/qcom/clk-cbf-8996.c +++ b/drivers/clk/qcom/clk-cbf-8996.c @@ -226,7 +226,12 @@ static int qcom_msm8996_cbf_icc_register(struct platform_device *pdev, struct cl struct device *dev = &pdev->dev; struct clk *clk = devm_clk_hw_get_clk(dev, cbf_hw, "cbf"); const struct icc_clk_data data[] = { - { .clk = clk, .name = "cbf", }, + { + .clk = clk, + .name = "cbf", + .master_id = MASTER_CBF_M4M, + .slave_id = SLAVE_CBF_M4M, + }, }; struct icc_provider *provider; diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 9b3aaa7f20ac..30b19bd39d08 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -1304,7 +1304,39 @@ clk_rcg2_shared_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) return clk_rcg2_recalc_rate(hw, parent_rate); } +static int clk_rcg2_shared_init(struct clk_hw *hw) +{ + /* + * This does a few things: + * + * 1. Sets rcg->parked_cfg to reflect the value at probe so that the + * proper parent is reported from clk_rcg2_shared_get_parent(). + * + * 2. Clears the force enable bit of the RCG because we rely on child + * clks (branches) to turn the RCG on/off with a hardware feedback + * mechanism and only set the force enable bit in the RCG when we + * want to make sure the clk stays on for parent switches or + * parking. + * + * 3. Parks shared RCGs on the safe source at registration because we + * can't be certain that the parent clk will stay on during boot, + * especially if the parent is shared. If this RCG is enabled at + * boot, and the parent is turned off, the RCG will get stuck on. A + * GDSC can wedge if is turned on and the RCG is stuck on because + * the GDSC's controller will hang waiting for the clk status to + * toggle on when it never does. + * + * The safest option here is to "park" the RCG at init so that the clk + * can never get stuck on or off. This ensures the GDSC can't get + * wedged. + */ + clk_rcg2_shared_disable(hw); + + return 0; +} + const struct clk_ops clk_rcg2_shared_ops = { + .init = clk_rcg2_shared_init, .enable = clk_rcg2_shared_enable, .disable = clk_rcg2_shared_disable, .get_parent = clk_rcg2_shared_get_parent, diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 48f81e3a5e80..ea3788ba46f7 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -8,6 +8,7 @@ #include <linux/regmap.h> #include <linux/platform_device.h> #include <linux/clk-provider.h> +#include <linux/interconnect-clk.h> #include <linux/reset-controller.h> #include <linux/of.h> @@ -252,11 +253,42 @@ static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec, return cc->rclks[idx] ? &cc->rclks[idx]->hw : NULL; } -int qcom_cc_really_probe(struct platform_device *pdev, +static int qcom_cc_icc_register(struct device *dev, + const struct qcom_cc_desc *desc) +{ + struct icc_clk_data *icd; + struct clk_hw *hws; + int i; + + if (!IS_ENABLED(CONFIG_INTERCONNECT_CLK)) + return 0; + + if (!desc->icc_hws) + return 0; + + icd = devm_kcalloc(dev, desc->num_icc_hws, sizeof(*icd), GFP_KERNEL); + if (!icd) + return -ENOMEM; + + for (i = 0; i < desc->num_icc_hws; i++) { + icd[i].master_id = desc->icc_hws[i].master_id; + icd[i].slave_id = desc->icc_hws[i].slave_id; + hws = &desc->clks[desc->icc_hws[i].clk_id]->hw; + icd[i].clk = devm_clk_hw_get_clk(dev, hws, "icc"); + if (!icd[i].clk) + return dev_err_probe(dev, -ENOENT, + "(%d) clock entry is null\n", i); + icd[i].name = clk_hw_get_name(hws); + } + + return devm_icc_clk_register(dev, desc->icc_first_node_id, + desc->num_icc_hws, icd); +} + +int qcom_cc_really_probe(struct device *dev, const struct qcom_cc_desc *desc, struct regmap *regmap) { int i, ret; - struct device *dev = &pdev->dev; struct qcom_reset_controller *reset; struct qcom_cc *cc; struct gdsc_desc *scd; @@ -321,7 +353,7 @@ int qcom_cc_really_probe(struct platform_device *pdev, if (ret) return ret; - return 0; + return qcom_cc_icc_register(dev, desc); } EXPORT_SYMBOL_GPL(qcom_cc_really_probe); @@ -333,7 +365,7 @@ int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc) if (IS_ERR(regmap)) return PTR_ERR(regmap); - return qcom_cc_really_probe(pdev, desc, regmap); + return qcom_cc_really_probe(&pdev->dev, desc, regmap); } EXPORT_SYMBOL_GPL(qcom_cc_probe); @@ -351,8 +383,9 @@ int qcom_cc_probe_by_index(struct platform_device *pdev, int index, if (IS_ERR(regmap)) return PTR_ERR(regmap); - return qcom_cc_really_probe(pdev, desc, regmap); + return qcom_cc_really_probe(&pdev->dev, desc, regmap); } EXPORT_SYMBOL_GPL(qcom_cc_probe_by_index); MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("QTI Common Clock module"); diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h index 2d4a8a837e6c..7e57f8fe8ea6 100644 --- a/drivers/clk/qcom/common.h +++ b/drivers/clk/qcom/common.h @@ -19,6 +19,12 @@ struct clk_hw; #define PLL_VOTE_FSM_ENA BIT(20) #define PLL_VOTE_FSM_RESET BIT(21) +struct qcom_icc_hws_data { + int master_id; + int slave_id; + int clk_id; +}; + struct qcom_cc_desc { const struct regmap_config *config; struct clk_regmap **clks; @@ -29,6 +35,9 @@ struct qcom_cc_desc { size_t num_gdscs; struct clk_hw **clk_hws; size_t num_clk_hws; + struct qcom_icc_hws_data *icc_hws; + size_t num_icc_hws; + unsigned int icc_first_node_id; }; /** @@ -60,7 +69,7 @@ extern int qcom_cc_register_sleep_clk(struct device *dev); extern struct regmap *qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc); -extern int qcom_cc_really_probe(struct platform_device *pdev, +extern int qcom_cc_really_probe(struct device *dev, const struct qcom_cc_desc *desc, struct regmap *regmap); extern int qcom_cc_probe(struct platform_device *pdev, diff --git a/drivers/clk/qcom/dispcc-qcm2290.c b/drivers/clk/qcom/dispcc-qcm2290.c index 654a10d53e5c..449ffea2295d 100644 --- a/drivers/clk/qcom/dispcc-qcm2290.c +++ b/drivers/clk/qcom/dispcc-qcm2290.c @@ -522,7 +522,7 @@ static int disp_cc_qcm2290_probe(struct platform_device *pdev) /* Keep some clocks always-on */ qcom_branch_set_clk_en(regmap, 0x604c); /* DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(pdev, &disp_cc_qcm2290_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_qcm2290_desc, regmap); if (ret) { dev_err(&pdev->dev, "Failed to register DISP CC clocks\n"); return ret; diff --git a/drivers/clk/qcom/dispcc-sc7180.c b/drivers/clk/qcom/dispcc-sc7180.c index 38d7859981c7..4710247be530 100644 --- a/drivers/clk/qcom/dispcc-sc7180.c +++ b/drivers/clk/qcom/dispcc-sc7180.c @@ -713,7 +713,7 @@ static int disp_cc_sc7180_probe(struct platform_device *pdev) clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll_config); - return qcom_cc_really_probe(pdev, &disp_cc_sc7180_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &disp_cc_sc7180_desc, regmap); } static struct platform_driver disp_cc_sc7180_driver = { diff --git a/drivers/clk/qcom/dispcc-sc7280.c b/drivers/clk/qcom/dispcc-sc7280.c index fbeb8fccb99a..db0745954894 100644 --- a/drivers/clk/qcom/dispcc-sc7280.c +++ b/drivers/clk/qcom/dispcc-sc7280.c @@ -881,7 +881,7 @@ static int disp_cc_sc7280_probe(struct platform_device *pdev) /* Keep some clocks always-on */ qcom_branch_set_clk_en(regmap, 0x5008); /* DISP_CC_XO_CLK */ - return qcom_cc_really_probe(pdev, &disp_cc_sc7280_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &disp_cc_sc7280_desc, regmap); } static struct platform_driver disp_cc_sc7280_driver = { diff --git a/drivers/clk/qcom/dispcc-sc8280xp.c b/drivers/clk/qcom/dispcc-sc8280xp.c index 91172f5b2f15..f1ca9ae0b33f 100644 --- a/drivers/clk/qcom/dispcc-sc8280xp.c +++ b/drivers/clk/qcom/dispcc-sc8280xp.c @@ -3172,7 +3172,7 @@ static int disp_cc_sc8280xp_probe(struct platform_device *pdev) clk_lucid_pll_configure(clkr_to_alpha_clk_pll(desc->clks[DISP_CC_PLL1]), regmap, &disp_cc_pll1_config); clk_lucid_pll_configure(clkr_to_alpha_clk_pll(desc->clks[DISP_CC_PLL2]), regmap, &disp_cc_pll2_config); - ret = qcom_cc_really_probe(pdev, desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, desc, regmap); if (ret) { dev_err(&pdev->dev, "Failed to register display clock controller\n"); goto out_pm_runtime_put; diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c index b84fdd17c3d8..e6139e8f74dc 100644 --- a/drivers/clk/qcom/dispcc-sdm845.c +++ b/drivers/clk/qcom/dispcc-sdm845.c @@ -863,7 +863,7 @@ static int disp_cc_sdm845_probe(struct platform_device *pdev) /* Enable hardware clock gating for DSI and MDP clocks */ regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0); - return qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &disp_cc_sdm845_desc, regmap); } static struct platform_driver disp_cc_sdm845_driver = { diff --git a/drivers/clk/qcom/dispcc-sm6115.c b/drivers/clk/qcom/dispcc-sm6115.c index bd07f26af35a..939887f82ecc 100644 --- a/drivers/clk/qcom/dispcc-sm6115.c +++ b/drivers/clk/qcom/dispcc-sm6115.c @@ -586,7 +586,7 @@ static int disp_cc_sm6115_probe(struct platform_device *pdev) /* Keep some clocks always-on */ qcom_branch_set_clk_en(regmap, 0x604c); /* DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(pdev, &disp_cc_sm6115_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6115_desc, regmap); if (ret) { dev_err(&pdev->dev, "Failed to register DISP CC clocks\n"); return ret; diff --git a/drivers/clk/qcom/dispcc-sm6125.c b/drivers/clk/qcom/dispcc-sm6125.c index 1cc5f220a3c4..51c7492816fb 100644 --- a/drivers/clk/qcom/dispcc-sm6125.c +++ b/drivers/clk/qcom/dispcc-sm6125.c @@ -28,7 +28,7 @@ enum { P_GPLL0_OUT_MAIN, }; -static struct pll_vco disp_cc_pll_vco[] = { +static const struct pll_vco disp_cc_pll_vco[] = { { 500000000, 1000000000, 2 }, }; @@ -682,7 +682,7 @@ static int disp_cc_sm6125_probe(struct platform_device *pdev) clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); - return qcom_cc_really_probe(pdev, &disp_cc_sm6125_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6125_desc, regmap); } static struct platform_driver disp_cc_sm6125_driver = { diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c index e4b7464c4d0e..50facb36701a 100644 --- a/drivers/clk/qcom/dispcc-sm6350.c +++ b/drivers/clk/qcom/dispcc-sm6350.c @@ -31,7 +31,7 @@ enum { P_GCC_DISP_GPLL0_CLK, }; -static struct pll_vco fabia_vco[] = { +static const struct pll_vco fabia_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -761,7 +761,7 @@ static int disp_cc_sm6350_probe(struct platform_device *pdev) clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); - return qcom_cc_really_probe(pdev, &disp_cc_sm6350_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6350_desc, regmap); } static struct platform_driver disp_cc_sm6350_driver = { diff --git a/drivers/clk/qcom/dispcc-sm6375.c b/drivers/clk/qcom/dispcc-sm6375.c index d81d4e3c0b0d..167dd369a794 100644 --- a/drivers/clk/qcom/dispcc-sm6375.c +++ b/drivers/clk/qcom/dispcc-sm6375.c @@ -35,7 +35,7 @@ enum { P_GCC_DISP_GPLL0_CLK, }; -static struct pll_vco lucid_vco[] = { +static const struct pll_vco lucid_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -583,7 +583,7 @@ static int disp_cc_sm6375_probe(struct platform_device *pdev) clk_lucid_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); - return qcom_cc_really_probe(pdev, &disp_cc_sm6375_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6375_desc, regmap); } static struct platform_driver disp_cc_sm6375_driver = { diff --git a/drivers/clk/qcom/dispcc-sm7150.c b/drivers/clk/qcom/dispcc-sm7150.c new file mode 100644 index 000000000000..d32bd7df1433 --- /dev/null +++ b/drivers/clk/qcom/dispcc-sm7150.c @@ -0,0 +1,1006 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com> + * Copyright (c) 2024, David Wronek <david@mainlining.org> + */ + +#include <linux/clk-provider.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,sm7150-dispcc.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "gdsc.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_GCC_DISP_GPLL0_CLK, + DT_CHIP_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_DP_PHY_PLL_LINK_CLK, + DT_DP_PHY_PLL_VCO_DIV_CLK, +}; + +enum { + P_BI_TCXO, + P_CHIP_SLEEP_CLK, + P_DISPCC_PLL0_OUT_EVEN, + P_DISPCC_PLL0_OUT_MAIN, + P_DP_PHY_PLL_LINK_CLK, + P_DP_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_GCC_DISP_GPLL0_CLK, +}; + +static const struct pll_vco fabia_vco[] = { + { 249600000, 2000000000, 0 }, + { 125000000, 1000000000, 1 }, +}; + +/* 860MHz configuration */ +static const struct alpha_pll_config dispcc_pll0_config = { + .l = 0x2c, + .alpha = 0xcaaa, + .test_ctl_val = 0x40000000, +}; + +static struct clk_alpha_pll dispcc_pll0 = { + .offset = 0x0, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static const struct parent_map dispcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 }, +}; + +static const struct clk_parent_data dispcc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map dispcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_DP_PHY_PLL_LINK_CLK, 1 }, + { P_DP_PHY_PLL_VCO_DIV_CLK, 2 }, +}; + +static const struct clk_parent_data dispcc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP_PHY_PLL_LINK_CLK }, + { .index = DT_DP_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map dispcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data dispcc_parent_data_2[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct clk_parent_data dispcc_parent_data_2_ao[] = { + { .index = DT_BI_TCXO_AO }, +}; + +static const struct parent_map dispcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_DISPCC_PLL0_OUT_MAIN, 1 }, + { P_GCC_DISP_GPLL0_CLK, 4 }, + { P_DISPCC_PLL0_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data dispcc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &dispcc_pll0.clkr.hw }, + { .index = DT_GCC_DISP_GPLL0_CLK }, + { .hw = &dispcc_pll0.clkr.hw }, +}; + +static const struct parent_map dispcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 2 }, +}; + +static const struct clk_parent_data dispcc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, +}; + +static const struct parent_map dispcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GCC_DISP_GPLL0_CLK, 4 }, +}; + +static const struct clk_parent_data dispcc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .index = DT_GCC_DISP_GPLL0_CLK }, +}; + +static const struct parent_map dispcc_parent_map_6[] = { + { P_CHIP_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data dispcc_parent_data_6[] = { + { .index = DT_CHIP_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_dispcc_mdss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0), + F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0), + { } +}; + +static struct clk_rcg2 dispcc_mdss_ahb_clk_src = { + .cmd_rcgr = 0x22bc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_5, + .freq_tbl = ftbl_dispcc_mdss_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_ahb_clk_src", + .parent_data = dispcc_parent_data_5, + .num_parents = ARRAY_SIZE(dispcc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_dispcc_mdss_byte0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 dispcc_mdss_byte0_clk_src = { + .cmd_rcgr = 0x2110, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_0, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_byte0_clk_src", + .parent_data = dispcc_parent_data_0, + .num_parents = ARRAY_SIZE(dispcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 dispcc_mdss_byte1_clk_src = { + .cmd_rcgr = 0x212c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_0, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_byte1_clk_src", + .parent_data = dispcc_parent_data_0, + .num_parents = ARRAY_SIZE(dispcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 dispcc_mdss_dp_aux_clk_src = { + .cmd_rcgr = 0x21dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_2, + .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_dp_aux_clk_src", + .parent_data = dispcc_parent_data_2, + .num_parents = ARRAY_SIZE(dispcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_dispcc_mdss_dp_crypto_clk_src[] = { + F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0), + F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0), + F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0), + F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 dispcc_mdss_dp_crypto_clk_src = { + .cmd_rcgr = 0x2194, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_1, + .freq_tbl = ftbl_dispcc_mdss_dp_crypto_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_dp_crypto_clk_src", + .parent_data = dispcc_parent_data_1, + .num_parents = ARRAY_SIZE(dispcc_parent_data_1), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 dispcc_mdss_dp_link_clk_src = { + .cmd_rcgr = 0x2178, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_1, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_dp_link_clk_src", + .parent_data = dispcc_parent_data_1, + .num_parents = ARRAY_SIZE(dispcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 dispcc_mdss_dp_pixel1_clk_src = { + .cmd_rcgr = 0x21c4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = dispcc_parent_map_1, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_dp_pixel1_clk_src", + .parent_data = dispcc_parent_data_1, + .num_parents = ARRAY_SIZE(dispcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 dispcc_mdss_dp_pixel_clk_src = { + .cmd_rcgr = 0x21ac, + .mnd_width = 16, + .hid_width = 5, + .parent_map = dispcc_parent_map_1, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_dp_pixel_clk_src", + .parent_data = dispcc_parent_data_1, + .num_parents = ARRAY_SIZE(dispcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 dispcc_mdss_esc0_clk_src = { + .cmd_rcgr = 0x2148, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_0, + .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_esc0_clk_src", + .parent_data = dispcc_parent_data_0, + .num_parents = ARRAY_SIZE(dispcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 dispcc_mdss_esc1_clk_src = { + .cmd_rcgr = 0x2160, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_0, + .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_esc1_clk_src", + .parent_data = dispcc_parent_data_0, + .num_parents = ARRAY_SIZE(dispcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_dispcc_mdss_mdp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(85714286, P_GCC_DISP_GPLL0_CLK, 7, 0, 0), + F(100000000, P_GCC_DISP_GPLL0_CLK, 6, 0, 0), + F(150000000, P_GCC_DISP_GPLL0_CLK, 4, 0, 0), + F(172000000, P_DISPCC_PLL0_OUT_MAIN, 5, 0, 0), + F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0), + F(286666667, P_DISPCC_PLL0_OUT_MAIN, 3, 0, 0), + F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0), + F(344000000, P_DISPCC_PLL0_OUT_MAIN, 2.5, 0, 0), + F(430000000, P_DISPCC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 dispcc_mdss_mdp_clk_src = { + .cmd_rcgr = 0x20c8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_3, + .freq_tbl = ftbl_dispcc_mdss_mdp_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_mdp_clk_src", + .parent_data = dispcc_parent_data_3, + .num_parents = ARRAY_SIZE(dispcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 dispcc_mdss_pclk0_clk_src = { + .cmd_rcgr = 0x2098, + .mnd_width = 8, + .hid_width = 5, + .parent_map = dispcc_parent_map_4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_pclk0_clk_src", + .parent_data = dispcc_parent_data_4, + .num_parents = ARRAY_SIZE(dispcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 dispcc_mdss_pclk1_clk_src = { + .cmd_rcgr = 0x20b0, + .mnd_width = 8, + .hid_width = 5, + .parent_map = dispcc_parent_map_4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_pclk1_clk_src", + .parent_data = dispcc_parent_data_4, + .num_parents = ARRAY_SIZE(dispcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static const struct freq_tbl ftbl_dispcc_mdss_rot_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(171428571, P_GCC_DISP_GPLL0_CLK, 3.5, 0, 0), + F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0), + F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0), + F(344000000, P_DISPCC_PLL0_OUT_MAIN, 2.5, 0, 0), + F(430000000, P_DISPCC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 dispcc_mdss_rot_clk_src = { + .cmd_rcgr = 0x20e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_3, + .freq_tbl = ftbl_dispcc_mdss_rot_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_rot_clk_src", + .parent_data = dispcc_parent_data_3, + .num_parents = ARRAY_SIZE(dispcc_parent_data_3), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 dispcc_mdss_vsync_clk_src = { + .cmd_rcgr = 0x20f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_2, + .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_vsync_clk_src", + .parent_data = dispcc_parent_data_2, + .num_parents = ARRAY_SIZE(dispcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_dispcc_sleep_clk_src[] = { + F(32000, P_CHIP_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 dispcc_sleep_clk_src = { + .cmd_rcgr = 0x6060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_6, + .freq_tbl = ftbl_dispcc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_sleep_clk_src", + .parent_data = dispcc_parent_data_6, + .num_parents = ARRAY_SIZE(dispcc_parent_data_6), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 dispcc_xo_clk_src = { + .cmd_rcgr = 0x6044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = dispcc_parent_map_2, + .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "dispcc_xo_clk_src", + .parent_data = dispcc_parent_data_2_ao, + .num_parents = ARRAY_SIZE(dispcc_parent_data_2_ao), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch dispcc_mdss_ahb_clk = { + .halt_reg = 0x2080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_byte0_clk = { + .halt_reg = 0x2028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_byte0_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap_div dispcc_mdss_byte0_div_clk_src = { + .reg = 0x2128, + .shift = 0, + .width = 2, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_byte0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_byte0_intf_clk = { + .halt_reg = 0x202c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x202c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_byte0_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_byte0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_byte1_clk = { + .halt_reg = 0x2030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_byte1_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap_div dispcc_mdss_byte1_div_clk_src = { + .reg = 0x2144, + .shift = 0, + .width = 2, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_byte1_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_byte1_intf_clk = { + .halt_reg = 0x2034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_byte1_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_byte1_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_dp_aux_clk = { + .halt_reg = 0x2054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_dp_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_dp_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_dp_crypto_clk = { + .halt_reg = 0x2048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_dp_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_dp_crypto_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_dp_link_clk = { + .halt_reg = 0x2040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_dp_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_dp_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_dp_link_intf_clk = { + .halt_reg = 0x2044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_dp_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_dp_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_dp_pixel1_clk = { + .halt_reg = 0x2050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_dp_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_dp_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_dp_pixel_clk = { + .halt_reg = 0x204c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x204c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_dp_pixel_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_dp_pixel_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_esc0_clk = { + .halt_reg = 0x2038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_esc0_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_esc0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_esc1_clk = { + .halt_reg = 0x203c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x203c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_esc1_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_esc1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_mdp_clk = { + .halt_reg = 0x200c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_mdp_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_mdp_lut_clk = { + .halt_reg = 0x201c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x201c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_mdp_lut_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_non_gdsc_ahb_clk = { + .halt_reg = 0x4004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_non_gdsc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_pclk0_clk = { + .halt_reg = 0x2004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_pclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_pclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_pclk1_clk = { + .halt_reg = 0x2008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_pclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_pclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_rot_clk = { + .halt_reg = 0x2014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_rot_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_rot_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_rscc_ahb_clk = { + .halt_reg = 0x400c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x400c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_rscc_ahb_clk", + .parent_names = (const char *[]) { + "dispcc_mdss_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_rscc_vsync_clk = { + .halt_reg = 0x4008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_rscc_vsync_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_mdss_vsync_clk = { + .halt_reg = 0x2024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_mdss_vsync_clk", + .parent_hws = (const struct clk_hw*[]) { + &dispcc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch dispcc_sleep_clk = { + .halt_reg = 0x6078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "dispcc_sleep_clk", + .parent_names = (const char *[]) { + "dispcc_sleep_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc mdss_gdsc = { + .gdscr = 0x3000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "mdss_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL, +}; + +static struct clk_regmap *dispcc_sm7150_clocks[] = { + [DISPCC_MDSS_AHB_CLK] = &dispcc_mdss_ahb_clk.clkr, + [DISPCC_MDSS_AHB_CLK_SRC] = &dispcc_mdss_ahb_clk_src.clkr, + [DISPCC_MDSS_BYTE0_CLK] = &dispcc_mdss_byte0_clk.clkr, + [DISPCC_MDSS_BYTE0_CLK_SRC] = &dispcc_mdss_byte0_clk_src.clkr, + [DISPCC_MDSS_BYTE0_DIV_CLK_SRC] = &dispcc_mdss_byte0_div_clk_src.clkr, + [DISPCC_MDSS_BYTE0_INTF_CLK] = &dispcc_mdss_byte0_intf_clk.clkr, + [DISPCC_MDSS_BYTE1_CLK] = &dispcc_mdss_byte1_clk.clkr, + [DISPCC_MDSS_BYTE1_CLK_SRC] = &dispcc_mdss_byte1_clk_src.clkr, + [DISPCC_MDSS_BYTE1_DIV_CLK_SRC] = &dispcc_mdss_byte1_div_clk_src.clkr, + [DISPCC_MDSS_BYTE1_INTF_CLK] = &dispcc_mdss_byte1_intf_clk.clkr, + [DISPCC_MDSS_DP_AUX_CLK] = &dispcc_mdss_dp_aux_clk.clkr, + [DISPCC_MDSS_DP_AUX_CLK_SRC] = &dispcc_mdss_dp_aux_clk_src.clkr, + [DISPCC_MDSS_DP_CRYPTO_CLK] = &dispcc_mdss_dp_crypto_clk.clkr, + [DISPCC_MDSS_DP_CRYPTO_CLK_SRC] = &dispcc_mdss_dp_crypto_clk_src.clkr, + [DISPCC_MDSS_DP_LINK_CLK] = &dispcc_mdss_dp_link_clk.clkr, + [DISPCC_MDSS_DP_LINK_CLK_SRC] = &dispcc_mdss_dp_link_clk_src.clkr, + [DISPCC_MDSS_DP_LINK_INTF_CLK] = &dispcc_mdss_dp_link_intf_clk.clkr, + [DISPCC_MDSS_DP_PIXEL1_CLK] = &dispcc_mdss_dp_pixel1_clk.clkr, + [DISPCC_MDSS_DP_PIXEL1_CLK_SRC] = &dispcc_mdss_dp_pixel1_clk_src.clkr, + [DISPCC_MDSS_DP_PIXEL_CLK] = &dispcc_mdss_dp_pixel_clk.clkr, + [DISPCC_MDSS_DP_PIXEL_CLK_SRC] = &dispcc_mdss_dp_pixel_clk_src.clkr, + [DISPCC_MDSS_ESC0_CLK] = &dispcc_mdss_esc0_clk.clkr, + [DISPCC_MDSS_ESC0_CLK_SRC] = &dispcc_mdss_esc0_clk_src.clkr, + [DISPCC_MDSS_ESC1_CLK] = &dispcc_mdss_esc1_clk.clkr, + [DISPCC_MDSS_ESC1_CLK_SRC] = &dispcc_mdss_esc1_clk_src.clkr, + [DISPCC_MDSS_MDP_CLK] = &dispcc_mdss_mdp_clk.clkr, + [DISPCC_MDSS_MDP_CLK_SRC] = &dispcc_mdss_mdp_clk_src.clkr, + [DISPCC_MDSS_MDP_LUT_CLK] = &dispcc_mdss_mdp_lut_clk.clkr, + [DISPCC_MDSS_NON_GDSC_AHB_CLK] = &dispcc_mdss_non_gdsc_ahb_clk.clkr, + [DISPCC_MDSS_PCLK0_CLK] = &dispcc_mdss_pclk0_clk.clkr, + [DISPCC_MDSS_PCLK0_CLK_SRC] = &dispcc_mdss_pclk0_clk_src.clkr, + [DISPCC_MDSS_PCLK1_CLK] = &dispcc_mdss_pclk1_clk.clkr, + [DISPCC_MDSS_PCLK1_CLK_SRC] = &dispcc_mdss_pclk1_clk_src.clkr, + [DISPCC_MDSS_ROT_CLK] = &dispcc_mdss_rot_clk.clkr, + [DISPCC_MDSS_ROT_CLK_SRC] = &dispcc_mdss_rot_clk_src.clkr, + [DISPCC_MDSS_RSCC_AHB_CLK] = &dispcc_mdss_rscc_ahb_clk.clkr, + [DISPCC_MDSS_RSCC_VSYNC_CLK] = &dispcc_mdss_rscc_vsync_clk.clkr, + [DISPCC_MDSS_VSYNC_CLK] = &dispcc_mdss_vsync_clk.clkr, + [DISPCC_MDSS_VSYNC_CLK_SRC] = &dispcc_mdss_vsync_clk_src.clkr, + [DISPCC_PLL0] = &dispcc_pll0.clkr, + [DISPCC_SLEEP_CLK] = &dispcc_sleep_clk.clkr, + [DISPCC_SLEEP_CLK_SRC] = &dispcc_sleep_clk_src.clkr, + [DISPCC_XO_CLK_SRC] = &dispcc_xo_clk_src.clkr, +}; + +static struct gdsc *dispcc_sm7150_gdscs[] = { + [MDSS_GDSC] = &mdss_gdsc, +}; + +static const struct regmap_config dispcc_sm7150_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x10000, + .fast_io = true, +}; + +static const struct qcom_cc_desc dispcc_sm7150_desc = { + .config = &dispcc_sm7150_regmap_config, + .clks = dispcc_sm7150_clocks, + .num_clks = ARRAY_SIZE(dispcc_sm7150_clocks), + .gdscs = dispcc_sm7150_gdscs, + .num_gdscs = ARRAY_SIZE(dispcc_sm7150_gdscs), +}; + +static const struct of_device_id dispcc_sm7150_match_table[] = { + { .compatible = "qcom,sm7150-dispcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, dispcc_sm7150_match_table); + +static int dispcc_sm7150_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &dispcc_sm7150_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + clk_fabia_pll_configure(&dispcc_pll0, regmap, &dispcc_pll0_config); + /* Enable clock gating for DSI and MDP clocks */ + regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0); + + /* Keep some clocks always-on */ + qcom_branch_set_clk_en(regmap, 0x605c); /* DISPCC_XO_CLK */ + + return qcom_cc_really_probe(&pdev->dev, &dispcc_sm7150_desc, regmap); +} + +static struct platform_driver dispcc_sm7150_driver = { + .probe = dispcc_sm7150_probe, + .driver = { + .name = "dispcc-sm7150", + .of_match_table = dispcc_sm7150_match_table, + }, +}; + +module_platform_driver(dispcc_sm7150_driver); + +MODULE_DESCRIPTION("Qualcomm SM7150 Display Clock Controller"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c index 43307c8a342c..5a09009b7289 100644 --- a/drivers/clk/qcom/dispcc-sm8250.c +++ b/drivers/clk/qcom/dispcc-sm8250.c @@ -1366,7 +1366,7 @@ static int disp_cc_sm8250_probe(struct platform_device *pdev) /* Keep some clocks always-on */ qcom_branch_set_clk_en(regmap, 0x605c); /* DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(pdev, &disp_cc_sm8250_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8250_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/dispcc-sm8450.c b/drivers/clk/qcom/dispcc-sm8450.c index 49bb4f58c391..d1d3f60789ee 100644 --- a/drivers/clk/qcom/dispcc-sm8450.c +++ b/drivers/clk/qcom/dispcc-sm8450.c @@ -71,7 +71,7 @@ enum { P_SLEEP_CLK, }; -static struct pll_vco lucid_evo_vco[] = { +static const struct pll_vco lucid_evo_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -1778,7 +1778,7 @@ static int disp_cc_sm8450_probe(struct platform_device *pdev) /* Keep some clocks always-on */ qcom_branch_set_clk_en(regmap, 0xe05c); /* DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(pdev, &disp_cc_sm8450_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8450_desc, regmap); if (ret) goto err_put_rpm; diff --git a/drivers/clk/qcom/dispcc-sm8550.c b/drivers/clk/qcom/dispcc-sm8550.c index 38ecea805503..31ae46f180a5 100644 --- a/drivers/clk/qcom/dispcc-sm8550.c +++ b/drivers/clk/qcom/dispcc-sm8550.c @@ -71,7 +71,7 @@ enum { P_SLEEP_CLK, }; -static struct pll_vco lucid_ole_vco[] = { +static const struct pll_vco lucid_ole_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -1771,7 +1771,7 @@ static int disp_cc_sm8550_probe(struct platform_device *pdev) /* Keep some clocks always-on */ qcom_branch_set_clk_en(regmap, 0xe054); /* DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(pdev, &disp_cc_sm8550_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8550_desc, regmap); if (ret) goto err_put_rpm; diff --git a/drivers/clk/qcom/dispcc-sm8650.c b/drivers/clk/qcom/dispcc-sm8650.c index 3eb64bcad487..c9d2751f5cb8 100644 --- a/drivers/clk/qcom/dispcc-sm8650.c +++ b/drivers/clk/qcom/dispcc-sm8650.c @@ -69,7 +69,7 @@ enum { P_SLEEP_CLK, }; -static struct pll_vco lucid_ole_vco[] = { +static const struct pll_vco lucid_ole_vco[] = { { 249600000, 2100000000, 0 }, }; @@ -1768,7 +1768,7 @@ static int disp_cc_sm8650_probe(struct platform_device *pdev) /* Keep some clocks always-on */ qcom_branch_set_clk_en(regmap, 0xe054); /* DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(pdev, &disp_cc_sm8650_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8650_desc, regmap); if (ret) goto err_put_rpm; diff --git a/drivers/clk/qcom/dispcc-x1e80100.c b/drivers/clk/qcom/dispcc-x1e80100.c index 0b2ee6456762..40069eba41f2 100644 --- a/drivers/clk/qcom/dispcc-x1e80100.c +++ b/drivers/clk/qcom/dispcc-x1e80100.c @@ -1680,7 +1680,7 @@ static int disp_cc_x1e80100_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0xe074); /* DISP_CC_SLEEP_CLK */ qcom_branch_set_clk_en(regmap, 0xe054); /* DISP_CC_XO_CLK */ - ret = qcom_cc_really_probe(pdev, &disp_cc_x1e80100_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_x1e80100_desc, regmap); if (ret) goto err_put_rpm; diff --git a/drivers/clk/qcom/ecpricc-qdu1000.c b/drivers/clk/qcom/ecpricc-qdu1000.c index c628054a7025..dbc11260479b 100644 --- a/drivers/clk/qcom/ecpricc-qdu1000.c +++ b/drivers/clk/qcom/ecpricc-qdu1000.c @@ -2439,7 +2439,7 @@ static int ecpri_cc_qdu1000_probe(struct platform_device *pdev) clk_lucid_evo_pll_configure(&ecpri_cc_pll0, regmap, &ecpri_cc_pll0_config); clk_lucid_evo_pll_configure(&ecpri_cc_pll1, regmap, &ecpri_cc_pll1_config); - return qcom_cc_really_probe(pdev, &ecpri_cc_qdu1000_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &ecpri_cc_qdu1000_desc, regmap); } static struct platform_driver ecpri_cc_qdu1000_driver = { diff --git a/drivers/clk/qcom/gcc-ipq5018.c b/drivers/clk/qcom/gcc-ipq5018.c index c1732d70e3a2..70f5dcb96700 100644 --- a/drivers/clk/qcom/gcc-ipq5018.c +++ b/drivers/clk/qcom/gcc-ipq5018.c @@ -3698,7 +3698,7 @@ static int gcc_ipq5018_probe(struct platform_device *pdev) clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config); - return qcom_cc_really_probe(pdev, &ipq5018_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &ipq5018_desc, regmap); } static struct platform_driver gcc_ipq5018_driver = { diff --git a/drivers/clk/qcom/gcc-ipq6018.c b/drivers/clk/qcom/gcc-ipq6018.c index 7e69de34c310..2e411d874662 100644 --- a/drivers/clk/qcom/gcc-ipq6018.c +++ b/drivers/clk/qcom/gcc-ipq6018.c @@ -1617,7 +1617,7 @@ static const struct freq_tbl ftbl_sdcc_apps_clk_src[] = { F(96000000, P_GPLL2, 12, 0, 0), F(177777778, P_GPLL0, 4.5, 0, 0), F(192000000, P_GPLL2, 6, 0, 0), - F(384000000, P_GPLL2, 3, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), { } }; @@ -4642,7 +4642,7 @@ static int gcc_ipq6018_probe(struct platform_device *pdev) clk_alpha_pll_configure(&nss_crypto_pll_main, regmap, &nss_crypto_pll_config); - return qcom_cc_really_probe(pdev, &gcc_ipq6018_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_ipq6018_desc, regmap); } static struct platform_driver gcc_ipq6018_driver = { diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c index d2be56c5892d..32fd01ef469a 100644 --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c @@ -4760,7 +4760,7 @@ static int gcc_ipq8074_probe(struct platform_device *pdev) clk_alpha_pll_configure(&nss_crypto_pll_main, regmap, &nss_crypto_pll_config); - return qcom_cc_really_probe(pdev, &gcc_ipq8074_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_ipq8074_desc, regmap); } static struct platform_driver gcc_ipq8074_driver = { diff --git a/drivers/clk/qcom/gcc-ipq9574.c b/drivers/clk/qcom/gcc-ipq9574.c index 0a3f846695b8..f08a447370bd 100644 --- a/drivers/clk/qcom/gcc-ipq9574.c +++ b/drivers/clk/qcom/gcc-ipq9574.c @@ -4,6 +4,8 @@ */ #include <linux/clk-provider.h> +#include <linux/interconnect-clk.h> +#include <linux/interconnect-provider.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> @@ -12,6 +14,7 @@ #include <dt-bindings/clock/qcom,ipq9574-gcc.h> #include <dt-bindings/reset/qcom,ipq9574-gcc.h> +#include <dt-bindings/interconnect/qcom,ipq9574.h> #include "clk-alpha-pll.h" #include "clk-branch.h" @@ -1569,6 +1572,24 @@ static struct clk_regmap_phy_mux pcie0_pipe_clk_src = { }, }; +static struct clk_branch gcc_pcie0_pipe_clk = { + .halt_reg = 0x28044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x28044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie0_pipe_clk", + .parent_hws = (const struct clk_hw *[]) { + &pcie0_pipe_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_regmap_phy_mux pcie1_pipe_clk_src = { .reg = 0x29064, .clkr = { @@ -1583,6 +1604,24 @@ static struct clk_regmap_phy_mux pcie1_pipe_clk_src = { }, }; +static struct clk_branch gcc_pcie1_pipe_clk = { + .halt_reg = 0x29044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x29044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie1_pipe_clk", + .parent_hws = (const struct clk_hw *[]) { + &pcie1_pipe_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_regmap_phy_mux pcie2_pipe_clk_src = { .reg = 0x2a064, .clkr = { @@ -1597,6 +1636,24 @@ static struct clk_regmap_phy_mux pcie2_pipe_clk_src = { }, }; +static struct clk_branch gcc_pcie2_pipe_clk = { + .halt_reg = 0x2a044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x2a044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie2_pipe_clk", + .parent_hws = (const struct clk_hw *[]) { + &pcie2_pipe_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_regmap_phy_mux pcie3_pipe_clk_src = { .reg = 0x2b064, .clkr = { @@ -1611,6 +1668,24 @@ static struct clk_regmap_phy_mux pcie3_pipe_clk_src = { }, }; +static struct clk_branch gcc_pcie3_pipe_clk = { + .halt_reg = 0x2b044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x2b044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie3_pipe_clk", + .parent_hws = (const struct clk_hw *[]) { + &pcie3_pipe_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static const struct freq_tbl ftbl_pcie_rchng_clk_src[] = { F(24000000, P_XO, 1, 0, 0), F(100000000, P_GPLL0, 8, 0, 0), @@ -4141,6 +4216,10 @@ static struct clk_regmap *gcc_ipq9574_clks[] = { [GCC_SNOC_PCIE1_1LANE_S_CLK] = &gcc_snoc_pcie1_1lane_s_clk.clkr, [GCC_SNOC_PCIE2_2LANE_S_CLK] = &gcc_snoc_pcie2_2lane_s_clk.clkr, [GCC_SNOC_PCIE3_2LANE_S_CLK] = &gcc_snoc_pcie3_2lane_s_clk.clkr, + [GCC_PCIE0_PIPE_CLK] = &gcc_pcie0_pipe_clk.clkr, + [GCC_PCIE1_PIPE_CLK] = &gcc_pcie1_pipe_clk.clkr, + [GCC_PCIE2_PIPE_CLK] = &gcc_pcie2_pipe_clk.clkr, + [GCC_PCIE3_PIPE_CLK] = &gcc_pcie3_pipe_clk.clkr, }; static const struct qcom_reset_map gcc_ipq9574_resets[] = { @@ -4301,6 +4380,32 @@ static const struct qcom_reset_map gcc_ipq9574_resets[] = { [GCC_WCSS_Q6_TBU_BCR] = { 0x12054, 0 }, }; +#define IPQ_APPS_ID 9574 /* some unique value */ + +static struct qcom_icc_hws_data icc_ipq9574_hws[] = { + { MASTER_ANOC_PCIE0, SLAVE_ANOC_PCIE0, GCC_ANOC_PCIE0_1LANE_M_CLK }, + { MASTER_SNOC_PCIE0, SLAVE_SNOC_PCIE0, GCC_SNOC_PCIE0_1LANE_S_CLK }, + { MASTER_ANOC_PCIE1, SLAVE_ANOC_PCIE1, GCC_ANOC_PCIE1_1LANE_M_CLK }, + { MASTER_SNOC_PCIE1, SLAVE_SNOC_PCIE1, GCC_SNOC_PCIE1_1LANE_S_CLK }, + { MASTER_ANOC_PCIE2, SLAVE_ANOC_PCIE2, GCC_ANOC_PCIE2_2LANE_M_CLK }, + { MASTER_SNOC_PCIE2, SLAVE_SNOC_PCIE2, GCC_SNOC_PCIE2_2LANE_S_CLK }, + { MASTER_ANOC_PCIE3, SLAVE_ANOC_PCIE3, GCC_ANOC_PCIE3_2LANE_M_CLK }, + { MASTER_SNOC_PCIE3, SLAVE_SNOC_PCIE3, GCC_SNOC_PCIE3_2LANE_S_CLK }, + { MASTER_USB, SLAVE_USB, GCC_SNOC_USB_CLK }, + { MASTER_USB_AXI, SLAVE_USB_AXI, GCC_ANOC_USB_AXI_CLK }, + { MASTER_NSSNOC_NSSCC, SLAVE_NSSNOC_NSSCC, GCC_NSSNOC_NSSCC_CLK }, + { MASTER_NSSNOC_SNOC_0, SLAVE_NSSNOC_SNOC_0, GCC_NSSNOC_SNOC_CLK }, + { MASTER_NSSNOC_SNOC_1, SLAVE_NSSNOC_SNOC_1, GCC_NSSNOC_SNOC_1_CLK }, + { MASTER_NSSNOC_PCNOC_1, SLAVE_NSSNOC_PCNOC_1, GCC_NSSNOC_PCNOC_1_CLK }, + { MASTER_NSSNOC_QOSGEN_REF, SLAVE_NSSNOC_QOSGEN_REF, GCC_NSSNOC_QOSGEN_REF_CLK }, + { MASTER_NSSNOC_TIMEOUT_REF, SLAVE_NSSNOC_TIMEOUT_REF, GCC_NSSNOC_TIMEOUT_REF_CLK }, + { MASTER_NSSNOC_XO_DCD, SLAVE_NSSNOC_XO_DCD, GCC_NSSNOC_XO_DCD_CLK }, + { MASTER_NSSNOC_ATB, SLAVE_NSSNOC_ATB, GCC_NSSNOC_ATB_CLK }, + { MASTER_MEM_NOC_NSSNOC, SLAVE_MEM_NOC_NSSNOC, GCC_MEM_NOC_NSSNOC_CLK }, + { MASTER_NSSNOC_MEMNOC, SLAVE_NSSNOC_MEMNOC, GCC_NSSNOC_MEMNOC_CLK }, + { MASTER_NSSNOC_MEM_NOC_1, SLAVE_NSSNOC_MEM_NOC_1, GCC_NSSNOC_MEM_NOC_1_CLK }, +}; + static const struct of_device_id gcc_ipq9574_match_table[] = { { .compatible = "qcom,ipq9574-gcc" }, { } @@ -4323,6 +4428,9 @@ static const struct qcom_cc_desc gcc_ipq9574_desc = { .num_resets = ARRAY_SIZE(gcc_ipq9574_resets), .clk_hws = gcc_ipq9574_hws, .num_clk_hws = ARRAY_SIZE(gcc_ipq9574_hws), + .icc_hws = icc_ipq9574_hws, + .num_icc_hws = ARRAY_SIZE(icc_ipq9574_hws), + .icc_first_node_id = IPQ_APPS_ID, }; static int gcc_ipq9574_probe(struct platform_device *pdev) @@ -4335,6 +4443,7 @@ static struct platform_driver gcc_ipq9574_driver = { .driver = { .name = "qcom,gcc-ipq9574", .of_match_table = gcc_ipq9574_match_table, + .sync_state = icc_sync_state, }, }; diff --git a/drivers/clk/qcom/gcc-mdm9607.c b/drivers/clk/qcom/gcc-mdm9607.c index fb290e73ce94..6e6068b168e6 100644 --- a/drivers/clk/qcom/gcc-mdm9607.c +++ b/drivers/clk/qcom/gcc-mdm9607.c @@ -1604,7 +1604,7 @@ static int gcc_mdm9607_probe(struct platform_device *pdev) /* Vote for GPLL0 to turn on. Needed by acpuclock. */ regmap_update_bits(regmap, 0x45000, BIT(0), BIT(0)); - return qcom_cc_really_probe(pdev, &gcc_mdm9607_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_mdm9607_desc, regmap); } static struct platform_driver gcc_mdm9607_driver = { diff --git a/drivers/clk/qcom/gcc-mdm9615.c b/drivers/clk/qcom/gcc-mdm9615.c index aec7c4a1d3de..33987b957737 100644 --- a/drivers/clk/qcom/gcc-mdm9615.c +++ b/drivers/clk/qcom/gcc-mdm9615.c @@ -1736,7 +1736,7 @@ static int gcc_mdm9615_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); - return qcom_cc_really_probe(pdev, &gcc_mdm9615_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_mdm9615_desc, regmap); } static struct platform_driver gcc_mdm9615_driver = { diff --git a/drivers/clk/qcom/gcc-msm8917.c b/drivers/clk/qcom/gcc-msm8917.c index f2b8729e4198..3e2a2ae2ee6e 100644 --- a/drivers/clk/qcom/gcc-msm8917.c +++ b/drivers/clk/qcom/gcc-msm8917.c @@ -3270,7 +3270,7 @@ static int gcc_msm8917_probe(struct platform_device *pdev) clk_alpha_pll_configure(&gpll3_early, regmap, &gpll3_early_config); - return qcom_cc_really_probe(pdev, gcc_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, gcc_desc, regmap); } static const struct of_device_id gcc_msm8917_match_table[] = { diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c index 7b9a3e99b589..7431c9a65044 100644 --- a/drivers/clk/qcom/gcc-msm8939.c +++ b/drivers/clk/qcom/gcc-msm8939.c @@ -4108,7 +4108,7 @@ static int gcc_msm8939_probe(struct platform_device *pdev) clk_pll_configure_sr_hpm_lp(&gpll3, regmap, &gpll3_config, true); clk_pll_configure_sr_hpm_lp(&gpll4, regmap, &gpll4_config, true); - return qcom_cc_really_probe(pdev, &gcc_msm8939_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_msm8939_desc, regmap); } static struct platform_driver gcc_msm8939_driver = { diff --git a/drivers/clk/qcom/gcc-msm8953.c b/drivers/clk/qcom/gcc-msm8953.c index 7563bff58118..855a61966f3e 100644 --- a/drivers/clk/qcom/gcc-msm8953.c +++ b/drivers/clk/qcom/gcc-msm8953.c @@ -4220,7 +4220,7 @@ static int gcc_msm8953_probe(struct platform_device *pdev) clk_alpha_pll_configure(&gpll3_early, regmap, &gpll3_early_config); - return qcom_cc_really_probe(pdev, &gcc_msm8953_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_msm8953_desc, regmap); } static const struct of_device_id gcc_msm8953_match_table[] = { diff --git a/drivers/clk/qcom/gcc-msm8976.c b/drivers/clk/qcom/gcc-msm8976.c index f60a8171972b..399f22033c29 100644 --- a/drivers/clk/qcom/gcc-msm8976.c +++ b/drivers/clk/qcom/gcc-msm8976.c @@ -4129,7 +4129,7 @@ static int gcc_msm8976_probe(struct platform_device *pdev) if (ret) return ret; - return qcom_cc_really_probe(pdev, &gcc_msm8976_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_msm8976_desc, regmap); } static struct platform_driver gcc_msm8976_driver = { @@ -4154,3 +4154,4 @@ module_exit(gcc_msm8976_exit); MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>"); MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("QTI MSM8996 Global Clock Controller"); diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index e7b03a17514a..4fc667b94cf2 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -3620,7 +3620,7 @@ static int gcc_msm8996_probe(struct platform_device *pdev) */ regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21)); - return qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_msm8996_desc, regmap); } static struct platform_driver gcc_msm8996_driver = { diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c index cad7f1c7789c..90b66caba2cd 100644 --- a/drivers/clk/qcom/gcc-msm8998.c +++ b/drivers/clk/qcom/gcc-msm8998.c @@ -27,7 +27,7 @@ #define GCC_MMSS_MISC 0x0902C #define GCC_GPU_MISC 0x71028 -static struct pll_vco fabia_vco[] = { +static const struct pll_vco fabia_vco[] = { { 250000000, 2000000000, 0 }, { 125000000, 1000000000, 1 }, }; @@ -3292,7 +3292,7 @@ static int gcc_msm8998_probe(struct platform_device *pdev) regmap_write(regmap, GCC_MMSS_MISC, 0x10003); regmap_write(regmap, GCC_GPU_MISC, 0x10003); - return qcom_cc_really_probe(pdev, &gcc_msm8998_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_msm8998_desc, regmap); } static const struct of_device_id gcc_msm8998_match_table[] = { diff --git a/drivers/clk/qcom/gcc-qcm2290.c b/drivers/clk/qcom/gcc-qcm2290.c index 48995e50c6bd..9a6703365e61 100644 --- a/drivers/clk/qcom/gcc-qcm2290.c +++ b/drivers/clk/qcom/gcc-qcm2290.c @@ -2994,7 +2994,7 @@ static int gcc_qcm2290_probe(struct platform_device *pdev) clk_alpha_pll_configure(&gpll8, regmap, &gpll8_config); clk_alpha_pll_configure(&gpll9, regmap, &gpll9_config); - return qcom_cc_really_probe(pdev, &gcc_qcm2290_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_qcm2290_desc, regmap); } static struct platform_driver gcc_qcm2290_driver = { diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c index a39c4990b29d..c3cfd572e7c1 100644 --- a/drivers/clk/qcom/gcc-qcs404.c +++ b/drivers/clk/qcom/gcc-qcs404.c @@ -2824,7 +2824,7 @@ static int gcc_qcs404_probe(struct platform_device *pdev) clk_alpha_pll_configure(&gpll3_out_main, regmap, &gpll3_config); - return qcom_cc_really_probe(pdev, &gcc_qcs404_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_qcs404_desc, regmap); } static struct platform_driver gcc_qcs404_driver = { diff --git a/drivers/clk/qcom/gcc-qdu1000.c b/drivers/clk/qcom/gcc-qdu1000.c index 9f42d2601464..dbe9e9437939 100644 --- a/drivers/clk/qcom/gcc-qdu1000.c +++ b/drivers/clk/qcom/gcc-qdu1000.c @@ -2674,7 +2674,7 @@ static int gcc_qdu1000_probe(struct platform_device *pdev) if (ret) return ret; - ret = qcom_cc_really_probe(pdev, &gcc_qdu1000_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &gcc_qdu1000_desc, regmap); if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to register GCC clocks\n"); diff --git a/drivers/clk/qcom/gcc-sa8775p.c b/drivers/clk/qcom/gcc-sa8775p.c index 5bcbfbf52cb9..e7425e82c54f 100644 --- a/drivers/clk/qcom/gcc-sa8775p.c +++ b/drivers/clk/qcom/gcc-sa8775p.c @@ -1,14 +1,12 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, 2024, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2023, Linaro Limited */ -#include <linux/clk.h> #include <linux/clk-provider.h> -#include <linux/err.h> -#include <linux/kernel.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/regmap.h> @@ -1737,26 +1735,6 @@ static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { }, }; -static struct clk_branch gcc_aggre_ufs_phy_axi_hw_ctl_clk = { - .halt_reg = 0x830d4, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x830d4, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x830d4, - .enable_mask = BIT(1), - .hw.init = &(const struct clk_init_data){ - .name = "gcc_aggre_ufs_phy_axi_hw_ctl_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_prim_axi_clk = { .halt_reg = 0x1c05c, .halt_check = BRANCH_HALT_VOTED, @@ -3809,26 +3787,6 @@ static struct clk_branch gcc_ufs_phy_axi_clk = { }, }; -static struct clk_branch gcc_ufs_phy_axi_hw_ctl_clk = { - .halt_reg = 0x83018, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x83018, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x83018, - .enable_mask = BIT(1), - .hw.init = &(const struct clk_init_data){ - .name = "gcc_ufs_phy_axi_hw_ctl_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 = 0x8306c, .halt_check = BRANCH_HALT_VOTED, @@ -3849,26 +3807,6 @@ static struct clk_branch gcc_ufs_phy_ice_core_clk = { }, }; -static struct clk_branch gcc_ufs_phy_ice_core_hw_ctl_clk = { - .halt_reg = 0x8306c, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x8306c, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x8306c, - .enable_mask = BIT(1), - .hw.init = &(const struct clk_init_data){ - .name = "gcc_ufs_phy_ice_core_hw_ctl_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 = 0x830a4, .halt_check = BRANCH_HALT_VOTED, @@ -3889,26 +3827,6 @@ static struct clk_branch gcc_ufs_phy_phy_aux_clk = { }, }; -static struct clk_branch gcc_ufs_phy_phy_aux_hw_ctl_clk = { - .halt_reg = 0x830a4, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x830a4, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x830a4, - .enable_mask = BIT(1), - .hw.init = &(const struct clk_init_data){ - .name = "gcc_ufs_phy_phy_aux_hw_ctl_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 = 0x83028, .halt_check = BRANCH_HALT_DELAY, @@ -3983,26 +3901,6 @@ static struct clk_branch gcc_ufs_phy_unipro_core_clk = { }, }; -static struct clk_branch gcc_ufs_phy_unipro_core_hw_ctl_clk = { - .halt_reg = 0x83064, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x83064, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x83064, - .enable_mask = BIT(1), - .hw.init = &(const struct clk_init_data){ - .name = "gcc_ufs_phy_unipro_core_hw_ctl_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_master_clk = { .halt_reg = 0x1c018, .halt_check = BRANCH_HALT, @@ -4305,81 +4203,120 @@ static struct clk_branch gcc_video_axi1_clk = { static struct gdsc pcie_0_gdsc = { .gdscr = 0xa9004, + .collapse_ctrl = 0x4b104, + .collapse_mask = BIT(0), + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "pcie_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc pcie_1_gdsc = { .gdscr = 0x77004, + .collapse_ctrl = 0x4b104, + .collapse_mask = BIT(1), + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "pcie_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc ufs_card_gdsc = { .gdscr = 0x81004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "ufs_card_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc ufs_phy_gdsc = { .gdscr = 0x83004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "ufs_phy_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc usb20_prim_gdsc = { .gdscr = 0x1c004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "usb20_prim_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc usb30_prim_gdsc = { .gdscr = 0x1b004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "usb30_prim_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc usb30_sec_gdsc = { .gdscr = 0x2f004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "usb30_sec_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc emac0_gdsc = { .gdscr = 0xb6004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "emac0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc emac1_gdsc = { .gdscr = 0xb4004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "emac1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct clk_regmap *gcc_sa8775p_clocks[] = { [GCC_AGGRE_NOC_QUPV3_AXI_CLK] = &gcc_aggre_noc_qupv3_axi_clk.clkr, [GCC_AGGRE_UFS_CARD_AXI_CLK] = &gcc_aggre_ufs_card_axi_clk.clkr, [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, - [GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK] = &gcc_aggre_ufs_phy_axi_hw_ctl_clk.clkr, [GCC_AGGRE_USB2_PRIM_AXI_CLK] = &gcc_aggre_usb2_prim_axi_clk.clkr, [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, [GCC_AGGRE_USB3_SEC_AXI_CLK] = &gcc_aggre_usb3_sec_axi_clk.clkr, @@ -4569,13 +4506,10 @@ static struct clk_regmap *gcc_sa8775p_clocks[] = { [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_AXI_HW_CTL_CLK] = &gcc_ufs_phy_axi_hw_ctl_clk.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_ICE_CORE_HW_CTL_CLK] = &gcc_ufs_phy_ice_core_hw_ctl_clk.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_PHY_AUX_HW_CTL_CLK] = &gcc_ufs_phy_phy_aux_hw_ctl_clk.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, @@ -4584,7 +4518,6 @@ static struct clk_regmap *gcc_sa8775p_clocks[] = { [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_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK] = &gcc_ufs_phy_unipro_core_hw_ctl_clk.clkr, [GCC_USB20_MASTER_CLK] = &gcc_usb20_master_clk.clkr, [GCC_USB20_MASTER_CLK_SRC] = &gcc_usb20_master_clk_src.clkr, [GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr, @@ -4753,7 +4686,10 @@ static int gcc_sa8775p_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0x34004); /* GCC_VIDEO_AHB_CLK */ qcom_branch_set_clk_en(regmap, 0x34024); /* GCC_VIDEO_XO_CLK */ - return qcom_cc_really_probe(pdev, &gcc_sa8775p_desc, regmap); + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); + + return qcom_cc_really_probe(&pdev->dev, &gcc_sa8775p_desc, regmap); } static struct platform_driver gcc_sa8775p_driver = { diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index 6a5f785c0ced..4a49ad7a9e5b 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -2458,7 +2458,7 @@ static int gcc_sc7180_probe(struct platform_device *pdev) if (ret) return ret; - return qcom_cc_really_probe(pdev, &gcc_sc7180_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sc7180_desc, regmap); } static struct platform_driver gcc_sc7180_driver = { diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c index f45a8318900c..4502926a2691 100644 --- a/drivers/clk/qcom/gcc-sc7280.c +++ b/drivers/clk/qcom/gcc-sc7280.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/clk-provider.h> @@ -3094,6 +3095,9 @@ static struct clk_branch gcc_wpss_rscp_clk = { static struct gdsc gcc_pcie_0_gdsc = { .gdscr = 0x6b004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "gcc_pcie_0_gdsc", }, @@ -3112,6 +3116,9 @@ static struct gdsc gcc_pcie_1_gdsc = { 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", }, @@ -3121,6 +3128,9 @@ static struct gdsc gcc_ufs_phy_gdsc = { static struct gdsc gcc_usb30_prim_gdsc = { .gdscr = 0xf004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "gcc_usb30_prim_gdsc", }, @@ -3463,12 +3473,15 @@ static int gcc_sc7280_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0x71004);/* GCC_GPU_CFG_AHB_CLK */ regmap_update_bits(regmap, 0x7100C, BIT(13), BIT(13)); + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, ARRAY_SIZE(gcc_dfs_clocks)); if (ret) return ret; - return qcom_cc_really_probe(pdev, &gcc_sc7280_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sc7280_desc, regmap); } static struct platform_driver gcc_sc7280_driver = { diff --git a/drivers/clk/qcom/gcc-sc8180x.c b/drivers/clk/qcom/gcc-sc8180x.c index 5261bfc92b3d..ad135bfa4c76 100644 --- a/drivers/clk/qcom/gcc-sc8180x.c +++ b/drivers/clk/qcom/gcc-sc8180x.c @@ -39,7 +39,7 @@ enum { P_SLEEP_CLK, }; -static struct pll_vco trion_vco[] = { +static const struct pll_vco trion_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -4623,7 +4623,7 @@ static int gcc_sc8180x_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x4d110, 0x3, 0x3); regmap_update_bits(regmap, 0x71028, 0x3, 0x3); - return qcom_cc_really_probe(pdev, &gcc_sc8180x_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sc8180x_desc, regmap); } static struct platform_driver gcc_sc8180x_driver = { diff --git a/drivers/clk/qcom/gcc-sc8280xp.c b/drivers/clk/qcom/gcc-sc8280xp.c index 082d7b5504eb..5f11760cf73f 100644 --- a/drivers/clk/qcom/gcc-sc8280xp.c +++ b/drivers/clk/qcom/gcc-sc8280xp.c @@ -7558,7 +7558,7 @@ static int gcc_sc8280xp_probe(struct platform_device *pdev) if (ret) goto err_put_rpm; - ret = qcom_cc_really_probe(pdev, &gcc_sc8280xp_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &gcc_sc8280xp_desc, regmap); if (ret) goto err_put_rpm; diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c index c4fe70871b6d..df79298a1a25 100644 --- a/drivers/clk/qcom/gcc-sdm660.c +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -2474,7 +2474,7 @@ static int gcc_sdm660_probe(struct platform_device *pdev) if (ret) return ret; - return qcom_cc_really_probe(pdev, &gcc_sdm660_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sdm660_desc, regmap); } static struct platform_driver gcc_sdm660_driver = { diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index ea4c3bf4fb9b..dc3aa7014c3e 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -4011,7 +4011,7 @@ static int gcc_sdm845_probe(struct platform_device *pdev) return ret; gcc_desc = of_device_get_match_data(&pdev->dev); - return qcom_cc_really_probe(pdev, gcc_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, gcc_desc, regmap); } static struct platform_driver gcc_sdm845_driver = { diff --git a/drivers/clk/qcom/gcc-sdx55.c b/drivers/clk/qcom/gcc-sdx55.c index 26279b8d321a..84c507656e8f 100644 --- a/drivers/clk/qcom/gcc-sdx55.c +++ b/drivers/clk/qcom/gcc-sdx55.c @@ -1616,7 +1616,7 @@ static int gcc_sdx55_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x6d008, BIT(21), BIT(21)); /* GCC_CPUSS_AHB_CLK */ regmap_update_bits(regmap, 0x6d008, BIT(22), BIT(22)); /* GCC_CPUSS_GNOC_CLK */ - return qcom_cc_really_probe(pdev, &gcc_sdx55_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sdx55_desc, regmap); } static struct platform_driver gcc_sdx55_driver = { diff --git a/drivers/clk/qcom/gcc-sdx65.c b/drivers/clk/qcom/gcc-sdx65.c index 8fde6463574b..fe297c606f97 100644 --- a/drivers/clk/qcom/gcc-sdx65.c +++ b/drivers/clk/qcom/gcc-sdx65.c @@ -1580,7 +1580,7 @@ static int gcc_sdx65_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x6d008, BIT(21), BIT(21)); /* GCC_CPUSS_AHB_CLK */ regmap_update_bits(regmap, 0x6d008, BIT(22), BIT(22)); /* GCC_CPUSS_GNOC_CLK */ - return qcom_cc_really_probe(pdev, &gcc_sdx65_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sdx65_desc, regmap); } static struct platform_driver gcc_sdx65_driver = { diff --git a/drivers/clk/qcom/gcc-sdx75.c b/drivers/clk/qcom/gcc-sdx75.c index c51338f08ef1..453a6bf8e878 100644 --- a/drivers/clk/qcom/gcc-sdx75.c +++ b/drivers/clk/qcom/gcc-sdx75.c @@ -2940,7 +2940,7 @@ static int gcc_sdx75_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0x3e004); /* GCC_AHB_PCIE_LINK_CLK */ qcom_branch_set_clk_en(regmap, 0x3e008); /* GCC_XO_PCIE_LINK_CLK */ - return qcom_cc_really_probe(pdev, &gcc_sdx75_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sdx75_desc, regmap); } static struct platform_driver gcc_sdx75_driver = { diff --git a/drivers/clk/qcom/gcc-sm4450.c b/drivers/clk/qcom/gcc-sm4450.c index 062e55e98156..e2d9e4691c5b 100644 --- a/drivers/clk/qcom/gcc-sm4450.c +++ b/drivers/clk/qcom/gcc-sm4450.c @@ -2861,7 +2861,7 @@ static int gcc_sm4450_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x4201c, BIT(21), BIT(21)); - return qcom_cc_really_probe(pdev, &gcc_sm4450_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm4450_desc, regmap); } static struct platform_driver gcc_sm4450_driver = { diff --git a/drivers/clk/qcom/gcc-sm6115.c b/drivers/clk/qcom/gcc-sm6115.c index 13e521cd4259..4c3804701e24 100644 --- a/drivers/clk/qcom/gcc-sm6115.c +++ b/drivers/clk/qcom/gcc-sm6115.c @@ -42,15 +42,15 @@ enum { P_SLEEP_CLK, }; -static struct pll_vco default_vco[] = { +static const struct pll_vco default_vco[] = { { 500000000, 1000000000, 2 }, }; -static struct pll_vco gpll9_vco[] = { +static const struct pll_vco gpll9_vco[] = { { 500000000, 1250000000, 0 }, }; -static struct pll_vco gpll10_vco[] = { +static const struct pll_vco gpll10_vco[] = { { 750000000, 1500000000, 1 }, }; @@ -3513,7 +3513,7 @@ static int gcc_sm6115_probe(struct platform_device *pdev) clk_alpha_pll_configure(&gpll10, regmap, &gpll10_config); clk_alpha_pll_configure(&gpll11, regmap, &gpll11_config); - return qcom_cc_really_probe(pdev, &gcc_sm6115_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm6115_desc, regmap); } static struct platform_driver gcc_sm6115_driver = { diff --git a/drivers/clk/qcom/gcc-sm6125.c b/drivers/clk/qcom/gcc-sm6125.c index da554efee2ce..07bb1e5c4a30 100644 --- a/drivers/clk/qcom/gcc-sm6125.c +++ b/drivers/clk/qcom/gcc-sm6125.c @@ -4161,7 +4161,7 @@ static int gcc_sm6125_probe(struct platform_device *pdev) if (ret) return ret; - return qcom_cc_really_probe(pdev, &gcc_sm6125_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm6125_desc, regmap); } static struct platform_driver gcc_sm6125_driver = { diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c index cf4a7b6e0b23..0dcc8eeb77e6 100644 --- a/drivers/clk/qcom/gcc-sm6350.c +++ b/drivers/clk/qcom/gcc-sm6350.c @@ -2559,7 +2559,7 @@ static int gcc_sm6350_probe(struct platform_device *pdev) if (ret) return ret; - return qcom_cc_really_probe(pdev, &gcc_sm6350_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm6350_desc, regmap); } static struct platform_driver gcc_sm6350_driver = { diff --git a/drivers/clk/qcom/gcc-sm6375.c b/drivers/clk/qcom/gcc-sm6375.c index 84639d5b89bf..f47dc2808095 100644 --- a/drivers/clk/qcom/gcc-sm6375.c +++ b/drivers/clk/qcom/gcc-sm6375.c @@ -50,11 +50,11 @@ enum { P_SLEEP_CLK, }; -static struct pll_vco lucid_vco[] = { +static const struct pll_vco lucid_vco[] = { { 249600000, 2000000000, 0 }, }; -static struct pll_vco zonda_vco[] = { +static const struct pll_vco zonda_vco[] = { { 595200000, 3600000000UL, 0 }, }; @@ -3892,7 +3892,7 @@ static int gcc_sm6375_probe(struct platform_device *pdev) clk_lucid_pll_configure(&gpll8, regmap, &gpll8_config); clk_zonda_pll_configure(&gpll9, regmap, &gpll9_config); - return qcom_cc_really_probe(pdev, &gcc_sm6375_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm6375_desc, regmap); } static struct platform_driver gcc_sm6375_driver = { diff --git a/drivers/clk/qcom/gcc-sm7150.c b/drivers/clk/qcom/gcc-sm7150.c index 44b49f7cd178..7eabaf0e1b57 100644 --- a/drivers/clk/qcom/gcc-sm7150.c +++ b/drivers/clk/qcom/gcc-sm7150.c @@ -44,9 +44,9 @@ static struct clk_alpha_pll gpll0 = { .clkr = { .enable_reg = 0x52000, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gpll0", - .parent_data = &(const struct clk_parent_data){ + .parent_data = &(const struct clk_parent_data) { .index = DT_BI_TCXO, }, .num_parents = 1, @@ -70,9 +70,9 @@ static struct clk_alpha_pll_postdiv gpll0_out_even = { .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), .width = 4, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(const struct clk_init_data) { .name = "gpll0_out_even", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gpll0.clkr.hw, }, .num_parents = 1, @@ -83,9 +83,9 @@ static struct clk_alpha_pll_postdiv gpll0_out_even = { static struct clk_fixed_factor gcc_pll0_main_div_cdiv = { .mult = 1, .div = 2, - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pll0_main_div_cdiv", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gpll0.clkr.hw, }, .num_parents = 1, @@ -99,9 +99,9 @@ static struct clk_alpha_pll gpll6 = { .clkr = { .enable_reg = 0x52000, .enable_mask = BIT(6), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gpll6", - .parent_data = &(const struct clk_parent_data){ + .parent_data = &(const struct clk_parent_data) { .index = DT_BI_TCXO, }, .num_parents = 1, @@ -116,9 +116,9 @@ static struct clk_alpha_pll gpll7 = { .clkr = { .enable_reg = 0x52000, .enable_mask = BIT(7), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gpll7", - .parent_data = &(const struct clk_parent_data){ + .parent_data = &(const struct clk_parent_data) { .index = DT_BI_TCXO, }, .num_parents = 1, @@ -252,7 +252,7 @@ static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -272,7 +272,7 @@ static struct clk_rcg2 gcc_cpuss_rbcpr_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_2, .freq_tbl = ftbl_gcc_cpuss_rbcpr_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(const struct clk_init_data) { .name = "gcc_cpuss_rbcpr_clk_src", .parent_data = gcc_parent_data_2_ao, .num_parents = ARRAY_SIZE(gcc_parent_data_2_ao), @@ -295,7 +295,7 @@ static struct clk_rcg2 gcc_gp1_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_1, .freq_tbl = ftbl_gcc_gp1_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -309,7 +309,7 @@ static struct clk_rcg2 gcc_gp2_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_1, .freq_tbl = ftbl_gcc_gp1_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -323,7 +323,7 @@ static struct clk_rcg2 gcc_gp3_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_1, .freq_tbl = ftbl_gcc_gp1_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -343,7 +343,7 @@ static struct clk_rcg2 gcc_pcie_0_aux_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_3, .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -363,7 +363,7 @@ static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_pcie_phy_refgen_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -383,7 +383,7 @@ static struct clk_rcg2 gcc_pdm2_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_pdm2_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -687,7 +687,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_5, .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(const struct clk_init_data) { .name = "gcc_sdcc1_apps_clk_src", .parent_data = gcc_parent_data_5, .num_parents = ARRAY_SIZE(gcc_parent_data_5), @@ -709,7 +709,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -734,7 +734,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_6, .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(const struct clk_init_data) { .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_6, .num_parents = ARRAY_SIZE(gcc_parent_data_6), @@ -760,7 +760,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -779,7 +779,7 @@ static struct clk_rcg2 gcc_tsif_ref_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_7, .freq_tbl = ftbl_gcc_tsif_ref_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(const struct clk_init_data) { .name = "gcc_tsif_ref_clk_src", .parent_data = gcc_parent_data_7, .num_parents = ARRAY_SIZE(gcc_parent_data_7), @@ -802,7 +802,7 @@ static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -824,7 +824,7 @@ static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -838,7 +838,7 @@ static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_4, .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -859,7 +859,7 @@ static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_ufs_phy_unipro_core_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -881,7 +881,7 @@ static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -903,7 +903,7 @@ static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -922,7 +922,7 @@ static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_3, .freq_tbl = ftbl_gcc_usb3_prim_phy_aux_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .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), @@ -936,7 +936,7 @@ static struct clk_rcg2 gcc_vs_ctrl_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_2, .freq_tbl = ftbl_gcc_usb3_prim_phy_aux_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(const struct clk_init_data) { .name = "gcc_vs_ctrl_clk_src", .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), @@ -957,7 +957,7 @@ static struct clk_rcg2 gcc_vsensor_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_8, .freq_tbl = ftbl_gcc_vsensor_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(const struct clk_init_data) { .name = "gcc_vsensor_clk_src", .parent_data = gcc_parent_data_8, .num_parents = ARRAY_SIZE(gcc_parent_data_8), @@ -971,7 +971,7 @@ static struct clk_branch gcc_aggre_noc_pcie_tbu_clk = { .clkr = { .enable_reg = 0x2800c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_aggre_noc_pcie_tbu_clk", .ops = &clk_branch2_ops, }, @@ -986,9 +986,9 @@ static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { .clkr = { .enable_reg = 0x82024, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_aggre_ufs_phy_axi_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_ufs_phy_axi_clk_src.clkr.hw, }, .num_parents = 1, @@ -1006,9 +1006,9 @@ static struct clk_branch gcc_aggre_ufs_phy_axi_hw_ctl_clk = { .clkr = { .enable_reg = 0x82024, .enable_mask = BIT(1), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_aggre_ufs_phy_axi_hw_ctl_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_aggre_ufs_phy_axi_clk.clkr.hw, }, .num_parents = 1, @@ -1024,9 +1024,9 @@ static struct clk_branch gcc_aggre_usb3_prim_axi_clk = { .clkr = { .enable_reg = 0x8201c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_aggre_usb3_prim_axi_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_usb30_prim_master_clk_src.clkr.hw, }, .num_parents = 1, @@ -1042,9 +1042,9 @@ static struct clk_branch gcc_apc_vs_clk = { .clkr = { .enable_reg = 0x7a050, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_apc_vs_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_vsensor_clk_src.clkr.hw, }, .num_parents = 1, @@ -1062,7 +1062,7 @@ static struct clk_branch gcc_boot_rom_ahb_clk = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(10), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_boot_rom_ahb_clk", .ops = &clk_branch2_ops, }, @@ -1075,7 +1075,7 @@ static struct clk_branch gcc_camera_hf_axi_clk = { .clkr = { .enable_reg = 0xb020, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_camera_hf_axi_clk", .ops = &clk_branch2_ops, }, @@ -1088,7 +1088,7 @@ static struct clk_branch gcc_camera_sf_axi_clk = { .clkr = { .enable_reg = 0xb06c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_camera_sf_axi_clk", .ops = &clk_branch2_ops, }, @@ -1103,7 +1103,7 @@ static struct clk_branch gcc_ce1_ahb_clk = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(3), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ce1_ahb_clk", .ops = &clk_branch2_ops, }, @@ -1116,7 +1116,7 @@ static struct clk_branch gcc_ce1_axi_clk = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(4), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ce1_axi_clk", .ops = &clk_branch2_ops, }, @@ -1129,7 +1129,7 @@ static struct clk_branch gcc_ce1_clk = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(5), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ce1_clk", .ops = &clk_branch2_ops, }, @@ -1142,9 +1142,9 @@ static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { .clkr = { .enable_reg = 0x502c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_cfg_noc_usb3_prim_axi_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_usb30_prim_master_clk_src.clkr.hw, }, .num_parents = 1, @@ -1160,9 +1160,9 @@ static struct clk_branch gcc_cpuss_ahb_clk = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(21), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_cpuss_ahb_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_cpuss_ahb_clk_src.clkr.hw, }, .num_parents = 1, @@ -1178,9 +1178,9 @@ static struct clk_branch gcc_cpuss_rbcpr_clk = { .clkr = { .enable_reg = 0x48008, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_cpuss_rbcpr_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_cpuss_rbcpr_clk_src.clkr.hw, }, .num_parents = 1, @@ -1196,7 +1196,7 @@ static struct clk_branch gcc_ddrss_gpu_axi_clk = { .clkr = { .enable_reg = 0x4452c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ddrss_gpu_axi_clk", .ops = &clk_branch2_ops, }, @@ -1209,9 +1209,9 @@ static struct clk_branch gcc_disp_gpll0_clk_src = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(18), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_disp_gpll0_clk_src", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gpll0.clkr.hw, }, .num_parents = 1, @@ -1225,9 +1225,9 @@ static struct clk_branch gcc_disp_gpll0_div_clk_src = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(19), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_disp_gpll0_div_clk_src", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_pll0_main_div_cdiv.hw, }, .num_parents = 1, @@ -1242,7 +1242,7 @@ static struct clk_branch gcc_disp_hf_axi_clk = { .clkr = { .enable_reg = 0xb024, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_disp_hf_axi_clk", .ops = &clk_branch2_ops, }, @@ -1255,7 +1255,7 @@ static struct clk_branch gcc_disp_sf_axi_clk = { .clkr = { .enable_reg = 0xb070, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_disp_sf_axi_clk", .ops = &clk_branch2_ops, }, @@ -1269,9 +1269,9 @@ static struct clk_branch gcc_gp1_clk = { .clkr = { .enable_reg = 0x64000, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_gp1_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_gp1_clk_src.clkr.hw, }, .num_parents = 1, @@ -1287,9 +1287,9 @@ static struct clk_branch gcc_gp2_clk = { .clkr = { .enable_reg = 0x65000, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_gp2_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_gp2_clk_src.clkr.hw, }, .num_parents = 1, @@ -1305,9 +1305,9 @@ static struct clk_branch gcc_gp3_clk = { .clkr = { .enable_reg = 0x66000, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_gp3_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_gp3_clk_src.clkr.hw, }, .num_parents = 1, @@ -1322,9 +1322,9 @@ static struct clk_branch gcc_gpu_gpll0_clk_src = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(15), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_gpu_gpll0_clk_src", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gpll0.clkr.hw, }, .num_parents = 1, @@ -1338,9 +1338,9 @@ static struct clk_branch gcc_gpu_gpll0_div_clk_src = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(16), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_gpu_gpll0_div_clk_src", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_pll0_main_div_cdiv.hw, }, .num_parents = 1, @@ -1355,7 +1355,7 @@ static struct clk_branch gcc_gpu_memnoc_gfx_clk = { .clkr = { .enable_reg = 0x7100c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_gpu_memnoc_gfx_clk", .ops = &clk_branch2_ops, }, @@ -1368,7 +1368,7 @@ static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = { .clkr = { .enable_reg = 0x71018, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_gpu_snoc_dvm_gfx_clk", .ops = &clk_branch2_ops, }, @@ -1381,9 +1381,9 @@ static struct clk_branch gcc_gpu_vs_clk = { .clkr = { .enable_reg = 0x7a04c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_gpu_vs_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_vsensor_clk_src.clkr.hw, }, .num_parents = 1, @@ -1399,7 +1399,7 @@ static struct clk_branch gcc_npu_axi_clk = { .clkr = { .enable_reg = 0x4d008, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_npu_axi_clk", .ops = &clk_branch2_ops, }, @@ -1414,7 +1414,7 @@ static struct clk_branch gcc_npu_cfg_ahb_clk = { .clkr = { .enable_reg = 0x4d004, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_npu_cfg_ahb_clk", .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, @@ -1427,9 +1427,9 @@ static struct clk_branch gcc_npu_gpll0_clk_src = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(25), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_npu_gpll0_clk_src", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gpll0.clkr.hw, }, .num_parents = 1, @@ -1443,9 +1443,9 @@ static struct clk_branch gcc_npu_gpll0_div_clk_src = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(26), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_npu_gpll0_div_clk_src", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_pll0_main_div_cdiv.hw, }, .num_parents = 1, @@ -1461,9 +1461,9 @@ static struct clk_branch gcc_pcie_0_aux_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(3), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_0_aux_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_pcie_0_aux_clk_src.clkr.hw, }, .num_parents = 1, @@ -1481,7 +1481,7 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(2), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_0_cfg_ahb_clk", .ops = &clk_branch2_ops, }, @@ -1494,7 +1494,7 @@ static struct clk_branch gcc_pcie_0_clkref_clk = { .clkr = { .enable_reg = 0x8c008, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_0_clkref_clk", .ops = &clk_branch2_ops, }, @@ -1507,7 +1507,7 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(1), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_0_mstr_axi_clk", .ops = &clk_branch2_ops, }, @@ -1520,7 +1520,7 @@ static struct clk_branch gcc_pcie_0_pipe_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(4), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_0_pipe_clk", .ops = &clk_branch2_ops, }, @@ -1535,7 +1535,7 @@ static struct clk_branch gcc_pcie_0_slv_axi_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_0_slv_axi_clk", .ops = &clk_branch2_ops, }, @@ -1548,7 +1548,7 @@ static struct clk_branch gcc_pcie_0_slv_q2a_axi_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(5), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_0_slv_q2a_axi_clk", .ops = &clk_branch2_ops, }, @@ -1561,9 +1561,9 @@ static struct clk_branch gcc_pcie_phy_aux_clk = { .clkr = { .enable_reg = 0x6f004, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_phy_aux_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_pcie_0_aux_clk_src.clkr.hw, }, .num_parents = 1, @@ -1579,9 +1579,9 @@ static struct clk_branch gcc_pcie_phy_refgen_clk = { .clkr = { .enable_reg = 0x6f02c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pcie_phy_refgen_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_pcie_phy_refgen_clk_src.clkr.hw, }, .num_parents = 1, @@ -1597,9 +1597,9 @@ static struct clk_branch gcc_pdm2_clk = { .clkr = { .enable_reg = 0x3300c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pdm2_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_pdm2_clk_src.clkr.hw, }, .num_parents = 1, @@ -1617,7 +1617,7 @@ static struct clk_branch gcc_pdm_ahb_clk = { .clkr = { .enable_reg = 0x33004, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pdm_ahb_clk", .ops = &clk_branch2_ops, }, @@ -1630,7 +1630,7 @@ static struct clk_branch gcc_pdm_xo4_clk = { .clkr = { .enable_reg = 0x33008, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_pdm_xo4_clk", .ops = &clk_branch2_ops, }, @@ -1645,7 +1645,7 @@ static struct clk_branch gcc_prng_ahb_clk = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(13), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_prng_ahb_clk", .ops = &clk_branch2_ops, }, @@ -1658,7 +1658,7 @@ static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(9), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap0_core_2x_clk", .ops = &clk_branch2_ops, }, @@ -1671,7 +1671,7 @@ static struct clk_branch gcc_qupv3_wrap0_core_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(8), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap0_core_clk", .ops = &clk_branch2_ops, }, @@ -1684,9 +1684,9 @@ static struct clk_branch gcc_qupv3_wrap0_s0_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(10), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap0_s0_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap0_s0_clk_src.clkr.hw, }, .num_parents = 1, @@ -1702,9 +1702,9 @@ static struct clk_branch gcc_qupv3_wrap0_s1_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(11), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap0_s1_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap0_s1_clk_src.clkr.hw, }, .num_parents = 1, @@ -1720,9 +1720,9 @@ static struct clk_branch gcc_qupv3_wrap0_s2_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(12), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap0_s2_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap0_s2_clk_src.clkr.hw, }, .num_parents = 1, @@ -1738,9 +1738,9 @@ static struct clk_branch gcc_qupv3_wrap0_s3_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(13), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap0_s3_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap0_s3_clk_src.clkr.hw, }, .num_parents = 1, @@ -1756,9 +1756,9 @@ static struct clk_branch gcc_qupv3_wrap0_s4_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(14), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap0_s4_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap0_s4_clk_src.clkr.hw, }, .num_parents = 1, @@ -1774,9 +1774,9 @@ static struct clk_branch gcc_qupv3_wrap0_s5_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(15), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap0_s5_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap0_s5_clk_src.clkr.hw, }, .num_parents = 1, @@ -1792,9 +1792,9 @@ static struct clk_branch gcc_qupv3_wrap0_s6_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(16), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap0_s6_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap0_s6_clk_src.clkr.hw, }, .num_parents = 1, @@ -1810,9 +1810,9 @@ static struct clk_branch gcc_qupv3_wrap0_s7_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(17), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap0_s7_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap0_s7_clk_src.clkr.hw, }, .num_parents = 1, @@ -1828,7 +1828,7 @@ static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(18), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap1_core_2x_clk", .ops = &clk_branch2_ops, }, @@ -1841,7 +1841,7 @@ static struct clk_branch gcc_qupv3_wrap1_core_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(19), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap1_core_clk", .ops = &clk_branch2_ops, }, @@ -1854,9 +1854,9 @@ static struct clk_branch gcc_qupv3_wrap1_s0_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(22), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap1_s0_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap1_s0_clk_src.clkr.hw, }, .num_parents = 1, @@ -1872,9 +1872,9 @@ static struct clk_branch gcc_qupv3_wrap1_s1_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(23), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap1_s1_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap1_s1_clk_src.clkr.hw, }, .num_parents = 1, @@ -1890,9 +1890,9 @@ static struct clk_branch gcc_qupv3_wrap1_s2_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(24), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap1_s2_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap1_s2_clk_src.clkr.hw, }, .num_parents = 1, @@ -1908,9 +1908,9 @@ static struct clk_branch gcc_qupv3_wrap1_s3_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(25), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap1_s3_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap1_s3_clk_src.clkr.hw, }, .num_parents = 1, @@ -1926,9 +1926,9 @@ static struct clk_branch gcc_qupv3_wrap1_s4_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(26), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap1_s4_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap1_s4_clk_src.clkr.hw, }, .num_parents = 1, @@ -1944,9 +1944,9 @@ static struct clk_branch gcc_qupv3_wrap1_s5_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(27), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap1_s5_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap1_s5_clk_src.clkr.hw, }, .num_parents = 1, @@ -1962,9 +1962,9 @@ static struct clk_branch gcc_qupv3_wrap1_s6_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(28), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap1_s6_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap1_s6_clk_src.clkr.hw, }, .num_parents = 1, @@ -1980,9 +1980,9 @@ static struct clk_branch gcc_qupv3_wrap1_s7_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(29), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap1_s7_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_qupv3_wrap1_s7_clk_src.clkr.hw, }, .num_parents = 1, @@ -1998,7 +1998,7 @@ static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(6), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap_0_m_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2013,7 +2013,7 @@ static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(7), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap_0_s_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2026,7 +2026,7 @@ static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(20), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap_1_m_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2041,7 +2041,7 @@ static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { .clkr = { .enable_reg = 0x5200c, .enable_mask = BIT(21), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_qupv3_wrap_1_s_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2054,7 +2054,7 @@ static struct clk_branch gcc_sdcc1_ahb_clk = { .clkr = { .enable_reg = 0x12008, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_sdcc1_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2067,9 +2067,9 @@ static struct clk_branch gcc_sdcc1_apps_clk = { .clkr = { .enable_reg = 0x1200c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_sdcc1_apps_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_sdcc1_apps_clk_src.clkr.hw, }, .num_parents = 1, @@ -2085,9 +2085,9 @@ static struct clk_branch gcc_sdcc1_ice_core_clk = { .clkr = { .enable_reg = 0x12040, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_sdcc1_ice_core_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_sdcc1_ice_core_clk_src.clkr.hw, }, .num_parents = 1, @@ -2103,7 +2103,7 @@ static struct clk_branch gcc_sdcc2_ahb_clk = { .clkr = { .enable_reg = 0x14008, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_sdcc2_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2116,9 +2116,9 @@ static struct clk_branch gcc_sdcc2_apps_clk = { .clkr = { .enable_reg = 0x14004, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_sdcc2_apps_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_sdcc2_apps_clk_src.clkr.hw, }, .num_parents = 1, @@ -2134,7 +2134,7 @@ static struct clk_branch gcc_sdcc4_ahb_clk = { .clkr = { .enable_reg = 0x16008, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_sdcc4_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2147,9 +2147,9 @@ static struct clk_branch gcc_sdcc4_apps_clk = { .clkr = { .enable_reg = 0x16004, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_sdcc4_apps_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_sdcc4_apps_clk_src.clkr.hw, }, .num_parents = 1, @@ -2165,9 +2165,9 @@ static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = { .clkr = { .enable_reg = 0x52004, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_sys_noc_cpuss_ahb_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_cpuss_ahb_clk_src.clkr.hw, }, .num_parents = 1, @@ -2183,7 +2183,7 @@ static struct clk_branch gcc_tsif_ahb_clk = { .clkr = { .enable_reg = 0x36004, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_tsif_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2196,7 +2196,7 @@ static struct clk_branch gcc_tsif_inactivity_timers_clk = { .clkr = { .enable_reg = 0x3600c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_tsif_inactivity_timers_clk", .ops = &clk_branch2_ops, }, @@ -2209,9 +2209,9 @@ static struct clk_branch gcc_tsif_ref_clk = { .clkr = { .enable_reg = 0x36008, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_tsif_ref_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_tsif_ref_clk_src.clkr.hw, }, .num_parents = 1, @@ -2227,7 +2227,7 @@ static struct clk_branch gcc_ufs_mem_clkref_clk = { .clkr = { .enable_reg = 0x8c000, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_mem_clkref_clk", .ops = &clk_branch2_ops, }, @@ -2242,7 +2242,7 @@ static struct clk_branch gcc_ufs_phy_ahb_clk = { .clkr = { .enable_reg = 0x77014, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2257,9 +2257,9 @@ static struct clk_branch gcc_ufs_phy_axi_clk = { .clkr = { .enable_reg = 0x77038, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_axi_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_ufs_phy_axi_clk_src.clkr.hw, }, .num_parents = 1, @@ -2277,9 +2277,9 @@ static struct clk_branch gcc_ufs_phy_axi_hw_ctl_clk = { .clkr = { .enable_reg = 0x77038, .enable_mask = BIT(1), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_axi_hw_ctl_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_ufs_phy_axi_clk.clkr.hw, }, .num_parents = 1, @@ -2297,9 +2297,9 @@ static struct clk_branch gcc_ufs_phy_ice_core_clk = { .clkr = { .enable_reg = 0x77090, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_ice_core_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_ufs_phy_ice_core_clk_src.clkr.hw, }, .num_parents = 1, @@ -2317,9 +2317,9 @@ static struct clk_branch gcc_ufs_phy_ice_core_hw_ctl_clk = { .clkr = { .enable_reg = 0x77090, .enable_mask = BIT(1), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_ice_core_hw_ctl_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_ufs_phy_ice_core_clk.clkr.hw, }, .num_parents = 1, @@ -2337,9 +2337,9 @@ static struct clk_branch gcc_ufs_phy_phy_aux_clk = { .clkr = { .enable_reg = 0x77094, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_phy_aux_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_ufs_phy_phy_aux_clk_src.clkr.hw, }, .num_parents = 1, @@ -2357,9 +2357,9 @@ static struct clk_branch gcc_ufs_phy_phy_aux_hw_ctl_clk = { .clkr = { .enable_reg = 0x77094, .enable_mask = BIT(1), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_phy_aux_hw_ctl_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_ufs_phy_phy_aux_clk.clkr.hw, }, .num_parents = 1, @@ -2375,7 +2375,7 @@ static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { .clkr = { .enable_reg = 0x7701c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_rx_symbol_0_clk", .ops = &clk_branch2_ops, }, @@ -2388,7 +2388,7 @@ static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { .clkr = { .enable_reg = 0x77018, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_tx_symbol_0_clk", .ops = &clk_branch2_ops, }, @@ -2403,9 +2403,9 @@ static struct clk_branch gcc_ufs_phy_unipro_core_clk = { .clkr = { .enable_reg = 0x7708c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_unipro_core_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_ufs_phy_unipro_core_clk_src.clkr.hw, }, .num_parents = 1, @@ -2423,9 +2423,9 @@ static struct clk_branch gcc_ufs_phy_unipro_core_hw_ctl_clk = { .clkr = { .enable_reg = 0x7708c, .enable_mask = BIT(1), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_unipro_core_hw_ctl_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_ufs_phy_unipro_core_clk.clkr.hw, }, .num_parents = 1, @@ -2441,9 +2441,9 @@ static struct clk_branch gcc_usb30_prim_master_clk = { .clkr = { .enable_reg = 0xf010, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_usb30_prim_master_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_usb30_prim_master_clk_src.clkr.hw, }, .num_parents = 1, @@ -2459,9 +2459,9 @@ static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { .clkr = { .enable_reg = 0xf018, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_usb30_prim_mock_utmi_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw, }, .num_parents = 1, @@ -2477,7 +2477,7 @@ static struct clk_branch gcc_usb30_prim_sleep_clk = { .clkr = { .enable_reg = 0xf014, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_usb30_prim_sleep_clk", .ops = &clk_branch2_ops, }, @@ -2490,7 +2490,7 @@ static struct clk_branch gcc_usb3_prim_clkref_clk = { .clkr = { .enable_reg = 0x8c010, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_usb3_prim_clkref_clk", .ops = &clk_branch2_ops, }, @@ -2503,9 +2503,9 @@ static struct clk_branch gcc_usb3_prim_phy_aux_clk = { .clkr = { .enable_reg = 0xf050, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_usb3_prim_phy_aux_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, }, .num_parents = 1, @@ -2521,9 +2521,9 @@ static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { .clkr = { .enable_reg = 0xf054, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_usb3_prim_phy_com_aux_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, }, .num_parents = 1, @@ -2538,7 +2538,7 @@ static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { .clkr = { .enable_reg = 0xf058, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_usb3_prim_phy_pipe_clk", .ops = &clk_branch2_ops, }, @@ -2553,7 +2553,7 @@ static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { .clkr = { .enable_reg = 0x6a004, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_usb_phy_cfg_ahb2phy_clk", .ops = &clk_branch2_ops, }, @@ -2566,9 +2566,9 @@ static struct clk_branch gcc_vdda_vs_clk = { .clkr = { .enable_reg = 0x7a00c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_vdda_vs_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_vsensor_clk_src.clkr.hw, }, .num_parents = 1, @@ -2584,9 +2584,9 @@ static struct clk_branch gcc_vddcx_vs_clk = { .clkr = { .enable_reg = 0x7a004, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_vddcx_vs_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_vsensor_clk_src.clkr.hw, }, .num_parents = 1, @@ -2602,9 +2602,9 @@ static struct clk_branch gcc_vddmx_vs_clk = { .clkr = { .enable_reg = 0x7a008, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_vddmx_vs_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_vsensor_clk_src.clkr.hw, }, .num_parents = 1, @@ -2621,7 +2621,7 @@ static struct clk_branch gcc_video_axi_clk = { .clkr = { .enable_reg = 0xb01c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_video_axi_clk", .ops = &clk_branch2_ops, }, @@ -2636,7 +2636,7 @@ static struct clk_branch gcc_vs_ctrl_ahb_clk = { .clkr = { .enable_reg = 0x7a014, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_vs_ctrl_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2649,9 +2649,9 @@ static struct clk_branch gcc_vs_ctrl_clk = { .clkr = { .enable_reg = 0x7a010, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "gcc_vs_ctrl_clk", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gcc_vs_ctrl_clk_src.clkr.hw, }, .num_parents = 1, @@ -3017,7 +3017,7 @@ static int gcc_sm7150_probe(struct platform_device *pdev) if (ret) return ret; - return qcom_cc_really_probe(pdev, &gcc_sm7150_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm7150_desc, regmap); } static struct platform_driver gcc_sm7150_driver = { diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c index 1f748141d12c..cefceb780889 100644 --- a/drivers/clk/qcom/gcc-sm8150.c +++ b/drivers/clk/qcom/gcc-sm8150.c @@ -3797,7 +3797,7 @@ static int gcc_sm8150_probe(struct platform_device *pdev) if (ret) dev_err_probe(&pdev->dev, ret, "Failed to register with DFS!\n"); - return qcom_cc_really_probe(pdev, &gcc_sm8150_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm8150_desc, regmap); } static struct platform_driver gcc_sm8150_driver = { diff --git a/drivers/clk/qcom/gcc-sm8250.c b/drivers/clk/qcom/gcc-sm8250.c index e630bfa2d0c1..991cd8b8d597 100644 --- a/drivers/clk/qcom/gcc-sm8250.c +++ b/drivers/clk/qcom/gcc-sm8250.c @@ -3656,7 +3656,7 @@ static int gcc_sm8250_probe(struct platform_device *pdev) if (ret) return ret; - return qcom_cc_really_probe(pdev, &gcc_sm8250_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm8250_desc, regmap); } static struct platform_driver gcc_sm8250_driver = { diff --git a/drivers/clk/qcom/gcc-sm8350.c b/drivers/clk/qcom/gcc-sm8350.c index fc0402e8a2a7..2d94f3046b71 100644 --- a/drivers/clk/qcom/gcc-sm8350.c +++ b/drivers/clk/qcom/gcc-sm8350.c @@ -3822,7 +3822,7 @@ static int gcc_sm8350_probe(struct platform_device *pdev) /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ regmap_update_bits(regmap, gcc_ufs_phy_ice_core_clk.halt_reg, BIT(14), BIT(14)); - return qcom_cc_really_probe(pdev, &gcc_sm8350_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm8350_desc, regmap); } static struct platform_driver gcc_sm8350_driver = { diff --git a/drivers/clk/qcom/gcc-sm8450.c b/drivers/clk/qcom/gcc-sm8450.c index e86c58bc5e48..639a9a955914 100644 --- a/drivers/clk/qcom/gcc-sm8450.c +++ b/drivers/clk/qcom/gcc-sm8450.c @@ -3289,7 +3289,7 @@ static int gcc_sm8450_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0x42004); /* GCC_VIDEO_AHB_CLK */ qcom_branch_set_clk_en(regmap, 0x42028); /* GCC_VIDEO_XO_CLK */ - return qcom_cc_really_probe(pdev, &gcc_sm8450_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm8450_desc, regmap); } static struct platform_driver gcc_sm8450_driver = { diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c index 26d7349e7642..7944ddb4b47d 100644 --- a/drivers/clk/qcom/gcc-sm8550.c +++ b/drivers/clk/qcom/gcc-sm8550.c @@ -3364,7 +3364,7 @@ static int gcc_sm8550_probe(struct platform_device *pdev) /* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */ regmap_write(regmap, 0x52024, 0x0); - return qcom_cc_really_probe(pdev, &gcc_sm8550_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm8550_desc, regmap); } static struct platform_driver gcc_sm8550_driver = { diff --git a/drivers/clk/qcom/gcc-sm8650.c b/drivers/clk/qcom/gcc-sm8650.c index 9d1cbdf860fb..9bc19bea0c97 100644 --- a/drivers/clk/qcom/gcc-sm8650.c +++ b/drivers/clk/qcom/gcc-sm8650.c @@ -3822,7 +3822,7 @@ static int gcc_sm8650_probe(struct platform_device *pdev) /* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */ regmap_write(regmap, 0x52150, 0x0); - return qcom_cc_really_probe(pdev, &gcc_sm8650_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_sm8650_desc, regmap); } static struct platform_driver gcc_sm8650_driver = { diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index 1404017be918..6ffb3ddcae08 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -2812,7 +2812,7 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = { static struct clk_branch gcc_pcie_0_pipe_clk = { .halt_reg = 0xa0044, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52010, .enable_mask = BIT(25), @@ -2901,7 +2901,7 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = { static struct clk_branch gcc_pcie_1_pipe_clk = { .halt_reg = 0x2c044, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52020, .enable_mask = BIT(30), @@ -2990,7 +2990,7 @@ static struct clk_branch gcc_pcie_2_mstr_axi_clk = { static struct clk_branch gcc_pcie_2_pipe_clk = { .halt_reg = 0x13044, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52020, .enable_mask = BIT(23), @@ -3110,7 +3110,7 @@ static struct clk_branch gcc_pcie_3_phy_rchng_clk = { static struct clk_branch gcc_pcie_3_pipe_clk = { .halt_reg = 0x58050, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52020, .enable_mask = BIT(3), @@ -3235,7 +3235,7 @@ static struct clk_branch gcc_pcie_4_phy_rchng_clk = { static struct clk_branch gcc_pcie_4_pipe_clk = { .halt_reg = 0x6b044, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52008, .enable_mask = BIT(4), @@ -3360,7 +3360,7 @@ static struct clk_branch gcc_pcie_5_phy_rchng_clk = { static struct clk_branch gcc_pcie_5_pipe_clk = { .halt_reg = 0x2f044, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52018, .enable_mask = BIT(17), @@ -3498,7 +3498,7 @@ static struct clk_branch gcc_pcie_6a_phy_rchng_clk = { static struct clk_branch gcc_pcie_6a_pipe_clk = { .halt_reg = 0x31050, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52018, .enable_mask = BIT(26), @@ -3636,7 +3636,7 @@ static struct clk_branch gcc_pcie_6b_phy_rchng_clk = { static struct clk_branch gcc_pcie_6b_pipe_clk = { .halt_reg = 0x8d050, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52000, .enable_mask = BIT(30), @@ -5109,7 +5109,7 @@ static struct clk_branch gcc_usb3_mp_phy_com_aux_clk = { static struct clk_branch gcc_usb3_mp_phy_pipe_0_clk = { .halt_reg = 0x17290, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x17290, .enable_mask = BIT(0), @@ -5122,7 +5122,7 @@ static struct clk_branch gcc_usb3_mp_phy_pipe_0_clk = { static struct clk_branch gcc_usb3_mp_phy_pipe_1_clk = { .halt_reg = 0x17298, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x17298, .enable_mask = BIT(0), @@ -5186,7 +5186,7 @@ static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = { static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { .halt_reg = 0x39068, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x39068, .hwcg_bit = 1, .clkr = { @@ -5257,7 +5257,7 @@ static struct clk_regmap_mux gcc_usb3_sec_phy_pipe_clk_src = { static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { .halt_reg = 0xa1068, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0xa1068, .hwcg_bit = 1, .clkr = { @@ -5269,6 +5269,7 @@ static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5327,7 +5328,7 @@ static struct clk_regmap_mux gcc_usb3_tert_phy_pipe_clk_src = { static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { .halt_reg = 0xa2068, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0xa2068, .hwcg_bit = 1, .clkr = { @@ -5339,6 +5340,7 @@ static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5405,7 +5407,7 @@ static struct clk_branch gcc_usb4_0_master_clk = { static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { .halt_reg = 0x9f0d8, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9f0d8, .enable_mask = BIT(0), @@ -5418,7 +5420,7 @@ static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { .halt_reg = 0x9f048, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52010, .enable_mask = BIT(19), @@ -5457,7 +5459,7 @@ static struct clk_branch gcc_usb4_0_phy_rx1_clk = { static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = { .halt_reg = 0x9f0a4, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x9f0a4, .hwcg_bit = 1, .clkr = { @@ -5582,7 +5584,7 @@ static struct clk_branch gcc_usb4_1_master_clk = { static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { .halt_reg = 0x2b0d8, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b0d8, .enable_mask = BIT(0), @@ -5595,7 +5597,7 @@ static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { .halt_reg = 0x2b048, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52028, .enable_mask = BIT(0), @@ -5634,7 +5636,7 @@ static struct clk_branch gcc_usb4_1_phy_rx1_clk = { static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = { .halt_reg = 0x2b0a4, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x2b0a4, .hwcg_bit = 1, .clkr = { @@ -5759,7 +5761,7 @@ static struct clk_branch gcc_usb4_2_master_clk = { static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { .halt_reg = 0x110d8, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x110d8, .enable_mask = BIT(0), @@ -5772,7 +5774,7 @@ static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { .halt_reg = 0x11048, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52028, .enable_mask = BIT(1), @@ -5811,7 +5813,7 @@ static struct clk_branch gcc_usb4_2_phy_rx1_clk = { static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = { .halt_reg = 0x110a4, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x110a4, .hwcg_bit = 1, .clkr = { @@ -6781,7 +6783,7 @@ static int gcc_x1e80100_probe(struct platform_device *pdev) /* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */ regmap_write(regmap, 0x52224, 0x0); - return qcom_cc_really_probe(pdev, &gcc_x1e80100_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gcc_x1e80100_desc, regmap); } static struct platform_driver gcc_x1e80100_driver = { diff --git a/drivers/clk/qcom/gpucc-msm8998.c b/drivers/clk/qcom/gpucc-msm8998.c index 9a4fdff719ec..9efeab2691ba 100644 --- a/drivers/clk/qcom/gpucc-msm8998.c +++ b/drivers/clk/qcom/gpucc-msm8998.c @@ -48,7 +48,7 @@ static struct clk_branch gpucc_cxo_clk = { }, }; -static struct pll_vco fabia_vco[] = { +static const struct pll_vco fabia_vco[] = { { 249600000, 2000000000, 0 }, { 125000000, 1000000000, 1 }, }; @@ -334,7 +334,7 @@ static int gpucc_msm8998_probe(struct platform_device *pdev) /* tweak droop detector (GPUCC_GPU_DD_WRAP_CTRL) to reduce leakage */ regmap_write_bits(regmap, gfx3d_clk.clkr.enable_reg, BIT(0), BIT(0)); - return qcom_cc_really_probe(pdev, &gpucc_msm8998_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpucc_msm8998_desc, regmap); } static struct platform_driver gpucc_msm8998_driver = { diff --git a/drivers/clk/qcom/gpucc-qcm2290.c b/drivers/clk/qcom/gpucc-qcm2290.c new file mode 100644 index 000000000000..dc369dff882e --- /dev/null +++ b/drivers/clk/qcom/gpucc-qcm2290.c @@ -0,0 +1,423 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2024, Linaro Limited + */ + +#include <linux/clk-provider.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm_clock.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,qcm2290-gpucc.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "clk-regmap-phy-mux.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_GCC_AHB_CLK, + DT_BI_TCXO, + DT_GCC_GPU_GPLL0_CLK_SRC, + DT_GCC_GPU_GPLL0_DIV_CLK_SRC, +}; + +enum { + P_BI_TCXO, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_2X_DIV_CLK_SRC, + P_GPU_CC_PLL0_OUT_AUX, + P_GPU_CC_PLL0_OUT_AUX2, + P_GPU_CC_PLL0_OUT_MAIN, +}; + +static const struct pll_vco huayra_vco[] = { + { 600000000, 3300000000, 0 }, + { 600000000, 2200000000, 1 }, +}; + +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x25, + .config_ctl_val = 0x200d4828, + .config_ctl_hi_val = 0x6, + .test_ctl_val = GENMASK(28, 26), + .test_ctl_hi_val = BIT(14), + .user_ctl_val = 0xf, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .vco_table = huayra_vco, + .num_vco = ARRAY_SIZE(huayra_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_2290], + .clkr = { + .hw.init = &(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_huayra_ops, + }, + }, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_0[] = { + { .index = DT_BI_TCXO, }, + { .hw = &gpu_cc_pll0.clkr.hw, }, + { .index = DT_GCC_GPU_GPLL0_CLK_SRC, }, + { .index = DT_GCC_GPU_GPLL0_DIV_CLK_SRC, }, +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_2X_DIV_CLK_SRC, 1 }, + { P_GPU_CC_PLL0_OUT_AUX2, 2 }, + { P_GPU_CC_PLL0_OUT_AUX, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_1[] = { + { .index = DT_BI_TCXO, }, + { .hw = &gpu_cc_pll0.clkr.hw, }, + { .hw = &gpu_cc_pll0.clkr.hw, }, + { .hw = &gpu_cc_pll0.clkr.hw, }, + { .index = DT_GCC_GPU_GPLL0_CLK_SRC, }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x1120, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gmu_clk_src", + .parent_data = gpu_cc_parent_data_0, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = { + F(355200000, P_GPU_CC_PLL0_OUT_AUX, 2, 0, 0), + F(537600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(672000000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(844800000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(921600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(1017600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(1123200000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = { + .cmd_rcgr = 0x101c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_1, + .freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gx_gfx3d_clk_src", + .parent_data = gpu_cc_parent_data_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gpu_cc_ahb_clk = { + .halt_reg = 0x1078, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1078, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_ahb_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_crc_ahb_clk = { + .halt_reg = 0x107c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x107c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_crc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gfx3d_clk = { + .halt_reg = 0x10a4, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x10a4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_gfx3d_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpu_cc_gx_gfx3d_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 = 0x1098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_gmu_clk", + .parent_data = &(const struct clk_parent_data){ + .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_cx_snoc_dvm_clk = { + .halt_reg = 0x108c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x108c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_snoc_dvm_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_aon_clk = { + .halt_reg = 0x1004, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cxo_aon_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_clk = { + .halt_reg = 0x109c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x109c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_gfx3d_clk = { + .halt_reg = 0x1054, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gx_gfx3d_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpu_cc_gx_gfx3d_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_sleep_clk = { + .halt_reg = 0x1090, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x1090, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { + .halt_reg = 0x5000, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x5000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gpu_cx_gdsc = { + .gdscr = 0x106c, + .gds_hw_ctrl = 0x1540, + .pd = { + .name = "gpu_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc gpu_gx_gdsc = { + .gdscr = 0x100c, + .clamp_io_ctrl = 0x1508, + .resets = (unsigned int []){ GPU_GX_BCR }, + .reset_count = 1, + .pd = { + .name = "gpu_gx_gdsc", + }, + .parent = &gpu_cx_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = CLAMP_IO | AON_RESET | SW_RESET, +}; + +static struct clk_regmap *gpu_cc_qcm2290_clocks[] = { + [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, + [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, + [GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr, + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, + [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr, + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr, + [GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr, + [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, + [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, + [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, +}; + +static const struct qcom_reset_map gpu_cc_qcm2290_resets[] = { + [GPU_GX_BCR] = { 0x1008 }, +}; + +static struct gdsc *gpu_cc_qcm2290_gdscs[] = { + [GPU_CX_GDSC] = &gpu_cx_gdsc, + [GPU_GX_GDSC] = &gpu_gx_gdsc, +}; + +static const struct regmap_config gpu_cc_qcm2290_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9000, + .fast_io = true, +}; + + +static const struct qcom_cc_desc gpu_cc_qcm2290_desc = { + .config = &gpu_cc_qcm2290_regmap_config, + .clks = gpu_cc_qcm2290_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_qcm2290_clocks), + .resets = gpu_cc_qcm2290_resets, + .num_resets = ARRAY_SIZE(gpu_cc_qcm2290_resets), + .gdscs = gpu_cc_qcm2290_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_qcm2290_gdscs), +}; + +static const struct of_device_id gpu_cc_qcm2290_match_table[] = { + { .compatible = "qcom,qcm2290-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_qcm2290_match_table); + +static int gpu_cc_qcm2290_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + regmap = qcom_cc_map(pdev, &gpu_cc_qcm2290_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; + + ret = devm_pm_clk_create(&pdev->dev); + if (ret) + return ret; + + ret = pm_clk_add(&pdev->dev, NULL); + if (ret < 0) { + dev_err(&pdev->dev, "failed to acquire ahb clock\n"); + return ret; + } + + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return ret; + + clk_huayra_2290_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); + + regmap_update_bits(regmap, 0x1060, BIT(0), BIT(0)); /* GPU_CC_GX_CXO_CLK */ + + ret = qcom_cc_really_probe(&pdev->dev, &gpu_cc_qcm2290_desc, regmap); + if (ret) { + dev_err(&pdev->dev, "Failed to register display clock controller\n"); + goto out_pm_runtime_put; + } + +out_pm_runtime_put: + pm_runtime_put_sync(&pdev->dev); + + return 0; +} + +static struct platform_driver gpu_cc_qcm2290_driver = { + .probe = gpu_cc_qcm2290_probe, + .driver = { + .name = "gpucc-qcm2290", + .of_match_table = gpu_cc_qcm2290_match_table, + }, +}; +module_platform_driver(gpu_cc_qcm2290_driver); + +MODULE_DESCRIPTION("QTI QCM2290 GPU clock controller driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gpucc-sa8775p.c b/drivers/clk/qcom/gpucc-sa8775p.c index 1167c42da39d..f8a8ac343d70 100644 --- a/drivers/clk/qcom/gpucc-sa8775p.c +++ b/drivers/clk/qcom/gpucc-sa8775p.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, 2024, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2023, Linaro Limited */ @@ -161,7 +161,7 @@ static struct clk_rcg2 gpu_cc_ff_clk_src = { .name = "gpu_cc_ff_clk_src", .parent_data = gpu_cc_parent_data_0, .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -181,7 +181,7 @@ static struct clk_rcg2 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_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -200,7 +200,7 @@ static struct clk_rcg2 gpu_cc_hub_clk_src = { .name = "gpu_cc_hub_clk_src", .parent_data = gpu_cc_parent_data_2, .num_parents = ARRAY_SIZE(gpu_cc_parent_data_2), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -280,7 +280,7 @@ static struct clk_branch gpu_cc_ahb_clk = { &gpu_cc_hub_ahb_div_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -294,8 +294,7 @@ static struct clk_branch gpu_cc_cb_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data){ .name = "gpu_cc_cb_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, + .ops = &clk_branch2_aon_ops, }, }, }; @@ -312,7 +311,7 @@ static struct clk_branch gpu_cc_crc_ahb_clk = { &gpu_cc_hub_ahb_div_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -330,7 +329,7 @@ static struct clk_branch gpu_cc_cx_ff_clk = { &gpu_cc_ff_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -348,7 +347,7 @@ static struct clk_branch gpu_cc_cx_gmu_clk = { &gpu_cc_gmu_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_aon_ops, }, }, @@ -362,7 +361,6 @@ static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data){ .name = "gpu_cc_cx_snoc_dvm_clk", - .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, @@ -380,7 +378,7 @@ static struct clk_branch gpu_cc_cxo_aon_clk = { &gpu_cc_xo_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -398,7 +396,7 @@ static struct clk_branch gpu_cc_cxo_clk = { &gpu_cc_xo_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -416,7 +414,7 @@ static struct clk_branch gpu_cc_demet_clk = { &gpu_cc_demet_div_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_aon_ops, }, }, @@ -430,7 +428,6 @@ static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data){ .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", - .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, @@ -448,7 +445,7 @@ static struct clk_branch gpu_cc_hub_aon_clk = { &gpu_cc_hub_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_aon_ops, }, }, @@ -466,7 +463,7 @@ static struct clk_branch gpu_cc_hub_cx_int_clk = { &gpu_cc_hub_cx_int_div_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_aon_ops, }, }, @@ -480,7 +477,6 @@ static struct clk_branch gpu_cc_memnoc_gfx_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data){ .name = "gpu_cc_memnoc_gfx_clk", - .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, @@ -494,7 +490,6 @@ static struct clk_branch gpu_cc_sleep_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data){ .name = "gpu_cc_sleep_clk", - .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, @@ -528,16 +523,22 @@ static struct clk_regmap *gpu_cc_sa8775p_clocks[] = { static struct gdsc cx_gdsc = { .gdscr = 0x9108, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .gds_hw_ctrl = 0x953c, .pd = { .name = "cx_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE, }; static struct gdsc gx_gdsc = { .gdscr = 0x905c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "gx_gdsc", .power_on = gdsc_gx_do_nothing_enable, @@ -598,7 +599,7 @@ static int gpu_cc_sa8775p_probe(struct platform_device *pdev) clk_lucid_evo_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - return qcom_cc_really_probe(pdev, &gpu_cc_sa8775p_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sa8775p_desc, regmap); } static struct platform_driver gpu_cc_sa8775p_driver = { diff --git a/drivers/clk/qcom/gpucc-sc7180.c b/drivers/clk/qcom/gpucc-sc7180.c index 66f5b48cbf87..08f3983d016f 100644 --- a/drivers/clk/qcom/gpucc-sc7180.c +++ b/drivers/clk/qcom/gpucc-sc7180.c @@ -241,7 +241,7 @@ static int gpu_cc_sc7180_probe(struct platform_device *pdev) value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT; regmap_update_bits(regmap, 0x1098, mask, value); - return qcom_cc_really_probe(pdev, &gpu_cc_sc7180_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sc7180_desc, regmap); } static struct platform_driver gpu_cc_sc7180_driver = { diff --git a/drivers/clk/qcom/gpucc-sc7280.c b/drivers/clk/qcom/gpucc-sc7280.c index 35b394feb68d..bd699a624517 100644 --- a/drivers/clk/qcom/gpucc-sc7280.c +++ b/drivers/clk/qcom/gpucc-sc7280.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/clk-provider.h> @@ -379,6 +380,9 @@ static struct clk_branch gpu_cc_sleep_clk = { static struct gdsc cx_gdsc = { .gdscr = 0x106c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, .gds_hw_ctrl = 0x1540, .pd = { .name = "cx_gdsc", @@ -389,6 +393,9 @@ static struct gdsc cx_gdsc = { static struct gdsc gx_gdsc = { .gdscr = 0x100c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, .clamp_io_ctrl = 0x1508, .pd = { .name = "gx_gdsc", @@ -462,7 +469,7 @@ static int gpu_cc_sc7280_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0x1098); /* GPUCC_CX_GMU_CLK */ regmap_update_bits(regmap, 0x1098, BIT(13), BIT(13)); - return qcom_cc_really_probe(pdev, &gpu_cc_sc7280_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sc7280_desc, regmap); } static struct platform_driver gpu_cc_sc7280_driver = { diff --git a/drivers/clk/qcom/gpucc-sc8280xp.c b/drivers/clk/qcom/gpucc-sc8280xp.c index 3611d2d1823d..c96be61e3f47 100644 --- a/drivers/clk/qcom/gpucc-sc8280xp.c +++ b/drivers/clk/qcom/gpucc-sc8280xp.c @@ -449,7 +449,7 @@ static int gpu_cc_sc8280xp_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0x1170); /* GPU_CC_CB_CLK */ qcom_branch_set_clk_en(regmap, 0x109c); /* GPU_CC_CXO_CLK */ - ret = qcom_cc_really_probe(pdev, &gpu_cc_sc8280xp_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &gpu_cc_sc8280xp_desc, regmap); pm_runtime_put(&pdev->dev); return ret; diff --git a/drivers/clk/qcom/gpucc-sdm660.c b/drivers/clk/qcom/gpucc-sdm660.c index 459f123a6720..3ae1b80e38d9 100644 --- a/drivers/clk/qcom/gpucc-sdm660.c +++ b/drivers/clk/qcom/gpucc-sdm660.c @@ -51,7 +51,7 @@ static struct clk_branch gpucc_cxo_clk = { }, }; -static struct pll_vco gpu_vco[] = { +static const struct pll_vco gpu_vco[] = { { 1000000000, 2000000000, 0 }, { 500000000, 1000000000, 2 }, { 250000000, 500000000, 3 }, @@ -330,7 +330,7 @@ static int gpucc_sdm660_probe(struct platform_device *pdev) gpu_pll_config.alpha_hi = 0x8a; clk_alpha_pll_configure(&gpu_pll1_pll_out_main, regmap, &gpu_pll_config); - return qcom_cc_really_probe(pdev, &gpucc_sdm660_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpucc_sdm660_desc, regmap); } static struct platform_driver gpucc_sdm660_driver = { diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c index c87c3215dfe3..ef26690cf504 100644 --- a/drivers/clk/qcom/gpucc-sdm845.c +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -192,7 +192,7 @@ static int gpu_cc_sdm845_probe(struct platform_device *pdev) value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT; regmap_update_bits(regmap, 0x1098, mask, value); - return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sdm845_desc, regmap); } static struct platform_driver gpu_cc_sdm845_driver = { diff --git a/drivers/clk/qcom/gpucc-sm6115.c b/drivers/clk/qcom/gpucc-sm6115.c index fb71c21c9a89..d43c86cf73a5 100644 --- a/drivers/clk/qcom/gpucc-sm6115.c +++ b/drivers/clk/qcom/gpucc-sm6115.c @@ -38,11 +38,11 @@ enum { P_GPU_CC_PLL1_OUT_MAIN, }; -static struct pll_vco default_vco[] = { +static const struct pll_vco default_vco[] = { { 1000000000, 2000000000, 0 }, }; -static struct pll_vco pll1_vco[] = { +static const struct pll_vco pll1_vco[] = { { 500000000, 1000000000, 2 }, }; @@ -488,7 +488,7 @@ static int gpu_cc_sm6115_probe(struct platform_device *pdev) qcom_branch_set_force_mem_core(regmap, gpu_cc_gx_gfx3d_clk, true); qcom_branch_set_force_periph_on(regmap, gpu_cc_gx_gfx3d_clk, true); - return qcom_cc_really_probe(pdev, &gpu_cc_sm6115_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm6115_desc, regmap); } static struct platform_driver gpu_cc_sm6115_driver = { diff --git a/drivers/clk/qcom/gpucc-sm6125.c b/drivers/clk/qcom/gpucc-sm6125.c index 61959ba02f9a..ed6a6e505801 100644 --- a/drivers/clk/qcom/gpucc-sm6125.c +++ b/drivers/clk/qcom/gpucc-sm6125.c @@ -36,7 +36,7 @@ enum { P_GPU_CC_PLL1_OUT_AUX2, }; -static struct pll_vco gpu_cc_pll_vco[] = { +static const struct pll_vco gpu_cc_pll_vco[] = { { 1000000000, 2000000000, 0 }, { 500000000, 1000000000, 2 }, }; @@ -409,7 +409,7 @@ static int gpu_cc_sm6125_probe(struct platform_device *pdev) qcom_branch_set_force_mem_core(regmap, gpu_cc_gx_gfx3d_clk, true); qcom_branch_set_force_periph_on(regmap, gpu_cc_gx_gfx3d_clk, true); - return qcom_cc_really_probe(pdev, &gpu_cc_sm6125_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm6125_desc, regmap); } static struct platform_driver gpu_cc_sm6125_driver = { diff --git a/drivers/clk/qcom/gpucc-sm6350.c b/drivers/clk/qcom/gpucc-sm6350.c index 0bcbba2a2943..1e12ad8948db 100644 --- a/drivers/clk/qcom/gpucc-sm6350.c +++ b/drivers/clk/qcom/gpucc-sm6350.c @@ -502,7 +502,7 @@ static int gpu_cc_sm6350_probe(struct platform_device *pdev) value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT; regmap_update_bits(regmap, 0x1098, mask, value); - return qcom_cc_really_probe(pdev, &gpu_cc_sm6350_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm6350_desc, regmap); } static struct platform_driver gpu_cc_sm6350_driver = { diff --git a/drivers/clk/qcom/gpucc-sm6375.c b/drivers/clk/qcom/gpucc-sm6375.c index da24276a018e..41f59024143e 100644 --- a/drivers/clk/qcom/gpucc-sm6375.c +++ b/drivers/clk/qcom/gpucc-sm6375.c @@ -42,7 +42,7 @@ enum { P_GPU_CC_PLL1_OUT_ODD, }; -static struct pll_vco lucid_vco[] = { +static const struct pll_vco lucid_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -455,7 +455,7 @@ static int gpucc_sm6375_probe(struct platform_device *pdev) clk_lucid_pll_configure(&gpucc_pll0, regmap, &gpucc_pll0_config); clk_lucid_pll_configure(&gpucc_pll1, regmap, &gpucc_pll1_config); - ret = qcom_cc_really_probe(pdev, &gpucc_sm6375_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &gpucc_sm6375_desc, regmap); pm_runtime_put(&pdev->dev); return ret; diff --git a/drivers/clk/qcom/gpucc-sm8150.c b/drivers/clk/qcom/gpucc-sm8150.c index 135601629cba..d711464a71b6 100644 --- a/drivers/clk/qcom/gpucc-sm8150.c +++ b/drivers/clk/qcom/gpucc-sm8150.c @@ -304,7 +304,7 @@ static int gpu_cc_sm8150_probe(struct platform_device *pdev) clk_trion_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - return qcom_cc_really_probe(pdev, &gpu_cc_sm8150_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8150_desc, regmap); } static struct platform_driver gpu_cc_sm8150_driver = { diff --git a/drivers/clk/qcom/gpucc-sm8250.c b/drivers/clk/qcom/gpucc-sm8250.c index 84f7f65c8d42..113b486a6d2f 100644 --- a/drivers/clk/qcom/gpucc-sm8250.c +++ b/drivers/clk/qcom/gpucc-sm8250.c @@ -32,7 +32,7 @@ enum { P_GPU_CC_PLL1_OUT_MAIN, }; -static struct pll_vco lucid_vco[] = { +static const struct pll_vco lucid_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -320,7 +320,7 @@ static int gpu_cc_sm8250_probe(struct platform_device *pdev) value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT; regmap_update_bits(regmap, 0x1098, mask, value); - return qcom_cc_really_probe(pdev, &gpu_cc_sm8250_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8250_desc, regmap); } static struct platform_driver gpu_cc_sm8250_driver = { diff --git a/drivers/clk/qcom/gpucc-sm8350.c b/drivers/clk/qcom/gpucc-sm8350.c index 38505d1388b6..f3b6bdc24485 100644 --- a/drivers/clk/qcom/gpucc-sm8350.c +++ b/drivers/clk/qcom/gpucc-sm8350.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2022, Linaro Limited + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/clk.h> @@ -33,7 +34,7 @@ enum { P_GPU_CC_PLL1_OUT_MAIN, }; -static struct pll_vco lucid_5lpe_vco[] = { +static const struct pll_vco lucid_5lpe_vco[] = { { 249600000, 1750000000, 0 }, }; @@ -147,7 +148,7 @@ static struct clk_rcg2 gpu_cc_gmu_clk_src = { .parent_data = gpu_cc_parent_data_0, .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -169,7 +170,7 @@ static struct clk_rcg2 gpu_cc_hub_clk_src = { .parent_data = gpu_cc_parent_data_1, .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -604,7 +605,7 @@ static int gpu_cc_sm8350_probe(struct platform_device *pdev) clk_lucid_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - return qcom_cc_really_probe(pdev, &gpu_cc_sm8350_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8350_desc, regmap); } static const struct of_device_id gpu_cc_sm8350_match_table[] = { diff --git a/drivers/clk/qcom/gpucc-sm8450.c b/drivers/clk/qcom/gpucc-sm8450.c index 1c4769b646b0..b3c5d6923cd2 100644 --- a/drivers/clk/qcom/gpucc-sm8450.c +++ b/drivers/clk/qcom/gpucc-sm8450.c @@ -36,7 +36,7 @@ enum { P_GPU_CC_PLL1_OUT_MAIN, }; -static struct pll_vco lucid_evo_vco[] = { +static const struct pll_vco lucid_evo_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -751,7 +751,7 @@ static int gpu_cc_sm8450_probe(struct platform_device *pdev) clk_lucid_evo_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - return qcom_cc_really_probe(pdev, &gpu_cc_sm8450_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8450_desc, regmap); } static struct platform_driver gpu_cc_sm8450_driver = { diff --git a/drivers/clk/qcom/gpucc-sm8550.c b/drivers/clk/qcom/gpucc-sm8550.c index 4fc69c6026e5..7486edf56160 100644 --- a/drivers/clk/qcom/gpucc-sm8550.c +++ b/drivers/clk/qcom/gpucc-sm8550.c @@ -579,7 +579,7 @@ static int gpu_cc_sm8550_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0x9004); /* GPU_CC_CXO_AON_CLK */ qcom_branch_set_clk_en(regmap, 0x900c); /* GPU_CC_DEMET_CLK */ - return qcom_cc_really_probe(pdev, &gpu_cc_sm8550_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8550_desc, regmap); } static struct platform_driver gpu_cc_sm8550_driver = { diff --git a/drivers/clk/qcom/gpucc-sm8650.c b/drivers/clk/qcom/gpucc-sm8650.c index 03307e482aca..f15aeecc512d 100644 --- a/drivers/clk/qcom/gpucc-sm8650.c +++ b/drivers/clk/qcom/gpucc-sm8650.c @@ -37,7 +37,7 @@ enum { P_GPU_CC_PLL1_OUT_MAIN, }; -static struct pll_vco lucid_ole_vco[] = { +static const struct pll_vco lucid_ole_vco[] = { { 249600000, 2100000000, 0 }, }; @@ -647,7 +647,7 @@ static int gpu_cc_sm8650_probe(struct platform_device *pdev) clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); - return qcom_cc_really_probe(pdev, &gpu_cc_sm8650_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8650_desc, regmap); } static struct platform_driver gpu_cc_sm8650_driver = { diff --git a/drivers/clk/qcom/gpucc-x1e80100.c b/drivers/clk/qcom/gpucc-x1e80100.c index b7e79d118d6e..2eec20dd0254 100644 --- a/drivers/clk/qcom/gpucc-x1e80100.c +++ b/drivers/clk/qcom/gpucc-x1e80100.c @@ -640,7 +640,7 @@ static int gpu_cc_x1e80100_probe(struct platform_device *pdev) /* Keep clocks always enabled */ qcom_branch_set_clk_en(regmap, 0x93a4); /* GPU_CC_CB_CLK */ - return qcom_cc_really_probe(pdev, &gpu_cc_x1e80100_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &gpu_cc_x1e80100_desc, regmap); } static struct platform_driver gpu_cc_x1e80100_driver = { diff --git a/drivers/clk/qcom/kpss-xcc.c b/drivers/clk/qcom/kpss-xcc.c index 23b0b11f0007..e7cfa8d22044 100644 --- a/drivers/clk/qcom/kpss-xcc.c +++ b/drivers/clk/qcom/kpss-xcc.c @@ -58,9 +58,7 @@ static int kpss_xcc_driver_probe(struct platform_device *pdev) if (IS_ERR(hw)) return PTR_ERR(hw); - of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, hw); - - return 0; + return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, hw); } static struct platform_driver kpss_xcc_driver = { diff --git a/drivers/clk/qcom/lcc-ipq806x.c b/drivers/clk/qcom/lcc-ipq806x.c index fa8cda63cf20..bf5320a43e8c 100644 --- a/drivers/clk/qcom/lcc-ipq806x.c +++ b/drivers/clk/qcom/lcc-ipq806x.c @@ -454,7 +454,7 @@ static int lcc_ipq806x_probe(struct platform_device *pdev) /* Enable PLL4 source on the LPASS Primary PLL Mux */ regmap_write(regmap, 0xc4, 0x1); - return qcom_cc_really_probe(pdev, &lcc_ipq806x_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &lcc_ipq806x_desc, regmap); } static struct platform_driver lcc_ipq806x_driver = { diff --git a/drivers/clk/qcom/lcc-msm8960.c b/drivers/clk/qcom/lcc-msm8960.c index e725e7b9c456..d53bf315e9c3 100644 --- a/drivers/clk/qcom/lcc-msm8960.c +++ b/drivers/clk/qcom/lcc-msm8960.c @@ -481,7 +481,7 @@ static int lcc_msm8960_probe(struct platform_device *pdev) /* Enable PLL4 source on the LPASS Primary PLL Mux */ regmap_write(regmap, 0xc4, 0x1); - return qcom_cc_really_probe(pdev, &lcc_msm8960_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &lcc_msm8960_desc, regmap); } static struct platform_driver lcc_msm8960_driver = { diff --git a/drivers/clk/qcom/lpass-gfm-sm8250.c b/drivers/clk/qcom/lpass-gfm-sm8250.c index 8a1ee52cbcc3..65d380e30eed 100644 --- a/drivers/clk/qcom/lpass-gfm-sm8250.c +++ b/drivers/clk/qcom/lpass-gfm-sm8250.c @@ -315,3 +315,4 @@ static struct platform_driver lpass_gfm_clk_driver = { }; module_platform_driver(lpass_gfm_clk_driver); MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("QTI SM8250 LPASS Glitch Free Mux clock driver"); diff --git a/drivers/clk/qcom/lpassaudiocc-sc7280.c b/drivers/clk/qcom/lpassaudiocc-sc7280.c index c43d0b1af7f7..45e726477086 100644 --- a/drivers/clk/qcom/lpassaudiocc-sc7280.c +++ b/drivers/clk/qcom/lpassaudiocc-sc7280.c @@ -772,7 +772,7 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) regmap_write(regmap, 0x4, 0x3b); regmap_write(regmap, 0x8, 0xff05); - ret = qcom_cc_really_probe(pdev, &lpass_audio_cc_sc7280_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &lpass_audio_cc_sc7280_desc, regmap); if (ret) { dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC clocks\n"); goto exit; @@ -847,7 +847,7 @@ static int lpass_aon_cc_sc7280_probe(struct platform_device *pdev) clk_lucid_pll_configure(&lpass_aon_cc_pll, regmap, &lpass_aon_cc_pll_config); - ret = qcom_cc_really_probe(pdev, &lpass_aon_cc_sc7280_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &lpass_aon_cc_sc7280_desc, regmap); if (ret) { dev_err(&pdev->dev, "Failed to register LPASS AON CC clocks\n"); goto exit; diff --git a/drivers/clk/qcom/lpasscc-sc8280xp.c b/drivers/clk/qcom/lpasscc-sc8280xp.c index 3693e47d548e..9fd9498d7dc8 100644 --- a/drivers/clk/qcom/lpasscc-sc8280xp.c +++ b/drivers/clk/qcom/lpasscc-sc8280xp.c @@ -23,7 +23,7 @@ static const struct qcom_reset_map lpass_audiocc_sc8280xp_resets[] = { [LPASS_AUDIO_SWR_WSA2_CGCR] = { 0xd8, 1 }, }; -static struct regmap_config lpass_audiocc_sc8280xp_regmap_config = { +static const struct regmap_config lpass_audiocc_sc8280xp_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, @@ -41,7 +41,7 @@ static const struct qcom_reset_map lpasscc_sc8280xp_resets[] = { [LPASS_AUDIO_SWR_TX_CGCR] = { 0xc010, 1 }, }; -static struct regmap_config lpasscc_sc8280xp_regmap_config = { +static const struct regmap_config lpasscc_sc8280xp_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c index fd9cd2e3f956..726c6378752f 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7180.c +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -27,7 +27,7 @@ enum { P_SLEEP_CLK, }; -static struct pll_vco fabia_vco[] = { +static const struct pll_vco fabia_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -411,7 +411,7 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap, &lpass_lpaaudio_dig_pll_config); - ret = qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &lpass_core_cc_sc7180_desc, regmap); pm_runtime_mark_last_busy(&pdev->dev); exit: diff --git a/drivers/clk/qcom/lpasscorecc-sc7280.c b/drivers/clk/qcom/lpasscorecc-sc7280.c index a2f1e6ad6da4..b0888cd2460b 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7280.c +++ b/drivers/clk/qcom/lpasscorecc-sc7280.c @@ -406,7 +406,7 @@ static int lpass_core_cc_sc7280_probe(struct platform_device *pdev) clk_lucid_pll_configure(&lpass_core_cc_dig_pll, regmap, &lpass_core_cc_dig_pll_config); - return qcom_cc_really_probe(pdev, &lpass_core_cc_sc7280_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &lpass_core_cc_sc7280_desc, regmap); } static struct platform_driver lpass_core_cc_sc7280_driver = { diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c index 50638ab341ec..1061322534c4 100644 --- a/drivers/clk/qcom/mmcc-msm8960.c +++ b/drivers/clk/qcom/mmcc-msm8960.c @@ -3122,7 +3122,7 @@ static int mmcc_msm8960_probe(struct platform_device *pdev) clk_pll_configure_sr(&pll15, regmap, &pll15_config, false); - return qcom_cc_really_probe(pdev, desc, regmap); + return qcom_cc_really_probe(&pdev->dev, desc, regmap); } static struct platform_driver mmcc_msm8960_driver = { diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c index 36f460b78be2..d5bcb09ebd0c 100644 --- a/drivers/clk/qcom/mmcc-msm8974.c +++ b/drivers/clk/qcom/mmcc-msm8974.c @@ -2768,7 +2768,7 @@ static int mmcc_msm8974_probe(struct platform_device *pdev) msm8226_clock_override(); } - return qcom_cc_really_probe(pdev, desc, regmap); + return qcom_cc_really_probe(&pdev->dev, desc, regmap); } static struct platform_driver mmcc_msm8974_driver = { diff --git a/drivers/clk/qcom/mmcc-msm8994.c b/drivers/clk/qcom/mmcc-msm8994.c index 3229ff77372f..78e5083eaf0f 100644 --- a/drivers/clk/qcom/mmcc-msm8994.c +++ b/drivers/clk/qcom/mmcc-msm8994.c @@ -84,14 +84,14 @@ static const struct clk_parent_data mmcc_xo_dsibyte[] = { { .fw_name = "dsi1pllbyte" }, }; -static struct pll_vco mmpll_p_vco[] = { +static const struct pll_vco mmpll_p_vco[] = { { 250000000, 500000000, 3 }, { 500000000, 1000000000, 2 }, { 1000000000, 1500000000, 1 }, { 1500000000, 2000000000, 0 }, }; -static struct pll_vco mmpll_t_vco[] = { +static const struct pll_vco mmpll_t_vco[] = { { 500000000, 1500000000, 0 }, }; @@ -2602,7 +2602,7 @@ static int mmcc_msm8994_probe(struct platform_device *pdev) clk_alpha_pll_configure(&mmpll3_early, regmap, &mmpll_p_config); clk_alpha_pll_configure(&mmpll5_early, regmap, &mmpll_p_config); - return qcom_cc_really_probe(pdev, &mmcc_msm8994_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &mmcc_msm8994_desc, regmap); } static struct platform_driver mmcc_msm8994_driver = { diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c index d3f2dc798567..1a32c6eb8217 100644 --- a/drivers/clk/qcom/mmcc-msm8996.c +++ b/drivers/clk/qcom/mmcc-msm8996.c @@ -57,20 +57,20 @@ static struct clk_fixed_factor gpll0_div = { }, }; -static struct pll_vco mmpll_p_vco[] = { +static const struct pll_vco mmpll_p_vco[] = { { 250000000, 500000000, 3 }, { 500000000, 1000000000, 2 }, { 1000000000, 1500000000, 1 }, { 1500000000, 2000000000, 0 }, }; -static struct pll_vco mmpll_gfx_vco[] = { +static const struct pll_vco mmpll_gfx_vco[] = { { 400000000, 1000000000, 2 }, { 1000000000, 1500000000, 1 }, { 1500000000, 2000000000, 0 }, }; -static struct pll_vco mmpll_t_vco[] = { +static const struct pll_vco mmpll_t_vco[] = { { 500000000, 1500000000, 0 }, }; @@ -3626,7 +3626,7 @@ static int mmcc_msm8996_probe(struct platform_device *pdev) /* Disable the NoC FSM for mmss_mmagic_cfg_ahb_clk */ regmap_update_bits(regmap, 0x5054, BIT(15), 0); - return qcom_cc_really_probe(pdev, &mmcc_msm8996_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &mmcc_msm8996_desc, regmap); } static struct platform_driver mmcc_msm8996_driver = { diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c index 275fb3b71ede..5738445a8656 100644 --- a/drivers/clk/qcom/mmcc-msm8998.c +++ b/drivers/clk/qcom/mmcc-msm8998.c @@ -2866,7 +2866,7 @@ static int mmcc_msm8998_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); - return qcom_cc_really_probe(pdev, &mmcc_msm8998_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &mmcc_msm8998_desc, regmap); } static struct platform_driver mmcc_msm8998_driver = { diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index 996bd01fb9ac..98ba5b4518fb 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -96,14 +96,14 @@ static struct clk_alpha_pll mmpll6 = { }; /* APSS controlled PLLs */ -static struct pll_vco vco[] = { +static const struct pll_vco vco[] = { { 1000000000, 2000000000, 0 }, { 750000000, 1500000000, 1 }, { 500000000, 1000000000, 2 }, { 250000000, 500000000, 3 }, }; -static struct pll_vco mmpll3_vco[] = { +static const struct pll_vco mmpll3_vco[] = { { 750000000, 1500000000, 1 }, }; @@ -2847,7 +2847,7 @@ static int mmcc_660_probe(struct platform_device *pdev) clk_alpha_pll_configure(&mmpll8, regmap, &mmpll8_config); clk_alpha_pll_configure(&mmpll10, regmap, &mmpll10_config); - return qcom_cc_really_probe(pdev, &mmcc_660_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &mmcc_660_desc, regmap); } static struct platform_driver mmcc_660_driver = { diff --git a/drivers/clk/qcom/nsscc-qca8k.c b/drivers/clk/qcom/nsscc-qca8k.c new file mode 100644 index 000000000000..5c8324e2bcca --- /dev/null +++ b/drivers/clk/qcom/nsscc-qca8k.c @@ -0,0 +1,2221 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include <linux/clk-provider.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regmap.h> +#include <linux/phy.h> +#include <linux/mdio.h> +#include <linux/clk.h> +#include <linux/gpio/consumer.h> + +#include <dt-bindings/clock/qcom,qca8k-nsscc.h> +#include <dt-bindings/reset/qcom,qca8k-nsscc.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 "reset.h" + +#define QCA8K_CLK_REG_BASE 0x800000 +#define QCA8K_HIGH_ADDR_PREFIX 0x18 +#define QCA8K_LOW_ADDR_PREFIX 0x10 +#define QCA8K_CFG_PAGE_REG 0xc +#define QCA8K_CLK_REG_MASK GENMASK(4, 0) +#define QCA8K_CLK_PHY_ADDR_MASK GENMASK(7, 5) +#define QCA8K_CLK_PAGE_MASK GENMASK(23, 8) +#define QCA8K_REG_DATA_UPPER_16_BITS BIT(1) + +enum { + DT_XO, + DT_UNIPHY0_RX_CLK, + DT_UNIPHY0_TX_CLK, + DT_UNIPHY1_RX_CLK, + DT_UNIPHY1_TX_CLK, + DT_UNIPHY1_RX312P5M_CLK, + DT_UNIPHY1_TX312P5M_CLK, +}; + +enum { + P_XO, + P_UNIPHY0_RX, + P_UNIPHY0_TX, + P_UNIPHY1_RX, + P_UNIPHY1_TX, + P_UNIPHY1_RX312P5M, + P_UNIPHY1_TX312P5M, + P_MAC4_RX_DIV, + P_MAC4_TX_DIV, + P_MAC5_RX_DIV, + P_MAC5_TX_DIV, +}; + +static const struct clk_parent_data nss_cc_uniphy1_tx312p5m_data[] = { + { .index = DT_XO }, + { .index = DT_UNIPHY1_TX312P5M_CLK }, +}; + +static const struct parent_map nss_cc_uniphy1_tx312p5m_map[] = { + { P_XO, 0 }, + { P_UNIPHY1_TX312P5M, 1 }, +}; + +static struct clk_rcg2 nss_cc_switch_core_clk_src = { + .cmd_rcgr = 0x0, + .hid_width = 5, + .parent_map = nss_cc_uniphy1_tx312p5m_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_switch_core_clk_src", + .parent_data = nss_cc_uniphy1_tx312p5m_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy1_tx312p5m_data), + .ops = &clk_rcg2_mux_closest_ops, + }, +}; + +static struct clk_branch nss_cc_switch_core_clk = { + .halt_reg = 0x8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_switch_core_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_switch_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_apb_bridge_clk = { + .halt_reg = 0x10, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_apb_bridge_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_switch_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct clk_parent_data nss_cc_uniphy1_tx_data[] = { + { .index = DT_XO }, + { .index = DT_UNIPHY1_TX_CLK }, +}; + +static const struct parent_map nss_cc_uniphy1_tx_map[] = { + { P_XO, 0 }, + { P_UNIPHY1_TX, 2 }, +}; + +static struct clk_rcg2 nss_cc_mac0_tx_clk_src = { + .cmd_rcgr = 0x14, + .hid_width = 5, + .parent_map = nss_cc_uniphy1_tx_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac0_tx_clk_src", + .parent_data = nss_cc_uniphy1_tx_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy1_tx_data), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_mux_closest_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac0_tx_div_clk_src = { + .reg = 0x1c, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac0_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac0_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac0_tx_clk = { + .halt_reg = 0x20, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac0_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac0_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac0_tx_srds1_clk = { + .halt_reg = 0x24, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x24, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac0_tx_srds1_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac0_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct clk_parent_data nss_cc_uniphy1_rx_tx_data[] = { + { .index = DT_XO }, + { .index = DT_UNIPHY1_RX_CLK }, + { .index = DT_UNIPHY1_TX_CLK }, +}; + +static const struct parent_map nss_cc_uniphy1_rx_tx_map[] = { + { P_XO, 0 }, + { P_UNIPHY1_RX, 1 }, + { P_UNIPHY1_TX, 2 }, +}; + +static struct clk_rcg2 nss_cc_mac0_rx_clk_src = { + .cmd_rcgr = 0x28, + .hid_width = 5, + .parent_map = nss_cc_uniphy1_rx_tx_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac0_rx_clk_src", + .parent_data = nss_cc_uniphy1_rx_tx_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy1_rx_tx_data), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_mux_closest_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac0_rx_div_clk_src = { + .reg = 0x30, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac0_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac0_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac0_rx_clk = { + .halt_reg = 0x34, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x34, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac0_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac0_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac0_rx_srds1_clk = { + .halt_reg = 0x3c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac0_rx_srds1_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac0_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct clk_parent_data nss_cc_uniphy1_rx_tx312p5m_data[] = { + { .index = DT_XO }, + { .index = DT_UNIPHY1_TX312P5M_CLK }, + { .index = DT_UNIPHY1_RX312P5M_CLK }, +}; + +static const struct parent_map nss_cc_uniphy1_rx_tx312p5m_map[] = { + { P_XO, 0 }, + { P_UNIPHY1_TX312P5M, 6 }, + { P_UNIPHY1_RX312P5M, 7 }, +}; + +static const struct freq_conf ftbl_nss_cc_mac1_tx_clk_src_25[] = { + C(P_UNIPHY1_TX312P5M, 12.5, 0, 0), + C(P_UNIPHY1_RX312P5M, 12.5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_mac1_tx_clk_src_125[] = { + C(P_UNIPHY1_TX312P5M, 2.5, 0, 0), + C(P_UNIPHY1_RX312P5M, 2.5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_mac1_tx_clk_src_312p5[] = { + C(P_UNIPHY1_TX312P5M, 1, 0, 0), + C(P_UNIPHY1_RX312P5M, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_mac1_tx_clk_src[] = { + FM(25000000, ftbl_nss_cc_mac1_tx_clk_src_25), + FMS(50000000, P_XO, 1, 0, 0), + FM(125000000, ftbl_nss_cc_mac1_tx_clk_src_125), + FM(312500000, ftbl_nss_cc_mac1_tx_clk_src_312p5), + { } +}; + +static struct clk_rcg2 nss_cc_mac1_tx_clk_src = { + .cmd_rcgr = 0x40, + .freq_multi_tbl = ftbl_nss_cc_mac1_tx_clk_src, + .hid_width = 5, + .parent_map = nss_cc_uniphy1_rx_tx312p5m_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_tx_clk_src", + .parent_data = nss_cc_uniphy1_rx_tx312p5m_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy1_rx_tx312p5m_data), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac1_tx_div_clk_src = { + .reg = 0x48, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_regmap_div nss_cc_mac1_srds1_ch0_xgmii_rx_div_clk_src = { + .reg = 0x4c, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_srds1_ch0_xgmii_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac1_srds1_ch0_rx_clk = { + .halt_reg = 0x50, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x50, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_srds1_ch0_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac1_tx_clk = { + .halt_reg = 0x54, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x54, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac1_gephy0_tx_clk = { + .halt_reg = 0x58, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x58, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_gephy0_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac1_srds1_ch0_xgmii_rx_clk = { + .halt_reg = 0x5c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_srds1_ch0_xgmii_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_srds1_ch0_xgmii_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct clk_parent_data nss_cc_uniphy1_tx312p5m_prx_data[] = { + { .index = DT_XO }, + { .index = DT_UNIPHY1_TX312P5M_CLK }, +}; + +static const struct parent_map nss_cc_uniphy1_tx312p5m_prx_map[] = { + { P_XO, 0 }, + { P_UNIPHY1_TX312P5M, 6 }, +}; + +static const struct freq_tbl ftbl_nss_cc_mac1_rx_clk_src[] = { + F(25000000, P_UNIPHY1_TX312P5M, 12.5, 0, 0), + F(50000000, P_XO, 1, 0, 0), + F(125000000, P_UNIPHY1_TX312P5M, 2.5, 0, 0), + F(312500000, P_UNIPHY1_TX312P5M, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_mac1_rx_clk_src = { + .cmd_rcgr = 0x60, + .freq_tbl = ftbl_nss_cc_mac1_rx_clk_src, + .hid_width = 5, + .parent_map = nss_cc_uniphy1_tx312p5m_prx_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_rx_clk_src", + .parent_data = nss_cc_uniphy1_tx312p5m_prx_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy1_tx312p5m_prx_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac1_rx_div_clk_src = { + .reg = 0x68, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_regmap_div nss_cc_mac1_srds1_ch0_xgmii_tx_div_clk_src = { + .reg = 0x6c, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_srds1_ch0_xgmii_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac1_srds1_ch0_tx_clk = { + .halt_reg = 0x70, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x70, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_srds1_ch0_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac1_rx_clk = { + .halt_reg = 0x74, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x74, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac1_gephy0_rx_clk = { + .halt_reg = 0x78, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x78, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_gephy0_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac1_srds1_ch0_xgmii_tx_clk = { + .halt_reg = 0x7c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac1_srds1_ch0_xgmii_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac1_srds1_ch0_xgmii_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_rcg2 nss_cc_mac2_tx_clk_src = { + .cmd_rcgr = 0x80, + .freq_multi_tbl = ftbl_nss_cc_mac1_tx_clk_src, + .hid_width = 5, + .parent_map = nss_cc_uniphy1_rx_tx312p5m_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_tx_clk_src", + .parent_data = nss_cc_uniphy1_rx_tx312p5m_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy1_rx_tx312p5m_data), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac2_tx_div_clk_src = { + .reg = 0x88, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_regmap_div nss_cc_mac2_srds1_ch1_xgmii_rx_div_clk_src = { + .reg = 0x8c, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_srds1_ch1_xgmii_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac2_srds1_ch1_rx_clk = { + .halt_reg = 0x90, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x90, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_srds1_ch1_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac2_tx_clk = { + .halt_reg = 0x94, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x94, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac2_gephy1_tx_clk = { + .halt_reg = 0x98, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x98, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_gephy1_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac2_srds1_ch1_xgmii_rx_clk = { + .halt_reg = 0x9c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_srds1_ch1_xgmii_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_srds1_ch1_xgmii_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_rcg2 nss_cc_mac2_rx_clk_src = { + .cmd_rcgr = 0xa0, + .freq_tbl = ftbl_nss_cc_mac1_rx_clk_src, + .hid_width = 5, + .parent_map = nss_cc_uniphy1_tx312p5m_prx_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_rx_clk_src", + .parent_data = nss_cc_uniphy1_tx312p5m_prx_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy1_tx312p5m_prx_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac2_rx_div_clk_src = { + .reg = 0xa8, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_regmap_div nss_cc_mac2_srds1_ch1_xgmii_tx_div_clk_src = { + .reg = 0xac, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_srds1_ch1_xgmii_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac2_srds1_ch1_tx_clk = { + .halt_reg = 0xb0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_srds1_ch1_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac2_rx_clk = { + .halt_reg = 0xb4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac2_gephy1_rx_clk = { + .halt_reg = 0xb8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_gephy1_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac2_srds1_ch1_xgmii_tx_clk = { + .halt_reg = 0xbc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xbc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac2_srds1_ch1_xgmii_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac2_srds1_ch1_xgmii_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_rcg2 nss_cc_mac3_tx_clk_src = { + .cmd_rcgr = 0xc0, + .freq_multi_tbl = ftbl_nss_cc_mac1_tx_clk_src, + .hid_width = 5, + .parent_map = nss_cc_uniphy1_rx_tx312p5m_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_tx_clk_src", + .parent_data = nss_cc_uniphy1_rx_tx312p5m_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy1_rx_tx312p5m_data), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac3_tx_div_clk_src = { + .reg = 0xc8, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_regmap_div nss_cc_mac3_srds1_ch2_xgmii_rx_div_clk_src = { + .reg = 0xcc, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_srds1_ch2_xgmii_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac3_srds1_ch2_rx_clk = { + .halt_reg = 0xd0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xd0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_srds1_ch2_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac3_tx_clk = { + .halt_reg = 0xd4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xd4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac3_gephy2_tx_clk = { + .halt_reg = 0xd8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xd8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_gephy2_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac3_srds1_ch2_xgmii_rx_clk = { + .halt_reg = 0xdc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xdc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_srds1_ch2_xgmii_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_srds1_ch2_xgmii_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_rcg2 nss_cc_mac3_rx_clk_src = { + .cmd_rcgr = 0xe0, + .freq_tbl = ftbl_nss_cc_mac1_rx_clk_src, + .hid_width = 5, + .parent_map = nss_cc_uniphy1_tx312p5m_prx_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_rx_clk_src", + .parent_data = nss_cc_uniphy1_tx312p5m_prx_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy1_tx312p5m_prx_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac3_rx_div_clk_src = { + .reg = 0xe8, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_regmap_div nss_cc_mac3_srds1_ch2_xgmii_tx_div_clk_src = { + .reg = 0xec, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_srds1_ch2_xgmii_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac3_srds1_ch2_tx_clk = { + .halt_reg = 0xf0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_srds1_ch2_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac3_rx_clk = { + .halt_reg = 0xf4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac3_gephy2_rx_clk = { + .halt_reg = 0xf8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_gephy2_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac3_srds1_ch2_xgmii_tx_clk = { + .halt_reg = 0xfc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xfc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac3_srds1_ch2_xgmii_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac3_srds1_ch2_xgmii_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct clk_parent_data nss_cc_uniphy0_rx_uniphy1_rx_tx312p5m_data[] = { + { .index = DT_XO }, + { .index = DT_UNIPHY0_RX_CLK }, + { .index = DT_UNIPHY1_TX312P5M_CLK }, + { .index = DT_UNIPHY1_RX312P5M_CLK }, +}; + +static const struct parent_map nss_cc_uniphy0_rx_uniphy1_rx_tx312p5m_map[] = { + { P_XO, 0 }, + { P_UNIPHY0_RX, 1 }, + { P_UNIPHY1_TX312P5M, 3 }, + { P_UNIPHY1_RX312P5M, 7 }, +}; + +static const struct freq_conf ftbl_nss_cc_mac4_tx_clk_src_25[] = { + C(P_UNIPHY0_RX, 12.5, 0, 0), + C(P_UNIPHY0_RX, 5, 0, 0), + C(P_UNIPHY1_TX312P5M, 12.5, 0, 0), + C(P_UNIPHY1_RX312P5M, 12.5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_mac4_tx_clk_src_125[] = { + C(P_UNIPHY0_RX, 1, 0, 0), + C(P_UNIPHY0_RX, 2.5, 0, 0), + C(P_UNIPHY1_TX312P5M, 2.5, 0, 0), + C(P_UNIPHY1_RX312P5M, 2.5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_mac4_tx_clk_src_312p5[] = { + C(P_UNIPHY0_RX, 1, 0, 0), + C(P_UNIPHY1_TX312P5M, 1, 0, 0), + C(P_UNIPHY1_RX312P5M, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_mac4_tx_clk_src[] = { + FM(25000000, ftbl_nss_cc_mac4_tx_clk_src_25), + FMS(50000000, P_XO, 1, 0, 0), + FM(125000000, ftbl_nss_cc_mac4_tx_clk_src_125), + FM(312500000, ftbl_nss_cc_mac4_tx_clk_src_312p5), + { } +}; + +static struct clk_rcg2 nss_cc_mac4_tx_clk_src = { + .cmd_rcgr = 0x100, + .freq_multi_tbl = ftbl_nss_cc_mac4_tx_clk_src, + .hid_width = 5, + .parent_map = nss_cc_uniphy0_rx_uniphy1_rx_tx312p5m_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_tx_clk_src", + .parent_data = nss_cc_uniphy0_rx_uniphy1_rx_tx312p5m_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy0_rx_uniphy1_rx_tx312p5m_data), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac4_tx_div_clk_src = { + .reg = 0x108, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_regmap_div nss_cc_mac4_srds1_ch3_xgmii_rx_div_clk_src = { + .reg = 0x10c, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_srds1_ch3_xgmii_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac4_srds1_ch3_rx_clk = { + .halt_reg = 0x110, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_srds1_ch3_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac4_tx_clk = { + .halt_reg = 0x114, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x114, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac4_gephy3_tx_clk = { + .halt_reg = 0x118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_gephy3_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac4_srds1_ch3_xgmii_rx_clk = { + .halt_reg = 0x11c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_srds1_ch3_xgmii_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_srds1_ch3_xgmii_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct clk_parent_data nss_cc_uniphy0_tx_uniphy1_tx312p5m_data[] = { + { .index = DT_XO }, + { .index = DT_UNIPHY0_TX_CLK }, + { .index = DT_UNIPHY1_TX312P5M_CLK }, +}; + +static const struct parent_map nss_cc_uniphy0_tx_uniphy1_tx312p5m_map[] = { + { P_XO, 0 }, + { P_UNIPHY0_TX, 2 }, + { P_UNIPHY1_TX312P5M, 3 }, +}; + +static const struct freq_conf ftbl_nss_cc_mac4_rx_clk_src_25[] = { + C(P_UNIPHY0_TX, 12.5, 0, 0), + C(P_UNIPHY0_TX, 5, 0, 0), + C(P_UNIPHY1_TX312P5M, 12.5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_mac4_rx_clk_src_125[] = { + C(P_UNIPHY0_TX, 1, 0, 0), + C(P_UNIPHY0_TX, 2.5, 0, 0), + C(P_UNIPHY1_TX312P5M, 2.5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_mac4_rx_clk_src_312p5[] = { + C(P_UNIPHY0_TX, 1, 0, 0), + C(P_UNIPHY1_TX312P5M, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_mac4_rx_clk_src[] = { + FM(25000000, ftbl_nss_cc_mac4_rx_clk_src_25), + FMS(50000000, P_XO, 1, 0, 0), + FM(125000000, ftbl_nss_cc_mac4_rx_clk_src_125), + FM(312500000, ftbl_nss_cc_mac4_rx_clk_src_312p5), + { } +}; + +static struct clk_rcg2 nss_cc_mac4_rx_clk_src = { + .cmd_rcgr = 0x120, + .freq_multi_tbl = ftbl_nss_cc_mac4_rx_clk_src, + .hid_width = 5, + .parent_map = nss_cc_uniphy0_tx_uniphy1_tx312p5m_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_rx_clk_src", + .parent_data = nss_cc_uniphy0_tx_uniphy1_tx312p5m_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy0_tx_uniphy1_tx312p5m_data), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac4_rx_div_clk_src = { + .reg = 0x128, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_regmap_div nss_cc_mac4_srds1_ch3_xgmii_tx_div_clk_src = { + .reg = 0x12c, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_srds1_ch3_xgmii_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac4_srds1_ch3_tx_clk = { + .halt_reg = 0x130, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x130, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_srds1_ch3_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac4_rx_clk = { + .halt_reg = 0x134, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac4_gephy3_rx_clk = { + .halt_reg = 0x138, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x138, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_gephy3_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac4_srds1_ch3_xgmii_tx_clk = { + .halt_reg = 0x13c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x13c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac4_srds1_ch3_xgmii_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_srds1_ch3_xgmii_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct clk_parent_data nss_cc_uniphy0_tx_data[] = { + { .index = DT_XO }, + { .index = DT_UNIPHY0_TX_CLK }, +}; + +static const struct parent_map nss_cc_uniphy0_tx_map[] = { + { P_XO, 0 }, + { P_UNIPHY0_TX, 2 }, +}; + +static struct clk_rcg2 nss_cc_mac5_tx_clk_src = { + .cmd_rcgr = 0x140, + .hid_width = 5, + .parent_map = nss_cc_uniphy0_tx_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac5_tx_clk_src", + .parent_data = nss_cc_uniphy0_tx_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy0_tx_data), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_mux_closest_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac5_tx_div_clk_src = { + .reg = 0x148, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac5_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac5_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac5_tx_clk = { + .halt_reg = 0x14c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac5_tx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac5_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct clk_parent_data nss_cc_uniphy0_rx_tx_data[] = { + { .index = DT_XO }, + { .index = DT_UNIPHY0_RX_CLK }, + { .index = DT_UNIPHY0_TX_CLK }, +}; + +static const struct parent_map nss_cc_uniphy0_rx_tx_map[] = { + { P_XO, 0 }, + { P_UNIPHY0_RX, 1 }, + { P_UNIPHY0_TX, 2 }, +}; + +static struct clk_rcg2 nss_cc_mac5_rx_clk_src = { + .cmd_rcgr = 0x154, + .hid_width = 5, + .parent_map = nss_cc_uniphy0_rx_tx_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac5_rx_clk_src", + .parent_data = nss_cc_uniphy0_rx_tx_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy0_rx_tx_data), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_mux_closest_ops, + }, +}; + +static struct clk_regmap_div nss_cc_mac5_rx_div_clk_src = { + .reg = 0x15c, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac5_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac5_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac5_rx_clk = { + .halt_reg = 0x160, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x160, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac5_rx_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac5_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct parent_map nss_cc_mac4_rx_div_mac5_tx_div_map[] = { + { P_MAC4_RX_DIV, 0 }, + { P_MAC5_TX_DIV, 1 }, +}; + +static struct clk_regmap_mux nss_cc_mac5_tx_srds0_clk_src = { + .reg = 0x300, + .shift = 0, + .width = 1, + .parent_map = nss_cc_mac4_rx_div_mac5_tx_div_map, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac5_tx_srds0_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_rx_div_clk_src.clkr.hw, + &nss_cc_mac5_tx_div_clk_src.clkr.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac5_tx_srds0_clk = { + .halt_reg = 0x150, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x150, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac5_tx_srds0_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac5_tx_srds0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct parent_map nss_cc_mac4_tx_div_mac5_rx_div_map[] = { + { P_MAC4_TX_DIV, 0 }, + { P_MAC5_RX_DIV, 1 }, +}; + +static struct clk_regmap_mux nss_cc_mac5_rx_srds0_clk_src = { + .reg = 0x300, + .shift = 1, + .width = 1, + .parent_map = nss_cc_mac4_tx_div_mac5_rx_div_map, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac5_rx_srds0_clk_src", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac4_tx_div_clk_src.clkr.hw, + &nss_cc_mac5_rx_div_clk_src.clkr.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mac5_rx_srds0_clk = { + .halt_reg = 0x164, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x164, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mac5_rx_srds0_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_mac5_rx_srds0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct parent_map nss_cc_uniphy1_tx312p5m_map2[] = { + { P_XO, 0 }, + { P_UNIPHY1_TX312P5M, 2 }, +}; + +static const struct freq_tbl ftbl_nss_cc_ahb_clk_src[] = { + F(50000000, P_XO, 1, 0, 0), + F(104170000, P_UNIPHY1_TX312P5M, 3, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_ahb_clk_src = { + .cmd_rcgr = 0x168, + .freq_tbl = ftbl_nss_cc_ahb_clk_src, + .hid_width = 5, + .parent_map = nss_cc_uniphy1_tx312p5m_map2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ahb_clk_src", + .parent_data = nss_cc_uniphy1_tx312p5m_data, + .num_parents = ARRAY_SIZE(nss_cc_uniphy1_tx312p5m_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch nss_cc_ahb_clk = { + .halt_reg = 0x170, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x170, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ahb_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_sec_ctrl_ahb_clk = { + .halt_reg = 0x174, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x174, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_sec_ctrl_ahb_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_tlmm_clk = { + .halt_reg = 0x178, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x178, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_tlmm_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_tlmm_ahb_clk = { + .halt_reg = 0x190, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x190, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_tlmm_ahb_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_cnoc_ahb_clk = { + .halt_reg = 0x194, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x194, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_cnoc_ahb_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mdio_ahb_clk = { + .halt_reg = 0x198, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x198, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mdio_ahb_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_mdio_master_ahb_clk = { + .halt_reg = 0x19c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x19c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_mdio_master_ahb_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static const struct clk_parent_data nss_cc_xo_data[] = { + { .index = DT_XO }, +}; + +static const struct parent_map nss_cc_xo_map[] = { + { P_XO, 0 }, +}; + +static const struct freq_tbl ftbl_nss_cc_sys_clk_src[] = { + F(25000000, P_XO, 2, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_sys_clk_src = { + .cmd_rcgr = 0x1a0, + .freq_tbl = ftbl_nss_cc_sys_clk_src, + .hid_width = 5, + .parent_map = nss_cc_xo_map, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_sys_clk_src", + .parent_data = nss_cc_xo_data, + .num_parents = ARRAY_SIZE(nss_cc_xo_data), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch nss_cc_srds0_sys_clk = { + .halt_reg = 0x1a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_srds0_sys_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_srds1_sys_clk = { + .halt_reg = 0x1ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_srds1_sys_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_gephy0_sys_clk = { + .halt_reg = 0x1b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_gephy0_sys_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_gephy1_sys_clk = { + .halt_reg = 0x1b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_gephy1_sys_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_gephy2_sys_clk = { + .halt_reg = 0x1b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_gephy2_sys_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_branch nss_cc_gephy3_sys_clk = { + .halt_reg = 0x1bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_gephy3_sys_clk", + .parent_hws = (const struct clk_hw *[]) { + &nss_cc_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_prepare_ops, + }, + }, +}; + +static struct clk_regmap *nss_cc_qca8k_clocks[] = { + [NSS_CC_SWITCH_CORE_CLK_SRC] = &nss_cc_switch_core_clk_src.clkr, + [NSS_CC_SWITCH_CORE_CLK] = &nss_cc_switch_core_clk.clkr, + [NSS_CC_APB_BRIDGE_CLK] = &nss_cc_apb_bridge_clk.clkr, + [NSS_CC_MAC0_TX_CLK_SRC] = &nss_cc_mac0_tx_clk_src.clkr, + [NSS_CC_MAC0_TX_DIV_CLK_SRC] = &nss_cc_mac0_tx_div_clk_src.clkr, + [NSS_CC_MAC0_TX_CLK] = &nss_cc_mac0_tx_clk.clkr, + [NSS_CC_MAC0_TX_SRDS1_CLK] = &nss_cc_mac0_tx_srds1_clk.clkr, + [NSS_CC_MAC0_RX_CLK_SRC] = &nss_cc_mac0_rx_clk_src.clkr, + [NSS_CC_MAC0_RX_DIV_CLK_SRC] = &nss_cc_mac0_rx_div_clk_src.clkr, + [NSS_CC_MAC0_RX_CLK] = &nss_cc_mac0_rx_clk.clkr, + [NSS_CC_MAC0_RX_SRDS1_CLK] = &nss_cc_mac0_rx_srds1_clk.clkr, + [NSS_CC_MAC1_TX_CLK_SRC] = &nss_cc_mac1_tx_clk_src.clkr, + [NSS_CC_MAC1_TX_DIV_CLK_SRC] = &nss_cc_mac1_tx_div_clk_src.clkr, + [NSS_CC_MAC1_SRDS1_CH0_XGMII_RX_DIV_CLK_SRC] = + &nss_cc_mac1_srds1_ch0_xgmii_rx_div_clk_src.clkr, + [NSS_CC_MAC1_SRDS1_CH0_RX_CLK] = &nss_cc_mac1_srds1_ch0_rx_clk.clkr, + [NSS_CC_MAC1_TX_CLK] = &nss_cc_mac1_tx_clk.clkr, + [NSS_CC_MAC1_GEPHY0_TX_CLK] = &nss_cc_mac1_gephy0_tx_clk.clkr, + [NSS_CC_MAC1_SRDS1_CH0_XGMII_RX_CLK] = &nss_cc_mac1_srds1_ch0_xgmii_rx_clk.clkr, + [NSS_CC_MAC1_RX_CLK_SRC] = &nss_cc_mac1_rx_clk_src.clkr, + [NSS_CC_MAC1_RX_DIV_CLK_SRC] = &nss_cc_mac1_rx_div_clk_src.clkr, + [NSS_CC_MAC1_SRDS1_CH0_XGMII_TX_DIV_CLK_SRC] = + &nss_cc_mac1_srds1_ch0_xgmii_tx_div_clk_src.clkr, + [NSS_CC_MAC1_SRDS1_CH0_TX_CLK] = &nss_cc_mac1_srds1_ch0_tx_clk.clkr, + [NSS_CC_MAC1_RX_CLK] = &nss_cc_mac1_rx_clk.clkr, + [NSS_CC_MAC1_GEPHY0_RX_CLK] = &nss_cc_mac1_gephy0_rx_clk.clkr, + [NSS_CC_MAC1_SRDS1_CH0_XGMII_TX_CLK] = &nss_cc_mac1_srds1_ch0_xgmii_tx_clk.clkr, + [NSS_CC_MAC2_TX_CLK_SRC] = &nss_cc_mac2_tx_clk_src.clkr, + [NSS_CC_MAC2_TX_DIV_CLK_SRC] = &nss_cc_mac2_tx_div_clk_src.clkr, + [NSS_CC_MAC2_SRDS1_CH1_XGMII_RX_DIV_CLK_SRC] = + &nss_cc_mac2_srds1_ch1_xgmii_rx_div_clk_src.clkr, + [NSS_CC_MAC2_SRDS1_CH1_RX_CLK] = &nss_cc_mac2_srds1_ch1_rx_clk.clkr, + [NSS_CC_MAC2_TX_CLK] = &nss_cc_mac2_tx_clk.clkr, + [NSS_CC_MAC2_GEPHY1_TX_CLK] = &nss_cc_mac2_gephy1_tx_clk.clkr, + [NSS_CC_MAC2_SRDS1_CH1_XGMII_RX_CLK] = &nss_cc_mac2_srds1_ch1_xgmii_rx_clk.clkr, + [NSS_CC_MAC2_RX_CLK_SRC] = &nss_cc_mac2_rx_clk_src.clkr, + [NSS_CC_MAC2_RX_DIV_CLK_SRC] = &nss_cc_mac2_rx_div_clk_src.clkr, + [NSS_CC_MAC2_SRDS1_CH1_XGMII_TX_DIV_CLK_SRC] = + &nss_cc_mac2_srds1_ch1_xgmii_tx_div_clk_src.clkr, + [NSS_CC_MAC2_SRDS1_CH1_TX_CLK] = &nss_cc_mac2_srds1_ch1_tx_clk.clkr, + [NSS_CC_MAC2_RX_CLK] = &nss_cc_mac2_rx_clk.clkr, + [NSS_CC_MAC2_GEPHY1_RX_CLK] = &nss_cc_mac2_gephy1_rx_clk.clkr, + [NSS_CC_MAC2_SRDS1_CH1_XGMII_TX_CLK] = &nss_cc_mac2_srds1_ch1_xgmii_tx_clk.clkr, + [NSS_CC_MAC3_TX_CLK_SRC] = &nss_cc_mac3_tx_clk_src.clkr, + [NSS_CC_MAC3_TX_DIV_CLK_SRC] = &nss_cc_mac3_tx_div_clk_src.clkr, + [NSS_CC_MAC3_SRDS1_CH2_XGMII_RX_DIV_CLK_SRC] = + &nss_cc_mac3_srds1_ch2_xgmii_rx_div_clk_src.clkr, + [NSS_CC_MAC3_SRDS1_CH2_RX_CLK] = &nss_cc_mac3_srds1_ch2_rx_clk.clkr, + [NSS_CC_MAC3_TX_CLK] = &nss_cc_mac3_tx_clk.clkr, + [NSS_CC_MAC3_GEPHY2_TX_CLK] = &nss_cc_mac3_gephy2_tx_clk.clkr, + [NSS_CC_MAC3_SRDS1_CH2_XGMII_RX_CLK] = &nss_cc_mac3_srds1_ch2_xgmii_rx_clk.clkr, + [NSS_CC_MAC3_RX_CLK_SRC] = &nss_cc_mac3_rx_clk_src.clkr, + [NSS_CC_MAC3_RX_DIV_CLK_SRC] = &nss_cc_mac3_rx_div_clk_src.clkr, + [NSS_CC_MAC3_SRDS1_CH2_XGMII_TX_DIV_CLK_SRC] = + &nss_cc_mac3_srds1_ch2_xgmii_tx_div_clk_src.clkr, + [NSS_CC_MAC3_SRDS1_CH2_TX_CLK] = &nss_cc_mac3_srds1_ch2_tx_clk.clkr, + [NSS_CC_MAC3_RX_CLK] = &nss_cc_mac3_rx_clk.clkr, + [NSS_CC_MAC3_GEPHY2_RX_CLK] = &nss_cc_mac3_gephy2_rx_clk.clkr, + [NSS_CC_MAC3_SRDS1_CH2_XGMII_TX_CLK] = &nss_cc_mac3_srds1_ch2_xgmii_tx_clk.clkr, + [NSS_CC_MAC4_TX_CLK_SRC] = &nss_cc_mac4_tx_clk_src.clkr, + [NSS_CC_MAC4_TX_DIV_CLK_SRC] = &nss_cc_mac4_tx_div_clk_src.clkr, + [NSS_CC_MAC4_SRDS1_CH3_XGMII_RX_DIV_CLK_SRC] = + &nss_cc_mac4_srds1_ch3_xgmii_rx_div_clk_src.clkr, + [NSS_CC_MAC4_SRDS1_CH3_RX_CLK] = &nss_cc_mac4_srds1_ch3_rx_clk.clkr, + [NSS_CC_MAC4_TX_CLK] = &nss_cc_mac4_tx_clk.clkr, + [NSS_CC_MAC4_GEPHY3_TX_CLK] = &nss_cc_mac4_gephy3_tx_clk.clkr, + [NSS_CC_MAC4_SRDS1_CH3_XGMII_RX_CLK] = &nss_cc_mac4_srds1_ch3_xgmii_rx_clk.clkr, + [NSS_CC_MAC4_RX_CLK_SRC] = &nss_cc_mac4_rx_clk_src.clkr, + [NSS_CC_MAC4_RX_DIV_CLK_SRC] = &nss_cc_mac4_rx_div_clk_src.clkr, + [NSS_CC_MAC4_SRDS1_CH3_XGMII_TX_DIV_CLK_SRC] = + &nss_cc_mac4_srds1_ch3_xgmii_tx_div_clk_src.clkr, + [NSS_CC_MAC4_SRDS1_CH3_TX_CLK] = &nss_cc_mac4_srds1_ch3_tx_clk.clkr, + [NSS_CC_MAC4_RX_CLK] = &nss_cc_mac4_rx_clk.clkr, + [NSS_CC_MAC4_GEPHY3_RX_CLK] = &nss_cc_mac4_gephy3_rx_clk.clkr, + [NSS_CC_MAC4_SRDS1_CH3_XGMII_TX_CLK] = &nss_cc_mac4_srds1_ch3_xgmii_tx_clk.clkr, + [NSS_CC_MAC5_TX_CLK_SRC] = &nss_cc_mac5_tx_clk_src.clkr, + [NSS_CC_MAC5_TX_DIV_CLK_SRC] = &nss_cc_mac5_tx_div_clk_src.clkr, + [NSS_CC_MAC5_TX_SRDS0_CLK] = &nss_cc_mac5_tx_srds0_clk.clkr, + [NSS_CC_MAC5_TX_CLK] = &nss_cc_mac5_tx_clk.clkr, + [NSS_CC_MAC5_RX_CLK_SRC] = &nss_cc_mac5_rx_clk_src.clkr, + [NSS_CC_MAC5_RX_DIV_CLK_SRC] = &nss_cc_mac5_rx_div_clk_src.clkr, + [NSS_CC_MAC5_RX_SRDS0_CLK] = &nss_cc_mac5_rx_srds0_clk.clkr, + [NSS_CC_MAC5_RX_CLK] = &nss_cc_mac5_rx_clk.clkr, + [NSS_CC_MAC5_TX_SRDS0_CLK_SRC] = &nss_cc_mac5_tx_srds0_clk_src.clkr, + [NSS_CC_MAC5_RX_SRDS0_CLK_SRC] = &nss_cc_mac5_rx_srds0_clk_src.clkr, + [NSS_CC_AHB_CLK_SRC] = &nss_cc_ahb_clk_src.clkr, + [NSS_CC_AHB_CLK] = &nss_cc_ahb_clk.clkr, + [NSS_CC_SEC_CTRL_AHB_CLK] = &nss_cc_sec_ctrl_ahb_clk.clkr, + [NSS_CC_TLMM_CLK] = &nss_cc_tlmm_clk.clkr, + [NSS_CC_TLMM_AHB_CLK] = &nss_cc_tlmm_ahb_clk.clkr, + [NSS_CC_CNOC_AHB_CLK] = &nss_cc_cnoc_ahb_clk.clkr, + [NSS_CC_MDIO_AHB_CLK] = &nss_cc_mdio_ahb_clk.clkr, + [NSS_CC_MDIO_MASTER_AHB_CLK] = &nss_cc_mdio_master_ahb_clk.clkr, + [NSS_CC_SYS_CLK_SRC] = &nss_cc_sys_clk_src.clkr, + [NSS_CC_SRDS0_SYS_CLK] = &nss_cc_srds0_sys_clk.clkr, + [NSS_CC_SRDS1_SYS_CLK] = &nss_cc_srds1_sys_clk.clkr, + [NSS_CC_GEPHY0_SYS_CLK] = &nss_cc_gephy0_sys_clk.clkr, + [NSS_CC_GEPHY1_SYS_CLK] = &nss_cc_gephy1_sys_clk.clkr, + [NSS_CC_GEPHY2_SYS_CLK] = &nss_cc_gephy2_sys_clk.clkr, + [NSS_CC_GEPHY3_SYS_CLK] = &nss_cc_gephy3_sys_clk.clkr, +}; + +static const struct qcom_reset_map nss_cc_qca8k_resets[] = { + [NSS_CC_SWITCH_CORE_ARES] = { 0xc, 2 }, + [NSS_CC_APB_BRIDGE_ARES] = { 0x10, 2 }, + [NSS_CC_MAC0_TX_ARES] = { 0x20, 2 }, + [NSS_CC_MAC0_TX_SRDS1_ARES] = { 0x24, 2 }, + [NSS_CC_MAC0_RX_ARES] = { 0x34, 2 }, + [NSS_CC_MAC0_RX_SRDS1_ARES] = { 0x3c, 2 }, + [NSS_CC_MAC1_SRDS1_CH0_RX_ARES] = { 0x50, 2 }, + [NSS_CC_MAC1_TX_ARES] = { 0x54, 2 }, + [NSS_CC_MAC1_GEPHY0_TX_ARES] = { 0x58, 2 }, + [NSS_CC_MAC1_SRDS1_CH0_XGMII_RX_ARES] = { 0x5c, 2 }, + [NSS_CC_MAC1_SRDS1_CH0_TX_ARES] = { 0x70, 2 }, + [NSS_CC_MAC1_RX_ARES] = { 0x74, 2 }, + [NSS_CC_MAC1_GEPHY0_RX_ARES] = { 0x78, 2 }, + [NSS_CC_MAC1_SRDS1_CH0_XGMII_TX_ARES] = { 0x7c, 2 }, + [NSS_CC_MAC2_SRDS1_CH1_RX_ARES] = { 0x90, 2 }, + [NSS_CC_MAC2_TX_ARES] = { 0x94, 2 }, + [NSS_CC_MAC2_GEPHY1_TX_ARES] = { 0x98, 2 }, + [NSS_CC_MAC2_SRDS1_CH1_XGMII_RX_ARES] = { 0x9c, 2 }, + [NSS_CC_MAC2_SRDS1_CH1_TX_ARES] = { 0xb0, 2 }, + [NSS_CC_MAC2_RX_ARES] = { 0xb4, 2 }, + [NSS_CC_MAC2_GEPHY1_RX_ARES] = { 0xb8, 2 }, + [NSS_CC_MAC2_SRDS1_CH1_XGMII_TX_ARES] = { 0xbc, 2 }, + [NSS_CC_MAC3_SRDS1_CH2_RX_ARES] = { 0xd0, 2 }, + [NSS_CC_MAC3_TX_ARES] = { 0xd4, 2 }, + [NSS_CC_MAC3_GEPHY2_TX_ARES] = { 0xd8, 2 }, + [NSS_CC_MAC3_SRDS1_CH2_XGMII_RX_ARES] = { 0xdc, 2 }, + [NSS_CC_MAC3_SRDS1_CH2_TX_ARES] = { 0xf0, 2 }, + [NSS_CC_MAC3_RX_ARES] = { 0xf4, 2 }, + [NSS_CC_MAC3_GEPHY2_RX_ARES] = { 0xf8, 2 }, + [NSS_CC_MAC3_SRDS1_CH2_XGMII_TX_ARES] = { 0xfc, 2 }, + [NSS_CC_MAC4_SRDS1_CH3_RX_ARES] = { 0x110, 2 }, + [NSS_CC_MAC4_TX_ARES] = { 0x114, 2 }, + [NSS_CC_MAC4_GEPHY3_TX_ARES] = { 0x118, 2 }, + [NSS_CC_MAC4_SRDS1_CH3_XGMII_RX_ARES] = { 0x11c, 2 }, + [NSS_CC_MAC4_SRDS1_CH3_TX_ARES] = { 0x130, 2 }, + [NSS_CC_MAC4_RX_ARES] = { 0x134, 2 }, + [NSS_CC_MAC4_GEPHY3_RX_ARES] = { 0x138, 2 }, + [NSS_CC_MAC4_SRDS1_CH3_XGMII_TX_ARES] = { 0x13c, 2 }, + [NSS_CC_MAC5_TX_ARES] = { 0x14c, 2 }, + [NSS_CC_MAC5_TX_SRDS0_ARES] = { 0x150, 2 }, + [NSS_CC_MAC5_RX_ARES] = { 0x160, 2 }, + [NSS_CC_MAC5_RX_SRDS0_ARES] = { 0x164, 2 }, + [NSS_CC_AHB_ARES] = { 0x170, 2 }, + [NSS_CC_SEC_CTRL_AHB_ARES] = { 0x174, 2 }, + [NSS_CC_TLMM_ARES] = { 0x178, 2 }, + [NSS_CC_TLMM_AHB_ARES] = { 0x190, 2 }, + [NSS_CC_CNOC_AHB_ARES] = { 0x194, 2 }, /* reset CNOC AHB & APB */ + [NSS_CC_MDIO_AHB_ARES] = { 0x198, 2 }, + [NSS_CC_MDIO_MASTER_AHB_ARES] = { 0x19c, 2 }, + [NSS_CC_SRDS0_SYS_ARES] = { 0x1a8, 2 }, + [NSS_CC_SRDS1_SYS_ARES] = { 0x1ac, 2 }, + [NSS_CC_GEPHY0_SYS_ARES] = { 0x1b0, 2 }, + [NSS_CC_GEPHY1_SYS_ARES] = { 0x1b4, 2 }, + [NSS_CC_GEPHY2_SYS_ARES] = { 0x1b8, 2 }, + [NSS_CC_GEPHY3_SYS_ARES] = { 0x1bc, 2 }, + [NSS_CC_SEC_CTRL_ARES] = { 0x1c8, 2 }, + [NSS_CC_SEC_CTRL_SENSE_ARES] = { 0x1d0, 2 }, + [NSS_CC_SLEEP_ARES] = { 0x1e0, 2 }, + [NSS_CC_DEBUG_ARES] = { 0x1e8, 2 }, + [NSS_CC_GEPHY0_ARES] = { 0x304, 0 }, + [NSS_CC_GEPHY1_ARES] = { 0x304, 1 }, + [NSS_CC_GEPHY2_ARES] = { 0x304, 2 }, + [NSS_CC_GEPHY3_ARES] = { 0x304, 3 }, + [NSS_CC_DSP_ARES] = { 0x304, 4 }, + [NSS_CC_GEPHY_FULL_ARES] = { .reg = 0x304, .bitmask = GENMASK(4, 0) }, + [NSS_CC_GLOBAL_ARES] = { 0x308, 0 }, + [NSS_CC_XPCS_ARES] = { 0x30c, 0 }, +}; + +/* For each read/write operation of clock register, there are three MDIO frames + * sent to the device. + * + * 1. The high address part[23:8] of register is packaged into the first MDIO frame + * for selecting page. + * 2. The low address part[7:0] of register is packaged into the second MDIO frame + * with the low 16bit data to read/write. + * 3. The low address part[7:0] of register is packaged into the last MDIO frame + * with the high 16bit data to read/write. + * + * The clause22 MDIO frame format used by device is as below. + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ST| OP| ADDR | REG | TA| DATA | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +static inline void convert_reg_to_mii_addr(u32 regaddr, u16 *reg, u16 *phy_addr, u16 *page) +{ + *reg = FIELD_GET(QCA8K_CLK_REG_MASK, regaddr); + *phy_addr = FIELD_GET(QCA8K_CLK_PHY_ADDR_MASK, regaddr) | QCA8K_LOW_ADDR_PREFIX; + *page = FIELD_GET(QCA8K_CLK_PAGE_MASK, regaddr); +} + +static int qca8k_mii_read(struct mii_bus *bus, u16 switch_phy_id, u32 reg, u32 *val) +{ + int ret, data; + + ret = __mdiobus_read(bus, switch_phy_id, reg); + if (ret >= 0) { + data = ret; + + ret = __mdiobus_read(bus, switch_phy_id, (reg | QCA8K_REG_DATA_UPPER_16_BITS)); + if (ret >= 0) + *val = data | ret << 16; + } + + if (ret < 0) + dev_err_ratelimited(&bus->dev, "fail to read qca8k mii register\n"); + + return ret < 0 ? ret : 0; +} + +static void qca8k_mii_write(struct mii_bus *bus, u16 switch_phy_id, u32 reg, u32 val) +{ + int ret; + + ret = __mdiobus_write(bus, switch_phy_id, reg, lower_16_bits(val)); + if (ret >= 0) + ret = __mdiobus_write(bus, switch_phy_id, (reg | QCA8K_REG_DATA_UPPER_16_BITS), + upper_16_bits(val)); + + if (ret < 0) + dev_err_ratelimited(&bus->dev, "fail to write qca8k mii register\n"); +} + +static int qca8k_mii_page_set(struct mii_bus *bus, u16 switch_phy_id, u32 reg, u16 page) +{ + int ret; + + ret = __mdiobus_write(bus, switch_phy_id, reg, page); + if (ret < 0) + dev_err_ratelimited(&bus->dev, "fail to set page\n"); + + return ret; +} + +static int qca8k_regmap_read(void *context, unsigned int regaddr, unsigned int *val) +{ + struct mii_bus *bus = context; + u16 reg, phy_addr, page; + int ret; + + regaddr += QCA8K_CLK_REG_BASE; + convert_reg_to_mii_addr(regaddr, ®, &phy_addr, &page); + + mutex_lock(&bus->mdio_lock); + ret = qca8k_mii_page_set(bus, QCA8K_HIGH_ADDR_PREFIX, QCA8K_CFG_PAGE_REG, page); + if (ret < 0) + goto qca8k_read_exit; + + ret = qca8k_mii_read(bus, phy_addr, reg, val); + +qca8k_read_exit: + mutex_unlock(&bus->mdio_lock); + return ret; +}; + +static int qca8k_regmap_write(void *context, unsigned int regaddr, unsigned int val) +{ + struct mii_bus *bus = context; + u16 reg, phy_addr, page; + int ret; + + regaddr += QCA8K_CLK_REG_BASE; + convert_reg_to_mii_addr(regaddr, ®, &phy_addr, &page); + + mutex_lock(&bus->mdio_lock); + ret = qca8k_mii_page_set(bus, QCA8K_HIGH_ADDR_PREFIX, QCA8K_CFG_PAGE_REG, page); + if (ret < 0) + goto qca8k_write_exit; + + qca8k_mii_write(bus, phy_addr, reg, val); + +qca8k_write_exit: + mutex_unlock(&bus->mdio_lock); + return ret; +}; + +static int qca8k_regmap_update_bits(void *context, unsigned int regaddr, + unsigned int mask, unsigned int value) +{ + struct mii_bus *bus = context; + u16 reg, phy_addr, page; + int ret; + u32 val; + + regaddr += QCA8K_CLK_REG_BASE; + convert_reg_to_mii_addr(regaddr, ®, &phy_addr, &page); + + mutex_lock(&bus->mdio_lock); + ret = qca8k_mii_page_set(bus, QCA8K_HIGH_ADDR_PREFIX, QCA8K_CFG_PAGE_REG, page); + if (ret < 0) + goto qca8k_update_exit; + + ret = qca8k_mii_read(bus, phy_addr, reg, &val); + if (ret < 0) + goto qca8k_update_exit; + + val &= ~mask; + val |= value; + qca8k_mii_write(bus, phy_addr, reg, val); + +qca8k_update_exit: + mutex_unlock(&bus->mdio_lock); + return ret; +} + +static const struct regmap_config nss_cc_qca8k_regmap_config = { + .reg_bits = 12, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x30c, + .reg_read = qca8k_regmap_read, + .reg_write = qca8k_regmap_write, + .reg_update_bits = qca8k_regmap_update_bits, + .disable_locking = true, +}; + +static const struct qcom_cc_desc nss_cc_qca8k_desc = { + .config = &nss_cc_qca8k_regmap_config, + .clks = nss_cc_qca8k_clocks, + .num_clks = ARRAY_SIZE(nss_cc_qca8k_clocks), + .resets = nss_cc_qca8k_resets, + .num_resets = ARRAY_SIZE(nss_cc_qca8k_resets), +}; + +/* + * The reference clock of QCA8k NSSCC needs to be enabled to make sure + * the GPIO reset taking effect. + */ +static int nss_cc_qca8k_clock_enable_and_reset(struct device *dev) +{ + struct gpio_desc *gpiod; + struct clk *clk; + + clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(gpiod)) { + return PTR_ERR(gpiod); + } else if (gpiod) { + msleep(100); + gpiod_set_value_cansleep(gpiod, 0); + } + + return 0; +} + +static int nss_cc_qca8k_probe(struct mdio_device *mdiodev) +{ + struct regmap *regmap; + int ret; + + ret = nss_cc_qca8k_clock_enable_and_reset(&mdiodev->dev); + if (ret) + return dev_err_probe(&mdiodev->dev, ret, "Fail to reset NSSCC\n"); + + regmap = devm_regmap_init(&mdiodev->dev, NULL, mdiodev->bus, nss_cc_qca8k_desc.config); + if (IS_ERR(regmap)) + return dev_err_probe(&mdiodev->dev, PTR_ERR(regmap), "Failed to init regmap\n"); + + return qcom_cc_really_probe(&mdiodev->dev, &nss_cc_qca8k_desc, regmap); +} + +static const struct of_device_id nss_cc_qca8k_match_table[] = { + { .compatible = "qcom,qca8084-nsscc" }, + { } +}; +MODULE_DEVICE_TABLE(of, nss_cc_qca8k_match_table); + +static struct mdio_driver nss_cc_qca8k_driver = { + .mdiodrv.driver = { + .name = "qcom,qca8k-nsscc", + .of_match_table = nss_cc_qca8k_match_table, + }, + .probe = nss_cc_qca8k_probe, +}; + +mdio_module_driver(nss_cc_qca8k_driver); + +MODULE_DESCRIPTION("QCOM NSS_CC QCA8K Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/tcsrcc-sm8550.c b/drivers/clk/qcom/tcsrcc-sm8550.c index 552a3eb1fd91..e5e8f2e82b94 100644 --- a/drivers/clk/qcom/tcsrcc-sm8550.c +++ b/drivers/clk/qcom/tcsrcc-sm8550.c @@ -166,7 +166,7 @@ static int tcsr_cc_sm8550_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); - return qcom_cc_really_probe(pdev, &tcsr_cc_sm8550_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &tcsr_cc_sm8550_desc, regmap); } static struct platform_driver tcsr_cc_sm8550_driver = { diff --git a/drivers/clk/qcom/videocc-sc7180.c b/drivers/clk/qcom/videocc-sc7180.c index ae0f812f83e8..d7f845480396 100644 --- a/drivers/clk/qcom/videocc-sc7180.c +++ b/drivers/clk/qcom/videocc-sc7180.c @@ -226,7 +226,7 @@ static int video_cc_sc7180_probe(struct platform_device *pdev) /* Keep VIDEO_CC_XO_CLK ALWAYS-ON */ regmap_update_bits(regmap, 0x984, 0x1, 0x1); - return qcom_cc_really_probe(pdev, &video_cc_sc7180_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &video_cc_sc7180_desc, regmap); } static struct platform_driver video_cc_sc7180_driver = { diff --git a/drivers/clk/qcom/videocc-sc7280.c b/drivers/clk/qcom/videocc-sc7280.c index cdd59c6f60df..317b325d6daf 100644 --- a/drivers/clk/qcom/videocc-sc7280.c +++ b/drivers/clk/qcom/videocc-sc7280.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/clk-provider.h> @@ -232,6 +233,9 @@ static struct clk_branch video_cc_venus_ahb_clk = { static struct gdsc mvs0_gdsc = { .gdscr = 0x3004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, .pd = { .name = "mvs0_gdsc", }, @@ -241,6 +245,9 @@ static struct gdsc mvs0_gdsc = { static struct gdsc mvsc_gdsc = { .gdscr = 0x2004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, .pd = { .name = "mvsc_gdsc", }, @@ -298,7 +305,7 @@ static int video_cc_sc7280_probe(struct platform_device *pdev) clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config); - return qcom_cc_really_probe(pdev, &video_cc_sc7280_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &video_cc_sc7280_desc, regmap); } static struct platform_driver video_cc_sc7280_driver = { diff --git a/drivers/clk/qcom/videocc-sdm845.c b/drivers/clk/qcom/videocc-sdm845.c index b7f21ecad961..f77a07779477 100644 --- a/drivers/clk/qcom/videocc-sdm845.c +++ b/drivers/clk/qcom/videocc-sdm845.c @@ -329,7 +329,7 @@ static int video_cc_sdm845_probe(struct platform_device *pdev) clk_fabia_pll_configure(&video_pll0, regmap, &video_pll0_config); - return qcom_cc_really_probe(pdev, &video_cc_sdm845_desc, regmap); + return qcom_cc_really_probe(&pdev->dev, &video_cc_sdm845_desc, regmap); } static struct platform_driver video_cc_sdm845_driver = { @@ -343,3 +343,4 @@ static struct platform_driver video_cc_sdm845_driver = { module_platform_driver(video_cc_sdm845_driver); MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("QTI SDM845 VIDEOCC Driver"); diff --git a/drivers/clk/qcom/videocc-sm7150.c b/drivers/clk/qcom/videocc-sm7150.c new file mode 100644 index 000000000000..14ef7f561753 --- /dev/null +++ b/drivers/clk/qcom/videocc-sm7150.c @@ -0,0 +1,357 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com> + */ + +#include <linux/clk-provider.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,sm7150-videocc.h> + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "gdsc.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, +}; + +enum { + P_BI_TCXO, + P_VIDEOCC_PLL0_OUT_EVEN, + P_VIDEOCC_PLL0_OUT_MAIN, + P_VIDEOCC_PLL0_OUT_ODD, +}; + +static const struct pll_vco fabia_vco[] = { + { 249600000, 2000000000, 0 }, + { 125000000, 1000000000, 1 }, +}; + +static struct alpha_pll_config videocc_pll0_config = { + .l = 0x19, + .alpha = 0x0, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00002067, + .user_ctl_val = 0x00000001, + .user_ctl_hi_val = 0x00004805, + .test_ctl_hi_val = 0x40000000, +}; + +static struct clk_alpha_pll videocc_pll0 = { + .offset = 0x42c, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "videocc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static const struct parent_map videocc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_VIDEOCC_PLL0_OUT_MAIN, 1 }, + { P_VIDEOCC_PLL0_OUT_EVEN, 2 }, + { P_VIDEOCC_PLL0_OUT_ODD, 3 }, +}; + +static const struct clk_parent_data videocc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &videocc_pll0.clkr.hw }, + { .hw = &videocc_pll0.clkr.hw }, + { .hw = &videocc_pll0.clkr.hw }, +}; + +static const struct parent_map videocc_parent_map_1[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data videocc_parent_data_1[] = { + { .index = DT_BI_TCXO_AO }, +}; + +static const struct freq_tbl ftbl_videocc_iris_clk_src[] = { + F(240000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0), + F(365000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 videocc_iris_clk_src = { + .cmd_rcgr = 0x7f0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = videocc_parent_map_0, + .freq_tbl = ftbl_videocc_iris_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "videocc_iris_clk_src", + .parent_data = videocc_parent_data_0, + .num_parents = ARRAY_SIZE(videocc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_videocc_xo_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 videocc_xo_clk_src = { + .cmd_rcgr = 0xa98, + .mnd_width = 0, + .hid_width = 5, + .parent_map = videocc_parent_map_1, + .freq_tbl = ftbl_videocc_xo_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "videocc_xo_clk_src", + .parent_data = videocc_parent_data_1, + .num_parents = ARRAY_SIZE(videocc_parent_data_1), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch videocc_iris_ahb_clk = { + .halt_reg = 0x8f4, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x8f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "videocc_iris_ahb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &videocc_iris_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch videocc_mvs0_axi_clk = { + .halt_reg = 0x9ec, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9ec, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "videocc_mvs0_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch videocc_mvs0_core_clk = { + .halt_reg = 0x890, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x890, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "videocc_mvs0_core_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &videocc_iris_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch videocc_mvs1_axi_clk = { + .halt_reg = 0xa0c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa0c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "videocc_mvs1_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch videocc_mvs1_core_clk = { + .halt_reg = 0x8d0, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x8d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "videocc_mvs1_core_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &videocc_iris_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch videocc_mvsc_core_clk = { + .halt_reg = 0x850, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x850, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "videocc_mvsc_core_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &videocc_iris_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch videocc_mvsc_ctl_axi_clk = { + .halt_reg = 0x9cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "videocc_mvsc_ctl_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch videocc_venus_ahb_clk = { + .halt_reg = 0xa6c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa6c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "videocc_venus_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc venus_gdsc = { + .gdscr = 0x814, + .pd = { + .name = "venus_gdsc", + }, + .cxcs = (unsigned int []){ 0x850, 0x9cc }, + .cxc_count = 2, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR, +}; + +static struct gdsc vcodec0_gdsc = { + .gdscr = 0x874, + .pd = { + .name = "vcodec0_gdsc", + }, + .cxcs = (unsigned int []){ 0x890, 0x9ec }, + .cxc_count = 2, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc vcodec1_gdsc = { + .gdscr = 0x8b4, + .pd = { + .name = "vcodec1_gdsc", + }, + .cxcs = (unsigned int []){ 0x8d0, 0xa0c }, + .cxc_count = 2, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct clk_regmap *videocc_sm7150_clocks[] = { + [VIDEOCC_PLL0] = &videocc_pll0.clkr, + [VIDEOCC_IRIS_AHB_CLK] = &videocc_iris_ahb_clk.clkr, + [VIDEOCC_IRIS_CLK_SRC] = &videocc_iris_clk_src.clkr, + [VIDEOCC_MVS0_AXI_CLK] = &videocc_mvs0_axi_clk.clkr, + [VIDEOCC_MVS0_CORE_CLK] = &videocc_mvs0_core_clk.clkr, + [VIDEOCC_MVS1_AXI_CLK] = &videocc_mvs1_axi_clk.clkr, + [VIDEOCC_MVS1_CORE_CLK] = &videocc_mvs1_core_clk.clkr, + [VIDEOCC_MVSC_CORE_CLK] = &videocc_mvsc_core_clk.clkr, + [VIDEOCC_MVSC_CTL_AXI_CLK] = &videocc_mvsc_ctl_axi_clk.clkr, + [VIDEOCC_VENUS_AHB_CLK] = &videocc_venus_ahb_clk.clkr, + [VIDEOCC_XO_CLK_SRC] = &videocc_xo_clk_src.clkr, +}; + +static struct gdsc *videocc_sm7150_gdscs[] = { + [VENUS_GDSC] = &venus_gdsc, + [VCODEC0_GDSC] = &vcodec0_gdsc, + [VCODEC1_GDSC] = &vcodec1_gdsc, +}; + +static const struct regmap_config videocc_sm7150_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xb94, + .fast_io = true, +}; + +static const struct qcom_cc_desc videocc_sm7150_desc = { + .config = &videocc_sm7150_regmap_config, + .clks = videocc_sm7150_clocks, + .num_clks = ARRAY_SIZE(videocc_sm7150_clocks), + .gdscs = videocc_sm7150_gdscs, + .num_gdscs = ARRAY_SIZE(videocc_sm7150_gdscs), +}; + +static const struct of_device_id videocc_sm7150_match_table[] = { + { .compatible = "qcom,sm7150-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, videocc_sm7150_match_table); + +static int videocc_sm7150_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &videocc_sm7150_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + clk_fabia_pll_configure(&videocc_pll0, regmap, &videocc_pll0_config); + + /* Keep some clocks always-on */ + qcom_branch_set_clk_en(regmap, 0x984); /* VIDEOCC_XO_CLK */ + + return qcom_cc_really_probe(&pdev->dev, &videocc_sm7150_desc, regmap); +} + +static struct platform_driver videocc_sm7150_driver = { + .probe = videocc_sm7150_probe, + .driver = { + .name = "videocc-sm7150", + .of_match_table = videocc_sm7150_match_table, + }, +}; +module_platform_driver(videocc_sm7150_driver); + +MODULE_DESCRIPTION("Qualcomm SM7150 Video Clock Controller"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/videocc-sm8150.c b/drivers/clk/qcom/videocc-sm8150.c index a0329260157a..daab3237eec1 100644 --- a/drivers/clk/qcom/videocc-sm8150.c +++ b/drivers/clk/qcom/videocc-sm8150.c @@ -24,7 +24,7 @@ enum { P_VIDEO_PLL0_OUT_MAIN, }; -static struct pll_vco trion_vco[] = { +static const struct pll_vco trion_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -262,7 +262,7 @@ static int video_cc_sm8150_probe(struct platform_device *pdev) /* Keep VIDEO_CC_XO_CLK ALWAYS-ON */ regmap_update_bits(regmap, 0x984, 0x1, 0x1); - ret = qcom_cc_really_probe(pdev, &video_cc_sm8150_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8150_desc, regmap); pm_runtime_put_sync(&pdev->dev); diff --git a/drivers/clk/qcom/videocc-sm8250.c b/drivers/clk/qcom/videocc-sm8250.c index 016b596e03b3..d7e0c32284c1 100644 --- a/drivers/clk/qcom/videocc-sm8250.c +++ b/drivers/clk/qcom/videocc-sm8250.c @@ -26,7 +26,7 @@ enum { P_VIDEO_PLL1_OUT_MAIN, }; -static struct pll_vco lucid_vco[] = { +static const struct pll_vco lucid_vco[] = { { 249600000, 2000000000, 0 }, }; @@ -387,7 +387,7 @@ static int video_cc_sm8250_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0xe58); /* VIDEO_CC_AHB_CLK */ qcom_branch_set_clk_en(regmap, 0xeec); /* VIDEO_CC_XO_CLK */ - ret = qcom_cc_really_probe(pdev, &video_cc_sm8250_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8250_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/videocc-sm8350.c b/drivers/clk/qcom/videocc-sm8350.c index f7aec28d4c87..5bd6fe3e1298 100644 --- a/drivers/clk/qcom/videocc-sm8350.c +++ b/drivers/clk/qcom/videocc-sm8350.c @@ -562,7 +562,7 @@ static int video_cc_sm8350_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0xe58); /* VIDEO_CC_AHB_CLK */ qcom_branch_set_clk_en(regmap, video_cc_xo_clk_cbcr); /* VIDEO_CC_XO_CLK */ - ret = qcom_cc_really_probe(pdev, &video_cc_sm8350_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8350_desc, regmap); pm_runtime_put(&pdev->dev); return ret; diff --git a/drivers/clk/qcom/videocc-sm8450.c b/drivers/clk/qcom/videocc-sm8450.c index 67df40f16423..ed9163d64244 100644 --- a/drivers/clk/qcom/videocc-sm8450.c +++ b/drivers/clk/qcom/videocc-sm8450.c @@ -428,7 +428,7 @@ static int video_cc_sm8450_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0x8130); /* VIDEO_CC_SLEEP_CLK */ qcom_branch_set_clk_en(regmap, 0x8114); /* VIDEO_CC_XO_CLK */ - ret = qcom_cc_really_probe(pdev, &video_cc_sm8450_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8450_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/qcom/videocc-sm8550.c b/drivers/clk/qcom/videocc-sm8550.c index d73f747d2474..97d150b132a6 100644 --- a/drivers/clk/qcom/videocc-sm8550.c +++ b/drivers/clk/qcom/videocc-sm8550.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/clk-provider.h> @@ -10,7 +10,7 @@ #include <linux/pm_runtime.h> #include <linux/regmap.h> -#include <dt-bindings/clock/qcom,sm8450-videocc.h> +#include <dt-bindings/clock/qcom,sm8650-videocc.h> #include "clk-alpha-pll.h" #include "clk-branch.h" @@ -35,7 +35,7 @@ static const struct pll_vco lucid_ole_vco[] = { { 249600000, 2300000000, 0 }, }; -static const struct alpha_pll_config video_cc_pll0_config = { +static struct alpha_pll_config video_cc_pll0_config = { .l = 0x25, .alpha = 0x8000, .config_ctl_val = 0x20485699, @@ -66,7 +66,7 @@ static struct clk_alpha_pll video_cc_pll0 = { }, }; -static const struct alpha_pll_config video_cc_pll1_config = { +static struct alpha_pll_config video_cc_pll1_config = { .l = 0x36, .alpha = 0xb000, .config_ctl_val = 0x20485699, @@ -117,6 +117,14 @@ static const struct clk_parent_data video_cc_parent_data_1[] = { { .hw = &video_cc_pll1.clkr.hw }, }; +static const struct parent_map video_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, +}; + static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), @@ -126,6 +134,16 @@ static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { { } }; +static const struct freq_tbl ftbl_video_cc_mvs0_clk_src_sm8650[] = { + F(588000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(900000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1140000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1305000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1440000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + static struct clk_rcg2 video_cc_mvs0_clk_src = { .cmd_rcgr = 0x8000, .mnd_width = 0, @@ -149,6 +167,15 @@ static const struct freq_tbl ftbl_video_cc_mvs1_clk_src[] = { { } }; +static const struct freq_tbl ftbl_video_cc_mvs1_clk_src_sm8650[] = { + F(840000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), + F(1110000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), + F(1350000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), + F(1500000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), + F(1650000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), + { } +}; + static struct clk_rcg2 video_cc_mvs1_clk_src = { .cmd_rcgr = 0x8018, .mnd_width = 0, @@ -164,6 +191,26 @@ static struct clk_rcg2 video_cc_mvs1_clk_src = { }, }; +static const struct freq_tbl ftbl_video_cc_xo_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_xo_clk_src = { + .cmd_rcgr = 0x810c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_2, + .freq_tbl = ftbl_video_cc_xo_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_xo_clk_src", + .parent_data = video_cc_parent_data_2, + .num_parents = ARRAY_SIZE(video_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + static struct clk_regmap_div video_cc_mvs0_div_clk_src = { .reg = 0x80c4, .shift = 0, @@ -244,6 +291,26 @@ static struct clk_branch video_cc_mvs0_clk = { }, }; +static struct clk_branch video_cc_mvs0_shift_clk = { + .halt_reg = 0x8128, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8128, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8128, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch video_cc_mvs0c_clk = { .halt_reg = 0x8064, .halt_check = BRANCH_HALT, @@ -262,6 +329,26 @@ static struct clk_branch video_cc_mvs0c_clk = { }, }; +static struct clk_branch video_cc_mvs0c_shift_clk = { + .halt_reg = 0x812c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x812c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x812c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch video_cc_mvs1_clk = { .halt_reg = 0x80e0, .halt_check = BRANCH_HALT_SKIP, @@ -282,6 +369,26 @@ static struct clk_branch video_cc_mvs1_clk = { }, }; +static struct clk_branch video_cc_mvs1_shift_clk = { + .halt_reg = 0x8130, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8130, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8130, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch video_cc_mvs1c_clk = { .halt_reg = 0x8090, .halt_check = BRANCH_HALT, @@ -300,6 +407,26 @@ static struct clk_branch video_cc_mvs1c_clk = { }, }; +static struct clk_branch video_cc_mvs1c_shift_clk = { + .halt_reg = 0x8134, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8134, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs1c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct gdsc video_cc_mvs0c_gdsc = { .gdscr = 0x804c, .en_rest_wait_val = 0x2, @@ -363,6 +490,7 @@ static struct clk_regmap *video_cc_sm8550_clocks[] = { [VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr, [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, [VIDEO_CC_PLL1] = &video_cc_pll1.clkr, + [VIDEO_CC_XO_CLK_SRC] = NULL, }; static struct gdsc *video_cc_sm8550_gdscs[] = { @@ -380,6 +508,7 @@ static const struct qcom_reset_map video_cc_sm8550_resets[] = { [CVP_VIDEO_CC_MVS1C_BCR] = { 0x8074 }, [VIDEO_CC_MVS0C_CLK_ARES] = { .reg = 0x8064, .bit = 2, .udelay = 1000 }, [VIDEO_CC_MVS1C_CLK_ARES] = { .reg = 0x8090, .bit = 2, .udelay = 1000 }, + [VIDEO_CC_XO_CLK_ARES] = { .reg = 0x8124, .bit = 2, .udelay = 100 }, }; static const struct regmap_config video_cc_sm8550_regmap_config = { @@ -402,6 +531,7 @@ static struct qcom_cc_desc video_cc_sm8550_desc = { static const struct of_device_id video_cc_sm8550_match_table[] = { { .compatible = "qcom,sm8550-videocc" }, + { .compatible = "qcom,sm8650-videocc" }, { } }; MODULE_DEVICE_TABLE(of, video_cc_sm8550_match_table); @@ -410,6 +540,7 @@ static int video_cc_sm8550_probe(struct platform_device *pdev) { struct regmap *regmap; int ret; + u32 sleep_clk_offset = 0x8140; ret = devm_pm_runtime_enable(&pdev->dev); if (ret) @@ -425,15 +556,30 @@ static int video_cc_sm8550_probe(struct platform_device *pdev) return PTR_ERR(regmap); } + if (of_device_is_compatible(pdev->dev.of_node, "qcom,sm8650-videocc")) { + sleep_clk_offset = 0x8150; + video_cc_pll0_config.l = 0x1e; + video_cc_pll0_config.alpha = 0xa000; + video_cc_pll1_config.l = 0x2b; + video_cc_pll1_config.alpha = 0xc000; + video_cc_mvs0_clk_src.freq_tbl = ftbl_video_cc_mvs0_clk_src_sm8650; + video_cc_mvs1_clk_src.freq_tbl = ftbl_video_cc_mvs1_clk_src_sm8650; + video_cc_sm8550_clocks[VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr; + video_cc_sm8550_clocks[VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr; + video_cc_sm8550_clocks[VIDEO_CC_MVS1_SHIFT_CLK] = &video_cc_mvs1_shift_clk.clkr; + video_cc_sm8550_clocks[VIDEO_CC_MVS1C_SHIFT_CLK] = &video_cc_mvs1c_shift_clk.clkr; + video_cc_sm8550_clocks[VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr; + } + clk_lucid_ole_pll_configure(&video_cc_pll0, regmap, &video_cc_pll0_config); clk_lucid_ole_pll_configure(&video_cc_pll1, regmap, &video_cc_pll1_config); /* Keep some clocks always-on */ qcom_branch_set_clk_en(regmap, 0x80f4); /* VIDEO_CC_AHB_CLK */ - qcom_branch_set_clk_en(regmap, 0x8140); /* VIDEO_CC_SLEEP_CLK */ + qcom_branch_set_clk_en(regmap, sleep_clk_offset); /* VIDEO_CC_SLEEP_CLK */ qcom_branch_set_clk_en(regmap, 0x8124); /* VIDEO_CC_XO_CLK */ - ret = qcom_cc_really_probe(pdev, &video_cc_sm8550_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8550_desc, regmap); pm_runtime_put(&pdev->dev); diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index 6ea7fba9f9e5..398a226ad34e 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -369,9 +369,8 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, if (nrates > 0) { cpuclk->rate_count = nrates; - cpuclk->rate_table = kmemdup(rates, - sizeof(*rates) * nrates, - GFP_KERNEL); + cpuclk->rate_table = kmemdup_array(rates, nrates, sizeof(*rates), + GFP_KERNEL); if (!cpuclk->rate_table) { ret = -ENOMEM; goto unregister_notifier; diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index 2d42eb628926..606ce5458f54 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -1136,10 +1136,10 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, len++; pll->rate_count = len; - pll->rate_table = kmemdup(rate_table, - pll->rate_count * - sizeof(struct rockchip_pll_rate_table), - GFP_KERNEL); + pll->rate_table = kmemdup_array(rate_table, + pll->rate_count, + sizeof(*pll->rate_table), + GFP_KERNEL); WARN(!pll->rate_table, "%s: could not allocate rate table for %s\n", __func__, name); diff --git a/drivers/clk/rockchip/clk-rk3128.c b/drivers/clk/rockchip/clk-rk3128.c index 75071e0cd321..7c3d92af12df 100644 --- a/drivers/clk/rockchip/clk-rk3128.c +++ b/drivers/clk/rockchip/clk-rk3128.c @@ -526,7 +526,7 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), GATE(0, "pclk_ddrupctl", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 7, GFLAGS), GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), - GATE(0, "pclk_mipiphy", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 0, GFLAGS), + GATE(PCLK_MIPIPHY, "pclk_mipiphy", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 0, GFLAGS), GATE(0, "pclk_pmu", "pclk_pmu_pre", 0, RK2928_CLKGATE_CON(9), 2, GFLAGS), GATE(0, "pclk_pmu_niu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 3, GFLAGS), @@ -553,6 +553,7 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { RK2928_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(3), 15, GFLAGS), + GATE(HCLK_SFC, "hclk_sfc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 1, GFLAGS), GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS), GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS), }; @@ -563,23 +564,28 @@ static const char *const rk3128_critical_clocks[] __initconst = { "pclk_cpu", "aclk_peri", "hclk_peri", + "hclk_vio_h2p", "pclk_peri", "pclk_pmu", "sclk_timer5", }; -static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device_node *np) +static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device_node *np, + unsigned long soc_nr_clks) { struct rockchip_clk_provider *ctx; + unsigned long common_nr_clks; void __iomem *reg_base; + common_nr_clks = rockchip_clk_find_max_clk_id(common_clk_branches, + ARRAY_SIZE(common_clk_branches)) + 1; reg_base = of_iomap(np, 0); if (!reg_base) { pr_err("%s: could not map cru region\n", __func__); return ERR_PTR(-ENOMEM); } - ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + ctx = rockchip_clk_init(np, reg_base, max(common_nr_clks, soc_nr_clks)); if (IS_ERR(ctx)) { pr_err("%s: rockchip clk init failed\n", __func__); iounmap(reg_base); @@ -608,8 +614,12 @@ static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device static void __init rk3126_clk_init(struct device_node *np) { struct rockchip_clk_provider *ctx; + unsigned long soc_nr_clks; - ctx = rk3128_common_clk_init(np); + soc_nr_clks = rockchip_clk_find_max_clk_id(rk3126_clk_branches, + ARRAY_SIZE(rk3126_clk_branches)) + 1; + + ctx = rk3128_common_clk_init(np, soc_nr_clks); if (IS_ERR(ctx)) return; @@ -626,8 +636,12 @@ CLK_OF_DECLARE(rk3126_cru, "rockchip,rk3126-cru", rk3126_clk_init); static void __init rk3128_clk_init(struct device_node *np) { struct rockchip_clk_provider *ctx; + unsigned long soc_nr_clks; + + soc_nr_clks = rockchip_clk_find_max_clk_id(rk3128_clk_branches, + ARRAY_SIZE(rk3128_clk_branches)) + 1; - ctx = rk3128_common_clk_init(np); + ctx = rk3128_common_clk_init(np, soc_nr_clks); if (IS_ERR(ctx)) return; diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 9c8af4d1dae0..30e670c8afba 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -757,9 +757,11 @@ static const char *const rk3188_critical_clocks[] __initconst = { "sclk_mac_lbtest", }; -static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np) +static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np, + unsigned long soc_nr_clks) { struct rockchip_clk_provider *ctx; + unsigned long common_nr_clks; void __iomem *reg_base; reg_base = of_iomap(np, 0); @@ -768,7 +770,9 @@ static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device return ERR_PTR(-ENOMEM); } - ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + common_nr_clks = rockchip_clk_find_max_clk_id(common_clk_branches, + ARRAY_SIZE(common_clk_branches)) + 1; + ctx = rockchip_clk_init(np, reg_base, max(common_nr_clks, soc_nr_clks)); if (IS_ERR(ctx)) { pr_err("%s: rockchip clk init failed\n", __func__); iounmap(reg_base); @@ -789,8 +793,11 @@ static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device static void __init rk3066a_clk_init(struct device_node *np) { struct rockchip_clk_provider *ctx; + unsigned long soc_nr_clks; - ctx = rk3188_common_clk_init(np); + soc_nr_clks = rockchip_clk_find_max_clk_id(rk3066a_clk_branches, + ARRAY_SIZE(rk3066a_clk_branches)) + 1; + ctx = rk3188_common_clk_init(np, soc_nr_clks); if (IS_ERR(ctx)) return; @@ -812,11 +819,14 @@ CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init); static void __init rk3188a_clk_init(struct device_node *np) { struct rockchip_clk_provider *ctx; + unsigned long soc_nr_clks; struct clk *clk1, *clk2; unsigned long rate; int ret; - ctx = rk3188_common_clk_init(np); + soc_nr_clks = rockchip_clk_find_max_clk_id(rk3188_clk_branches, + ARRAY_SIZE(rk3188_clk_branches)) + 1; + ctx = rk3188_common_clk_init(np, soc_nr_clks); if (IS_ERR(ctx)) return; diff --git a/drivers/clk/sophgo/Kconfig b/drivers/clk/sophgo/Kconfig index 1cc49be71bdb..8b1367e3a95e 100644 --- a/drivers/clk/sophgo/Kconfig +++ b/drivers/clk/sophgo/Kconfig @@ -9,3 +9,31 @@ config CLK_SOPHGO_CV1800 The driver require a 25MHz Oscillator to function generate clock. It includes PLLs, common clock function and some vendor clock for IPs of CV18XX series SoC + +config CLK_SOPHGO_SG2042_PLL + tristate "Sophgo SG2042 PLL clock support" + depends on ARCH_SOPHGO || COMPILE_TEST + help + This driver supports the PLL clock controller on the + Sophgo SG2042 SoC. This clock IP uses three oscillators with + frequency of 25 MHz as input, which are used for Main/Fixed + PLL, DDR PLL 0 and DDR PLL 1 respectively. + +config CLK_SOPHGO_SG2042_CLKGEN + tristate "Sophgo SG2042 Clock Generator support" + depends on CLK_SOPHGO_SG2042_PLL + help + This driver supports the Clock Generator on the + Sophgo SG2042 SoC. This clock IP depends on SG2042 PLL clock + because it uses PLL clocks as input. + This driver provides clock function such as DIV/Mux/Gate. + +config CLK_SOPHGO_SG2042_RPGATE + tristate "Sophgo SG2042 RP subsystem clock controller support" + depends on CLK_SOPHGO_SG2042_CLKGEN + help + This driver supports the RP((Riscv Processors)) subsystem clock + controller on the Sophgo SG2042 SoC. + This clock IP depends on SG2042 Clock Generator because it uses + clock from Clock Generator IP as input. + This driver provides Gate function for RP. diff --git a/drivers/clk/sophgo/Makefile b/drivers/clk/sophgo/Makefile index a50320764200..53506845a044 100644 --- a/drivers/clk/sophgo/Makefile +++ b/drivers/clk/sophgo/Makefile @@ -5,3 +5,7 @@ clk-sophgo-cv1800-y += clk-cv1800.o clk-sophgo-cv1800-y += clk-cv18xx-common.o clk-sophgo-cv1800-y += clk-cv18xx-ip.o clk-sophgo-cv1800-y += clk-cv18xx-pll.o + +obj-$(CONFIG_CLK_SOPHGO_SG2042_CLKGEN) += clk-sg2042-clkgen.o +obj-$(CONFIG_CLK_SOPHGO_SG2042_PLL) += clk-sg2042-pll.o +obj-$(CONFIG_CLK_SOPHGO_SG2042_RPGATE) += clk-sg2042-rpgate.o diff --git a/drivers/clk/sophgo/clk-cv18xx-ip.c b/drivers/clk/sophgo/clk-cv18xx-ip.c index 805f561725ae..b186e64d4813 100644 --- a/drivers/clk/sophgo/clk-cv18xx-ip.c +++ b/drivers/clk/sophgo/clk-cv18xx-ip.c @@ -613,7 +613,7 @@ static u8 mmux_get_parent_id(struct cv1800_clk_mmux *mmux) return i; } - unreachable(); + BUG(); } static int mmux_enable(struct clk_hw *hw) diff --git a/drivers/clk/sophgo/clk-sg2042-clkgen.c b/drivers/clk/sophgo/clk-sg2042-clkgen.c new file mode 100644 index 000000000000..a334963e83ce --- /dev/null +++ b/drivers/clk/sophgo/clk-sg2042-clkgen.c @@ -0,0 +1,1152 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Sophgo SG2042 Clock Generator Driver + * + * Copyright (C) 2024 Sophgo Technology Inc. + * Copyright (C) 2024 Chen Wang <unicorn_wang@outlook.com> + */ + +#include <linux/array_size.h> +#include <linux/bits.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <asm/div64.h> + +#include <dt-bindings/clock/sophgo,sg2042-clkgen.h> + +#include "clk-sg2042.h" + +/* Registers defined in SYS_CTRL */ +#define R_PLL_BEGIN 0xC0 +#define R_PLL_STAT (0xC0 - R_PLL_BEGIN) +#define R_PLL_CLKEN_CONTROL (0xC4 - R_PLL_BEGIN) +#define R_MPLL_CONTROL (0xE8 - R_PLL_BEGIN) +#define R_FPLL_CONTROL (0xF4 - R_PLL_BEGIN) +#define R_DPLL0_CONTROL (0xF8 - R_PLL_BEGIN) +#define R_DPLL1_CONTROL (0xFC - R_PLL_BEGIN) + +/* Registers defined in CLOCK */ +#define R_CLKENREG0 0x00 +#define R_CLKENREG1 0x04 +#define R_CLKSELREG0 0x20 +#define R_CLKDIVREG0 0x40 +#define R_CLKDIVREG1 0x44 +#define R_CLKDIVREG2 0x48 +#define R_CLKDIVREG3 0x4C +#define R_CLKDIVREG4 0x50 +#define R_CLKDIVREG5 0x54 +#define R_CLKDIVREG6 0x58 +#define R_CLKDIVREG7 0x5C +#define R_CLKDIVREG8 0x60 +#define R_CLKDIVREG9 0x64 +#define R_CLKDIVREG10 0x68 +#define R_CLKDIVREG11 0x6C +#define R_CLKDIVREG12 0x70 +#define R_CLKDIVREG13 0x74 +#define R_CLKDIVREG14 0x78 +#define R_CLKDIVREG15 0x7C +#define R_CLKDIVREG16 0x80 +#define R_CLKDIVREG17 0x84 +#define R_CLKDIVREG18 0x88 +#define R_CLKDIVREG19 0x8C +#define R_CLKDIVREG20 0x90 +#define R_CLKDIVREG21 0x94 +#define R_CLKDIVREG22 0x98 +#define R_CLKDIVREG23 0x9C +#define R_CLKDIVREG24 0xA0 +#define R_CLKDIVREG25 0xA4 +#define R_CLKDIVREG26 0xA8 +#define R_CLKDIVREG27 0xAC +#define R_CLKDIVREG28 0xB0 +#define R_CLKDIVREG29 0xB4 +#define R_CLKDIVREG30 0xB8 + +/* All following shift value are the same for all DIV registers */ +#define SHIFT_DIV_RESET_CTRL 0 +#define SHIFT_DIV_FACTOR_SEL 3 +#define SHIFT_DIV_FACTOR 16 + +/** + * struct sg2042_divider_clock - Divider clock + * @hw: clk_hw for initialization + * @id: used to map clk_onecell_data + * @reg: used for readl/writel. + * **NOTE**: DIV registers are ALL in CLOCK! + * @lock: spinlock to protect register access, modification of + * frequency can only be served one at the time + * @offset_ctrl: offset of divider control registers + * @shift: shift of "Clock Divider Factor" in divider control register + * @width: width of "Clock Divider Factor" in divider control register + * @div_flags: private flags for this clock, not for framework-specific + * @initval: In the divider control register, we can configure whether + * to use the value of "Clock Divider Factor" or just use + * the initial value pre-configured by IC. BIT[3] controls + * this and by default (value is 0), means initial value + * is used. + * **NOTE** that we cannot read the initial value (default + * value when poweron) and default value of "Clock Divider + * Factor" is zero, which I think is a hardware design flaw + * and should be sync-ed with the initial value. So in + * software we have to add a configuration item (initval) + * to manually configure this value and use it when BIT[3] + * is zero. + */ +struct sg2042_divider_clock { + struct clk_hw hw; + + unsigned int id; + + void __iomem *reg; + /* protect register access */ + spinlock_t *lock; + + u32 offset_ctrl; + u8 shift; + u8 width; + u8 div_flags; + u32 initval; +}; + +#define to_sg2042_clk_divider(_hw) \ + container_of(_hw, struct sg2042_divider_clock, hw) + +/** + * struct sg2042_gate_clock - Gate clock + * @hw: clk_hw for initialization + * @id: used to map clk_onecell_data + * @offset_enable: offset of gate enable registers + * @bit_idx: which bit in the register controls gating of this clock + */ +struct sg2042_gate_clock { + struct clk_hw hw; + + unsigned int id; + + u32 offset_enable; + u8 bit_idx; +}; + +/** + * struct sg2042_mux_clock - Mux clock + * @hw: clk_hw for initialization + * @id: used to map clk_onecell_data + * @offset_select: offset of mux selection registers + * **NOTE**: MUX registers are ALL in CLOCK! + * @shift: shift of "Clock Select" in mux selection register + * @width: width of "Clock Select" in mux selection register + * @clk_nb: used for notification + * @original_index: set by notifier callback + */ +struct sg2042_mux_clock { + struct clk_hw hw; + + unsigned int id; + + u32 offset_select; + u8 shift; + u8 width; + + struct notifier_block clk_nb; + u8 original_index; +}; + +#define to_sg2042_mux_nb(_nb) container_of(_nb, struct sg2042_mux_clock, clk_nb) + +static unsigned long sg2042_clk_divider_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sg2042_divider_clock *divider = to_sg2042_clk_divider(hw); + unsigned long ret_rate; + u32 val; + + if (!(readl(divider->reg) & BIT(SHIFT_DIV_FACTOR_SEL))) { + val = divider->initval; + } else { + val = readl(divider->reg) >> divider->shift; + val &= clk_div_mask(divider->width); + } + + ret_rate = divider_recalc_rate(hw, parent_rate, val, NULL, + divider->div_flags, divider->width); + + pr_debug("--> %s: divider_recalc_rate: ret_rate = %ld\n", + clk_hw_get_name(hw), ret_rate); + return ret_rate; +} + +static long sg2042_clk_divider_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *prate) +{ + struct sg2042_divider_clock *divider = to_sg2042_clk_divider(hw); + unsigned long ret_rate; + u32 bestdiv; + + /* if read only, just return current value */ + if (divider->div_flags & CLK_DIVIDER_READ_ONLY) { + if (!(readl(divider->reg) & BIT(SHIFT_DIV_FACTOR_SEL))) { + bestdiv = divider->initval; + } else { + bestdiv = readl(divider->reg) >> divider->shift; + bestdiv &= clk_div_mask(divider->width); + } + ret_rate = DIV_ROUND_UP_ULL((u64)*prate, bestdiv); + } else { + ret_rate = divider_round_rate(hw, rate, prate, NULL, + divider->width, divider->div_flags); + } + + pr_debug("--> %s: divider_round_rate: val = %ld\n", + clk_hw_get_name(hw), ret_rate); + return ret_rate; +} + +static int sg2042_clk_divider_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct sg2042_divider_clock *divider = to_sg2042_clk_divider(hw); + unsigned long flags = 0; + u32 val, val2, value; + + value = divider_get_val(rate, parent_rate, NULL, + divider->width, divider->div_flags); + + if (divider->lock) + spin_lock_irqsave(divider->lock, flags); + else + __acquire(divider->lock); + + /* + * The sequence of clock frequency modification is: + * Assert to reset divider. + * Modify the value of Clock Divide Factor (and High Wide if needed). + * De-assert to restore divided clock with new frequency. + */ + val = readl(divider->reg); + + /* assert */ + val &= ~BIT(SHIFT_DIV_RESET_CTRL); + writel(val, divider->reg); + + if (divider->div_flags & CLK_DIVIDER_HIWORD_MASK) { + val = clk_div_mask(divider->width) << (divider->shift + 16); + } else { + val = readl(divider->reg); + val &= ~(clk_div_mask(divider->width) << divider->shift); + } + val |= value << divider->shift; + val |= BIT(SHIFT_DIV_FACTOR_SEL); + writel(val, divider->reg); + val2 = val; + + /* de-assert */ + val |= BIT(SHIFT_DIV_RESET_CTRL); + writel(val, divider->reg); + + if (divider->lock) + spin_unlock_irqrestore(divider->lock, flags); + else + __release(divider->lock); + + pr_debug("--> %s: divider_set_rate: register val = 0x%x\n", + clk_hw_get_name(hw), val2); + return 0; +} + +static const struct clk_ops sg2042_clk_divider_ops = { + .recalc_rate = sg2042_clk_divider_recalc_rate, + .round_rate = sg2042_clk_divider_round_rate, + .set_rate = sg2042_clk_divider_set_rate, +}; + +static const struct clk_ops sg2042_clk_divider_ro_ops = { + .recalc_rate = sg2042_clk_divider_recalc_rate, + .round_rate = sg2042_clk_divider_round_rate, +}; + +/* + * Clock initialization macro naming rules: + * FW: use CLK_HW_INIT_FW_NAME + * HW: use CLK_HW_INIT_HW + * HWS: use CLK_HW_INIT_HWS + * RO: means Read-Only + */ +#define SG2042_DIV_FW(_id, _name, _parent, \ + _r_ctrl, _shift, _width, \ + _div_flag, _initval) { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_FW_NAME( \ + _name, \ + _parent, \ + &sg2042_clk_divider_ops, \ + 0), \ + .offset_ctrl = _r_ctrl, \ + .shift = _shift, \ + .width = _width, \ + .div_flags = _div_flag, \ + .initval = _initval, \ + } + +#define SG2042_DIV_FW_RO(_id, _name, _parent, \ + _r_ctrl, _shift, _width, \ + _div_flag, _initval) { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_FW_NAME( \ + _name, \ + _parent, \ + &sg2042_clk_divider_ro_ops, \ + 0), \ + .offset_ctrl = _r_ctrl, \ + .shift = _shift, \ + .width = _width, \ + .div_flags = (_div_flag) | CLK_DIVIDER_READ_ONLY, \ + .initval = _initval, \ + } + +#define SG2042_DIV_HW(_id, _name, _parent, \ + _r_ctrl, _shift, _width, \ + _div_flag, _initval) { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_HW( \ + _name, \ + _parent, \ + &sg2042_clk_divider_ops, \ + 0), \ + .offset_ctrl = _r_ctrl, \ + .shift = _shift, \ + .width = _width, \ + .div_flags = _div_flag, \ + .initval = _initval, \ + } + +#define SG2042_DIV_HW_RO(_id, _name, _parent, \ + _r_ctrl, _shift, _width, \ + _div_flag, _initval) { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_HW( \ + _name, \ + _parent, \ + &sg2042_clk_divider_ro_ops, \ + 0), \ + .offset_ctrl = _r_ctrl, \ + .shift = _shift, \ + .width = _width, \ + .div_flags = (_div_flag) | CLK_DIVIDER_READ_ONLY, \ + .initval = _initval, \ + } + +#define SG2042_DIV_HWS(_id, _name, _parent, \ + _r_ctrl, _shift, _width, \ + _div_flag, _initval) { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_HWS( \ + _name, \ + _parent, \ + &sg2042_clk_divider_ops, \ + 0), \ + .offset_ctrl = _r_ctrl, \ + .shift = _shift, \ + .width = _width, \ + .div_flags = _div_flag, \ + .initval = _initval, \ + } + +#define SG2042_DIV_HWS_RO(_id, _name, _parent, \ + _r_ctrl, _shift, _width, \ + _div_flag, _initval) { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_HWS( \ + _name, \ + _parent, \ + &sg2042_clk_divider_ro_ops, \ + 0), \ + .offset_ctrl = _r_ctrl, \ + .shift = _shift, \ + .width = _width, \ + .div_flags = (_div_flag) | CLK_DIVIDER_READ_ONLY, \ + .initval = _initval, \ + } + +#define SG2042_GATE_HWS(_id, _name, _parent, _flags, \ + _r_enable, _bit_idx) { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_HWS( \ + _name, \ + _parent, \ + NULL, \ + _flags), \ + .offset_enable = _r_enable, \ + .bit_idx = _bit_idx, \ + } + +#define SG2042_GATE_HW(_id, _name, _parent, _flags, \ + _r_enable, _bit_idx) { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_HW( \ + _name, \ + _parent, \ + NULL, \ + _flags), \ + .offset_enable = _r_enable, \ + .bit_idx = _bit_idx, \ + } + +#define SG2042_GATE_FW(_id, _name, _parent, _flags, \ + _r_enable, _bit_idx) { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_FW_NAME( \ + _name, \ + _parent, \ + NULL, \ + _flags), \ + .offset_enable = _r_enable, \ + .bit_idx = _bit_idx, \ + } + +#define SG2042_MUX(_id, _name, _parents, _flags, _r_select, _shift, _width) { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_PARENTS_HW( \ + _name, \ + _parents, \ + NULL, \ + _flags), \ + .offset_select = _r_select, \ + .shift = _shift, \ + .width = _width, \ + } + +/* + * Clock items in the array are sorted according to the clock-tree diagram, + * from top to bottom, from upstream to downstream. Read TRM for details. + */ + +/* updated during probe/registration */ +static const struct clk_hw *clk_gate_ddr01_div0[] = { NULL }; +static const struct clk_hw *clk_gate_ddr01_div1[] = { NULL }; +static const struct clk_hw *clk_gate_ddr23_div0[] = { NULL }; +static const struct clk_hw *clk_gate_ddr23_div1[] = { NULL }; +static const struct clk_hw *clk_gate_rp_cpu_normal_div0[] = { NULL }; +static const struct clk_hw *clk_gate_rp_cpu_normal_div1[] = { NULL }; +static const struct clk_hw *clk_gate_axi_ddr_div0[] = { NULL }; +static const struct clk_hw *clk_gate_axi_ddr_div1[] = { NULL }; + +static const struct sg2042_gate_clock sg2042_gate_clks_level_1[] = { + SG2042_GATE_FW(GATE_CLK_DDR01_DIV0, "clk_gate_ddr01_div0", "dpll0", + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + R_CLKDIVREG27, 4), + SG2042_GATE_FW(GATE_CLK_DDR01_DIV1, "clk_gate_ddr01_div1", "fpll", + CLK_IS_CRITICAL, + R_CLKDIVREG28, 4), + + SG2042_GATE_FW(GATE_CLK_DDR23_DIV0, "clk_gate_ddr23_div0", "dpll1", + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + R_CLKDIVREG29, 4), + SG2042_GATE_FW(GATE_CLK_DDR23_DIV1, "clk_gate_ddr23_div1", "fpll", + CLK_IS_CRITICAL, + R_CLKDIVREG30, 4), + + SG2042_GATE_FW(GATE_CLK_RP_CPU_NORMAL_DIV0, + "clk_gate_rp_cpu_normal_div0", "mpll", + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + R_CLKDIVREG0, 4), + SG2042_GATE_FW(GATE_CLK_RP_CPU_NORMAL_DIV1, + "clk_gate_rp_cpu_normal_div1", "fpll", + CLK_IS_CRITICAL, + R_CLKDIVREG1, 4), + + SG2042_GATE_FW(GATE_CLK_AXI_DDR_DIV0, "clk_gate_axi_ddr_div0", "mpll", + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + R_CLKDIVREG25, 4), + SG2042_GATE_FW(GATE_CLK_AXI_DDR_DIV1, "clk_gate_axi_ddr_div1", "fpll", + CLK_IS_CRITICAL, + R_CLKDIVREG26, 4), +}; + +#define DEF_DIVFLAG (CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO) + +static struct sg2042_divider_clock sg2042_div_clks_level_1[] = { + SG2042_DIV_HWS_RO(DIV_CLK_DPLL0_DDR01_0, + "clk_div_ddr01_0", clk_gate_ddr01_div0, + R_CLKDIVREG27, 16, 5, DEF_DIVFLAG, 1), + SG2042_DIV_HWS_RO(DIV_CLK_FPLL_DDR01_1, + "clk_div_ddr01_1", clk_gate_ddr01_div1, + R_CLKDIVREG28, 16, 5, DEF_DIVFLAG, 1), + + SG2042_DIV_HWS_RO(DIV_CLK_DPLL1_DDR23_0, + "clk_div_ddr23_0", clk_gate_ddr23_div0, + R_CLKDIVREG29, 16, 5, DEF_DIVFLAG, 1), + SG2042_DIV_HWS_RO(DIV_CLK_FPLL_DDR23_1, + "clk_div_ddr23_1", clk_gate_ddr23_div1, + R_CLKDIVREG30, 16, 5, DEF_DIVFLAG, 1), + + SG2042_DIV_HWS(DIV_CLK_MPLL_RP_CPU_NORMAL_0, + "clk_div_rp_cpu_normal_0", clk_gate_rp_cpu_normal_div0, + R_CLKDIVREG0, 16, 5, DEF_DIVFLAG, 1), + SG2042_DIV_HWS(DIV_CLK_FPLL_RP_CPU_NORMAL_1, + "clk_div_rp_cpu_normal_1", clk_gate_rp_cpu_normal_div1, + R_CLKDIVREG1, 16, 5, DEF_DIVFLAG, 1), + + SG2042_DIV_HWS(DIV_CLK_MPLL_AXI_DDR_0, + "clk_div_axi_ddr_0", clk_gate_axi_ddr_div0, + R_CLKDIVREG25, 16, 5, DEF_DIVFLAG, 2), + SG2042_DIV_HWS(DIV_CLK_FPLL_AXI_DDR_1, + "clk_div_axi_ddr_1", clk_gate_axi_ddr_div1, + R_CLKDIVREG26, 16, 5, DEF_DIVFLAG, 1), +}; + +/* + * Note: regarding names for mux clock, "0/1" or "div0/div1" means the + * first/second parent input source, not the register value. + * For example: + * "clk_div_ddr01_0" is the name of Clock divider 0 control of DDR01, and + * "clk_gate_ddr01_div0" is the gate clock in front of the "clk_div_ddr01_0", + * they are both controlled by register CLKDIVREG27; + * "clk_div_ddr01_1" is the name of Clock divider 1 control of DDR01, and + * "clk_gate_ddr01_div1" is the gate clock in front of the "clk_div_ddr01_1", + * they are both controlled by register CLKDIVREG28; + * While for register value of mux selection, use Clock Select for DDR01’s clock + * as example, see CLKSELREG0, bit[2]. + * 1: Select in_dpll0_clk as clock source, correspondng to the parent input + * source from "clk_div_ddr01_0". + * 0: Select in_fpll_clk as clock source, corresponding to the parent input + * source from "clk_div_ddr01_1". + * So we need a table to define the array of register values corresponding to + * the parent index and tell CCF about this when registering mux clock. + */ +static const u32 sg2042_mux_table[] = {1, 0}; + +/* Aliases just for easy reading */ +#define clk_div_ddr01_0 (&sg2042_div_clks_level_1[0].hw) +#define clk_div_ddr01_1 (&sg2042_div_clks_level_1[1].hw) +#define clk_div_ddr23_0 (&sg2042_div_clks_level_1[2].hw) +#define clk_div_ddr23_1 (&sg2042_div_clks_level_1[3].hw) +#define clk_div_rp_cpu_normal_0 (&sg2042_div_clks_level_1[4].hw) +#define clk_div_rp_cpu_normal_1 (&sg2042_div_clks_level_1[5].hw) +#define clk_div_axi_ddr_0 (&sg2042_div_clks_level_1[6].hw) +#define clk_div_axi_ddr_1 (&sg2042_div_clks_level_1[7].hw) + +static const struct clk_hw *clk_mux_ddr01_p[] = { + clk_div_ddr01_0, + clk_div_ddr01_1, +}; + +static const struct clk_hw *clk_mux_ddr23_p[] = { + clk_div_ddr23_0, + clk_div_ddr23_1, +}; + +static const struct clk_hw *clk_mux_rp_cpu_normal_p[] = { + clk_div_rp_cpu_normal_0, + clk_div_rp_cpu_normal_1, +}; + +static const struct clk_hw *clk_mux_axi_ddr_p[] = { + clk_div_axi_ddr_0, + clk_div_axi_ddr_1, +}; + +/* Mux clocks to be updated during probe/registration */ +static const struct clk_hw *clk_mux_ddr01[] = { NULL }; +static const struct clk_hw *clk_mux_ddr23[] = { NULL }; +static const struct clk_hw *clk_mux_rp_cpu_normal[] = { NULL }; +static const struct clk_hw *clk_mux_axi_ddr[] = { NULL }; + +static struct sg2042_mux_clock sg2042_mux_clks[] = { + SG2042_MUX(MUX_CLK_DDR01, "clk_mux_ddr01", clk_mux_ddr01_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT | CLK_MUX_READ_ONLY, + R_CLKSELREG0, 2, 1), + SG2042_MUX(MUX_CLK_DDR23, "clk_mux_ddr23", clk_mux_ddr23_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT | CLK_MUX_READ_ONLY, + R_CLKSELREG0, 3, 1), + SG2042_MUX(MUX_CLK_RP_CPU_NORMAL, "clk_mux_rp_cpu_normal", clk_mux_rp_cpu_normal_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + R_CLKSELREG0, 0, 1), + SG2042_MUX(MUX_CLK_AXI_DDR, "clk_mux_axi_ddr", clk_mux_axi_ddr_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + R_CLKSELREG0, 1, 1), +}; + +/* Aliases just for easy reading */ +#define clk_div_top_rp_cmn_div2 (&sg2042_div_clks_level_2[0].hw) +#define clk_div_50m_a53 (&sg2042_div_clks_level_2[1].hw) +#define clk_div_timer1 (&sg2042_div_clks_level_2[2].hw) +#define clk_div_timer2 (&sg2042_div_clks_level_2[3].hw) +#define clk_div_timer3 (&sg2042_div_clks_level_2[4].hw) +#define clk_div_timer4 (&sg2042_div_clks_level_2[5].hw) +#define clk_div_timer5 (&sg2042_div_clks_level_2[6].hw) +#define clk_div_timer6 (&sg2042_div_clks_level_2[7].hw) +#define clk_div_timer7 (&sg2042_div_clks_level_2[8].hw) +#define clk_div_timer8 (&sg2042_div_clks_level_2[9].hw) +#define clk_div_uart_500m (&sg2042_div_clks_level_2[10].hw) +#define clk_div_ahb_lpc (&sg2042_div_clks_level_2[11].hw) +#define clk_div_efuse (&sg2042_div_clks_level_2[12].hw) +#define clk_div_tx_eth0 (&sg2042_div_clks_level_2[13].hw) +#define clk_div_ptp_ref_i_eth0 (&sg2042_div_clks_level_2[14].hw) +#define clk_div_ref_eth0 (&sg2042_div_clks_level_2[15].hw) +#define clk_div_emmc (&sg2042_div_clks_level_2[16].hw) +#define clk_div_sd (&sg2042_div_clks_level_2[17].hw) +#define clk_div_top_axi0 (&sg2042_div_clks_level_2[18].hw) +#define clk_div_100k_emmc (&sg2042_div_clks_level_2[19].hw) +#define clk_div_100k_sd (&sg2042_div_clks_level_2[20].hw) +#define clk_div_gpio_db (&sg2042_div_clks_level_2[21].hw) +#define clk_div_top_axi_hsperi (&sg2042_div_clks_level_2[22].hw) + +static struct sg2042_divider_clock sg2042_div_clks_level_2[] = { + SG2042_DIV_HWS(DIV_CLK_FPLL_TOP_RP_CMN_DIV2, + "clk_div_top_rp_cmn_div2", clk_mux_rp_cpu_normal, + R_CLKDIVREG3, 16, 16, DEF_DIVFLAG, 2), + + SG2042_DIV_FW(DIV_CLK_FPLL_50M_A53, "clk_div_50m_a53", "fpll", + R_CLKDIVREG2, 16, 8, DEF_DIVFLAG, 20), + /* downstream of div_50m_a53 */ + SG2042_DIV_HW(DIV_CLK_FPLL_DIV_TIMER1, "clk_div_timer1", clk_div_50m_a53, + R_CLKDIVREG6, 16, 16, DEF_DIVFLAG, 1), + SG2042_DIV_HW(DIV_CLK_FPLL_DIV_TIMER2, "clk_div_timer2", clk_div_50m_a53, + R_CLKDIVREG7, 16, 16, DEF_DIVFLAG, 1), + SG2042_DIV_HW(DIV_CLK_FPLL_DIV_TIMER3, "clk_div_timer3", clk_div_50m_a53, + R_CLKDIVREG8, 16, 16, DEF_DIVFLAG, 1), + SG2042_DIV_HW(DIV_CLK_FPLL_DIV_TIMER4, "clk_div_timer4", clk_div_50m_a53, + R_CLKDIVREG9, 16, 16, DEF_DIVFLAG, 1), + SG2042_DIV_HW(DIV_CLK_FPLL_DIV_TIMER5, "clk_div_timer5", clk_div_50m_a53, + R_CLKDIVREG10, 16, 16, DEF_DIVFLAG, 1), + SG2042_DIV_HW(DIV_CLK_FPLL_DIV_TIMER6, "clk_div_timer6", clk_div_50m_a53, + R_CLKDIVREG11, 16, 16, DEF_DIVFLAG, 1), + SG2042_DIV_HW(DIV_CLK_FPLL_DIV_TIMER7, "clk_div_timer7", clk_div_50m_a53, + R_CLKDIVREG12, 16, 16, DEF_DIVFLAG, 1), + SG2042_DIV_HW(DIV_CLK_FPLL_DIV_TIMER8, "clk_div_timer8", clk_div_50m_a53, + R_CLKDIVREG13, 16, 16, DEF_DIVFLAG, 1), + + /* + * Set clk_div_uart_500m as RO, because the width of CLKDIVREG4 is too + * narrow for us to produce 115200. Use UART internal divider directly. + */ + SG2042_DIV_FW_RO(DIV_CLK_FPLL_UART_500M, "clk_div_uart_500m", "fpll", + R_CLKDIVREG4, 16, 7, DEF_DIVFLAG, 2), + SG2042_DIV_FW(DIV_CLK_FPLL_AHB_LPC, "clk_div_ahb_lpc", "fpll", + R_CLKDIVREG5, 16, 16, DEF_DIVFLAG, 5), + SG2042_DIV_FW(DIV_CLK_FPLL_EFUSE, "clk_div_efuse", "fpll", + R_CLKDIVREG14, 16, 7, DEF_DIVFLAG, 40), + SG2042_DIV_FW(DIV_CLK_FPLL_TX_ETH0, "clk_div_tx_eth0", "fpll", + R_CLKDIVREG16, 16, 11, DEF_DIVFLAG, 8), + SG2042_DIV_FW(DIV_CLK_FPLL_PTP_REF_I_ETH0, + "clk_div_ptp_ref_i_eth0", "fpll", + R_CLKDIVREG17, 16, 8, DEF_DIVFLAG, 20), + SG2042_DIV_FW(DIV_CLK_FPLL_REF_ETH0, "clk_div_ref_eth0", "fpll", + R_CLKDIVREG18, 16, 8, DEF_DIVFLAG, 40), + SG2042_DIV_FW(DIV_CLK_FPLL_EMMC, "clk_div_emmc", "fpll", + R_CLKDIVREG19, 16, 5, DEF_DIVFLAG, 10), + SG2042_DIV_FW(DIV_CLK_FPLL_SD, "clk_div_sd", "fpll", + R_CLKDIVREG21, 16, 5, DEF_DIVFLAG, 10), + + SG2042_DIV_FW(DIV_CLK_FPLL_TOP_AXI0, "clk_div_top_axi0", "fpll", + R_CLKDIVREG23, 16, 5, DEF_DIVFLAG, 10), + /* downstream of div_top_axi0 */ + SG2042_DIV_HW(DIV_CLK_FPLL_100K_EMMC, "clk_div_100k_emmc", clk_div_top_axi0, + R_CLKDIVREG20, 16, 16, DEF_DIVFLAG, 1000), + SG2042_DIV_HW(DIV_CLK_FPLL_100K_SD, "clk_div_100k_sd", clk_div_top_axi0, + R_CLKDIVREG22, 16, 16, DEF_DIVFLAG, 1000), + SG2042_DIV_HW(DIV_CLK_FPLL_GPIO_DB, "clk_div_gpio_db", clk_div_top_axi0, + R_CLKDIVREG15, 16, 16, DEF_DIVFLAG, 1000), + + SG2042_DIV_FW(DIV_CLK_FPLL_TOP_AXI_HSPERI, + "clk_div_top_axi_hsperi", "fpll", + R_CLKDIVREG24, 16, 5, DEF_DIVFLAG, 4), +}; + +/* Gate clocks to be updated during probe/registration */ +static const struct clk_hw *clk_gate_rp_cpu_normal[] = { NULL }; +static const struct clk_hw *clk_gate_top_rp_cmn_div2[] = { NULL }; + +static const struct sg2042_gate_clock sg2042_gate_clks_level_2[] = { + SG2042_GATE_HWS(GATE_CLK_DDR01, "clk_gate_ddr01", clk_mux_ddr01, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + R_CLKENREG1, 14), + + SG2042_GATE_HWS(GATE_CLK_DDR23, "clk_gate_ddr23", clk_mux_ddr23, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + R_CLKENREG1, 15), + + SG2042_GATE_HWS(GATE_CLK_RP_CPU_NORMAL, + "clk_gate_rp_cpu_normal", clk_mux_rp_cpu_normal, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + R_CLKENREG0, 0), + + SG2042_GATE_HWS(GATE_CLK_AXI_DDR, "clk_gate_axi_ddr", clk_mux_axi_ddr, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + R_CLKENREG1, 13), + + /* upon are gate clocks directly downstream of muxes */ + + /* downstream of clk_div_top_rp_cmn_div2 */ + SG2042_GATE_HW(GATE_CLK_TOP_RP_CMN_DIV2, + "clk_gate_top_rp_cmn_div2", clk_div_top_rp_cmn_div2, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, R_CLKENREG0, 2), + SG2042_GATE_HWS(GATE_CLK_HSDMA, "clk_gate_hsdma", clk_gate_top_rp_cmn_div2, + CLK_SET_RATE_PARENT, R_CLKENREG1, 10), + + /* + * downstream of clk_gate_rp_cpu_normal + * + * FIXME: there should be one 1/2 DIV between clk_gate_rp_cpu_normal + * and clk_gate_axi_pcie0/clk_gate_axi_pcie1. + * But the 1/2 DIV is fixed and no configurable register exported, so + * when reading from these two clocks, the rate value are still the + * same as that of clk_gate_rp_cpu_normal, it's not correct. + * This just affects the value read. + */ + SG2042_GATE_HWS(GATE_CLK_AXI_PCIE0, + "clk_gate_axi_pcie0", clk_gate_rp_cpu_normal, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, R_CLKENREG1, 8), + SG2042_GATE_HWS(GATE_CLK_AXI_PCIE1, + "clk_gate_axi_pcie1", clk_gate_rp_cpu_normal, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, R_CLKENREG1, 9), + + /* downstream of div_50m_a53 */ + SG2042_GATE_HW(GATE_CLK_A53_50M, "clk_gate_a53_50m", clk_div_50m_a53, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, R_CLKENREG0, 1), + SG2042_GATE_HW(GATE_CLK_TIMER1, "clk_gate_timer1", clk_div_timer1, + CLK_SET_RATE_PARENT, R_CLKENREG0, 12), + SG2042_GATE_HW(GATE_CLK_TIMER2, "clk_gate_timer2", clk_div_timer2, + CLK_SET_RATE_PARENT, R_CLKENREG0, 13), + SG2042_GATE_HW(GATE_CLK_TIMER3, "clk_gate_timer3", clk_div_timer3, + CLK_SET_RATE_PARENT, R_CLKENREG0, 14), + SG2042_GATE_HW(GATE_CLK_TIMER4, "clk_gate_timer4", clk_div_timer4, + CLK_SET_RATE_PARENT, R_CLKENREG0, 15), + SG2042_GATE_HW(GATE_CLK_TIMER5, "clk_gate_timer5", clk_div_timer5, + CLK_SET_RATE_PARENT, R_CLKENREG0, 16), + SG2042_GATE_HW(GATE_CLK_TIMER6, "clk_gate_timer6", clk_div_timer6, + CLK_SET_RATE_PARENT, R_CLKENREG0, 17), + SG2042_GATE_HW(GATE_CLK_TIMER7, "clk_gate_timer7", clk_div_timer7, + CLK_SET_RATE_PARENT, R_CLKENREG0, 18), + SG2042_GATE_HW(GATE_CLK_TIMER8, "clk_gate_timer8", clk_div_timer8, + CLK_SET_RATE_PARENT, R_CLKENREG0, 19), + + /* gate clocks downstream from div clocks one-to-one */ + SG2042_GATE_HW(GATE_CLK_UART_500M, "clk_gate_uart_500m", clk_div_uart_500m, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, R_CLKENREG0, 4), + SG2042_GATE_HW(GATE_CLK_AHB_LPC, "clk_gate_ahb_lpc", clk_div_ahb_lpc, + CLK_SET_RATE_PARENT, R_CLKENREG0, 7), + SG2042_GATE_HW(GATE_CLK_EFUSE, "clk_gate_efuse", clk_div_efuse, + CLK_SET_RATE_PARENT, R_CLKENREG0, 20), + SG2042_GATE_HW(GATE_CLK_TX_ETH0, "clk_gate_tx_eth0", clk_div_tx_eth0, + CLK_SET_RATE_PARENT, R_CLKENREG0, 30), + SG2042_GATE_HW(GATE_CLK_PTP_REF_I_ETH0, + "clk_gate_ptp_ref_i_eth0", clk_div_ptp_ref_i_eth0, + CLK_SET_RATE_PARENT, R_CLKENREG1, 0), + SG2042_GATE_HW(GATE_CLK_REF_ETH0, "clk_gate_ref_eth0", clk_div_ref_eth0, + CLK_SET_RATE_PARENT, R_CLKENREG1, 1), + SG2042_GATE_HW(GATE_CLK_EMMC_100M, "clk_gate_emmc", clk_div_emmc, + CLK_SET_RATE_PARENT, R_CLKENREG1, 3), + SG2042_GATE_HW(GATE_CLK_SD_100M, "clk_gate_sd", clk_div_sd, + CLK_SET_RATE_PARENT, R_CLKENREG1, 6), + + /* downstream of clk_div_top_axi0 */ + SG2042_GATE_HW(GATE_CLK_AHB_ROM, "clk_gate_ahb_rom", clk_div_top_axi0, + 0, R_CLKENREG0, 8), + SG2042_GATE_HW(GATE_CLK_AHB_SF, "clk_gate_ahb_sf", clk_div_top_axi0, + 0, R_CLKENREG0, 9), + SG2042_GATE_HW(GATE_CLK_AXI_SRAM, "clk_gate_axi_sram", clk_div_top_axi0, + CLK_IGNORE_UNUSED, R_CLKENREG0, 10), + SG2042_GATE_HW(GATE_CLK_APB_TIMER, "clk_gate_apb_timer", clk_div_top_axi0, + CLK_IGNORE_UNUSED, R_CLKENREG0, 11), + SG2042_GATE_HW(GATE_CLK_APB_EFUSE, "clk_gate_apb_efuse", clk_div_top_axi0, + 0, R_CLKENREG0, 21), + SG2042_GATE_HW(GATE_CLK_APB_GPIO, "clk_gate_apb_gpio", clk_div_top_axi0, + 0, R_CLKENREG0, 22), + SG2042_GATE_HW(GATE_CLK_APB_GPIO_INTR, + "clk_gate_apb_gpio_intr", clk_div_top_axi0, + CLK_IS_CRITICAL, R_CLKENREG0, 23), + SG2042_GATE_HW(GATE_CLK_APB_I2C, "clk_gate_apb_i2c", clk_div_top_axi0, + 0, R_CLKENREG0, 26), + SG2042_GATE_HW(GATE_CLK_APB_WDT, "clk_gate_apb_wdt", clk_div_top_axi0, + 0, R_CLKENREG0, 27), + SG2042_GATE_HW(GATE_CLK_APB_PWM, "clk_gate_apb_pwm", clk_div_top_axi0, + 0, R_CLKENREG0, 28), + SG2042_GATE_HW(GATE_CLK_APB_RTC, "clk_gate_apb_rtc", clk_div_top_axi0, + 0, R_CLKENREG0, 29), + SG2042_GATE_HW(GATE_CLK_TOP_AXI0, "clk_gate_top_axi0", clk_div_top_axi0, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + R_CLKENREG1, 11), + /* downstream of DIV clocks which are sourced from clk_div_top_axi0 */ + SG2042_GATE_HW(GATE_CLK_GPIO_DB, "clk_gate_gpio_db", clk_div_gpio_db, + CLK_SET_RATE_PARENT, R_CLKENREG0, 24), + SG2042_GATE_HW(GATE_CLK_100K_EMMC, "clk_gate_100k_emmc", clk_div_100k_emmc, + CLK_SET_RATE_PARENT, R_CLKENREG1, 4), + SG2042_GATE_HW(GATE_CLK_100K_SD, "clk_gate_100k_sd", clk_div_100k_sd, + CLK_SET_RATE_PARENT, R_CLKENREG1, 7), + + /* downstream of clk_div_top_axi_hsperi */ + SG2042_GATE_HW(GATE_CLK_SYSDMA_AXI, + "clk_gate_sysdma_axi", clk_div_top_axi_hsperi, + CLK_SET_RATE_PARENT, R_CLKENREG0, 3), + SG2042_GATE_HW(GATE_CLK_APB_UART, + "clk_gate_apb_uart", clk_div_top_axi_hsperi, + CLK_SET_RATE_PARENT, R_CLKENREG0, 5), + SG2042_GATE_HW(GATE_CLK_AXI_DBG_I2C, + "clk_gate_axi_dbg_i2c", clk_div_top_axi_hsperi, + CLK_SET_RATE_PARENT, R_CLKENREG0, 6), + SG2042_GATE_HW(GATE_CLK_APB_SPI, + "clk_gate_apb_spi", clk_div_top_axi_hsperi, + CLK_SET_RATE_PARENT, R_CLKENREG0, 25), + SG2042_GATE_HW(GATE_CLK_AXI_ETH0, + "clk_gate_axi_eth0", clk_div_top_axi_hsperi, + CLK_SET_RATE_PARENT, R_CLKENREG0, 31), + SG2042_GATE_HW(GATE_CLK_AXI_EMMC, + "clk_gate_axi_emmc", clk_div_top_axi_hsperi, + CLK_SET_RATE_PARENT, R_CLKENREG1, 2), + SG2042_GATE_HW(GATE_CLK_AXI_SD, + "clk_gate_axi_sd", clk_div_top_axi_hsperi, + CLK_SET_RATE_PARENT, R_CLKENREG1, 5), + SG2042_GATE_HW(GATE_CLK_TOP_AXI_HSPERI, + "clk_gate_top_axi_hsperi", clk_div_top_axi_hsperi, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + R_CLKENREG1, 12), +}; + +static DEFINE_SPINLOCK(sg2042_clk_lock); + +static int sg2042_clk_register_divs(struct device *dev, + struct sg2042_clk_data *clk_data, + struct sg2042_divider_clock div_clks[], + int num_div_clks) +{ + struct sg2042_divider_clock *div; + struct clk_hw *hw; + int i, ret = 0; + + for (i = 0; i < num_div_clks; i++) { + div = &div_clks[i]; + + if (div->div_flags & CLK_DIVIDER_HIWORD_MASK) { + if (div->width + div->shift > 16) { + pr_warn("divider value exceeds LOWORD field\n"); + ret = -EINVAL; + break; + } + } + + div->reg = clk_data->iobase + div->offset_ctrl; + div->lock = &sg2042_clk_lock; + + hw = &div->hw; + ret = devm_clk_hw_register(dev, hw); + if (ret) { + pr_err("failed to register clock %s\n", div->hw.init->name); + break; + } + + clk_data->onecell_data.hws[div->id] = hw; + } + + return ret; +} + +static int sg2042_clk_register_gates(struct device *dev, + struct sg2042_clk_data *clk_data, + const struct sg2042_gate_clock gate_clks[], + int num_gate_clks) +{ + const struct sg2042_gate_clock *gate; + struct clk_hw *hw; + int i, ret = 0; + + for (i = 0; i < num_gate_clks; i++) { + gate = &gate_clks[i]; + hw = __devm_clk_hw_register_gate + (dev, + NULL, + gate->hw.init->name, + NULL, + gate->hw.init->parent_hws[0], + NULL, + gate->hw.init->flags, + clk_data->iobase + gate->offset_enable, + gate->bit_idx, + 0, + &sg2042_clk_lock); + if (IS_ERR(hw)) { + pr_err("failed to register clock %s\n", gate->hw.init->name); + ret = PTR_ERR(hw); + break; + } + + clk_data->onecell_data.hws[gate->id] = hw; + + /* Updated some clocks which take the role of parent */ + switch (gate->id) { + case GATE_CLK_RP_CPU_NORMAL: + *clk_gate_rp_cpu_normal = hw; + break; + case GATE_CLK_TOP_RP_CMN_DIV2: + *clk_gate_top_rp_cmn_div2 = hw; + break; + } + } + + return ret; +} + +static int sg2042_clk_register_gates_fw(struct device *dev, + struct sg2042_clk_data *clk_data, + const struct sg2042_gate_clock gate_clks[], + int num_gate_clks) +{ + const struct sg2042_gate_clock *gate; + struct clk_hw *hw; + int i, ret = 0; + + for (i = 0; i < num_gate_clks; i++) { + gate = &gate_clks[i]; + hw = devm_clk_hw_register_gate_parent_data + (dev, + gate->hw.init->name, + gate->hw.init->parent_data, + gate->hw.init->flags, + clk_data->iobase + gate->offset_enable, + gate->bit_idx, + 0, + &sg2042_clk_lock); + if (IS_ERR(hw)) { + pr_err("failed to register clock %s\n", gate->hw.init->name); + ret = PTR_ERR(hw); + break; + } + + clk_data->onecell_data.hws[gate->id] = hw; + + /* Updated some clocks which take the role of parent */ + switch (gate->id) { + case GATE_CLK_DDR01_DIV0: + *clk_gate_ddr01_div0 = hw; + break; + case GATE_CLK_DDR01_DIV1: + *clk_gate_ddr01_div1 = hw; + break; + case GATE_CLK_DDR23_DIV0: + *clk_gate_ddr23_div0 = hw; + break; + case GATE_CLK_DDR23_DIV1: + *clk_gate_ddr23_div1 = hw; + break; + case GATE_CLK_RP_CPU_NORMAL_DIV0: + *clk_gate_rp_cpu_normal_div0 = hw; + break; + case GATE_CLK_RP_CPU_NORMAL_DIV1: + *clk_gate_rp_cpu_normal_div1 = hw; + break; + case GATE_CLK_AXI_DDR_DIV0: + *clk_gate_axi_ddr_div0 = hw; + break; + case GATE_CLK_AXI_DDR_DIV1: + *clk_gate_axi_ddr_div1 = hw; + break; + } + } + + return ret; +} + +static int sg2042_mux_notifier_cb(struct notifier_block *nb, + unsigned long event, + void *data) +{ + struct sg2042_mux_clock *mux = to_sg2042_mux_nb(nb); + const struct clk_ops *ops = &clk_mux_ops; + struct clk_notifier_data *ndata = data; + struct clk_hw *hw; + int ret = 0; + + hw = __clk_get_hw(ndata->clk); + + /* To switch to fpll before changing rate and restore after that */ + if (event == PRE_RATE_CHANGE) { + mux->original_index = ops->get_parent(hw); + + /* + * "1" is the array index of the second parent input source of + * mux. For SG2042, it's fpll for all mux clocks. + * "0" is the array index of the frist parent input source of + * mux, For SG2042, it's mpll. + * FIXME, any good idea to avoid magic number? + */ + if (mux->original_index == 0) + ret = ops->set_parent(hw, 1); + } else if (event == POST_RATE_CHANGE) { + ret = ops->set_parent(hw, mux->original_index); + } + + return notifier_from_errno(ret); +} + +static int sg2042_clk_register_muxs(struct device *dev, + struct sg2042_clk_data *clk_data, + struct sg2042_mux_clock mux_clks[], + int num_mux_clks) +{ + struct sg2042_mux_clock *mux; + struct clk_hw *hw; + int i, ret = 0; + + for (i = 0; i < num_mux_clks; i++) { + mux = &mux_clks[i]; + + hw = __devm_clk_hw_register_mux + (dev, + NULL, + mux->hw.init->name, + mux->hw.init->num_parents, + NULL, + mux->hw.init->parent_hws, + NULL, + mux->hw.init->flags, + clk_data->iobase + mux->offset_select, + mux->shift, + BIT(mux->width) - 1, + 0, + sg2042_mux_table, + &sg2042_clk_lock); + if (IS_ERR(hw)) { + pr_err("failed to register clock %s\n", mux->hw.init->name); + ret = PTR_ERR(hw); + break; + } + + clk_data->onecell_data.hws[mux->id] = hw; + + /* Updated some clocks which takes the role of parent */ + switch (mux->id) { + case MUX_CLK_DDR01: + *clk_mux_ddr01 = hw; + break; + case MUX_CLK_DDR23: + *clk_mux_ddr23 = hw; + break; + case MUX_CLK_RP_CPU_NORMAL: + *clk_mux_rp_cpu_normal = hw; + break; + case MUX_CLK_AXI_DDR: + *clk_mux_axi_ddr = hw; + break; + } + + /* + * FIXME: Theoretically, we should set parent for the + * mux, but seems hardware has done this for us with + * default value, so we don't set parent again here. + */ + + if (!(mux->hw.init->flags & CLK_MUX_READ_ONLY)) { + mux->clk_nb.notifier_call = sg2042_mux_notifier_cb; + ret = devm_clk_notifier_register(dev, hw->clk, &mux->clk_nb); + if (ret) { + pr_err("failed to register clock notifier for %s\n", + mux->hw.init->name); + break; + } + } + } + + return ret; +} + +static int sg2042_init_clkdata(struct platform_device *pdev, + int num_clks, + struct sg2042_clk_data **pp_clk_data) +{ + struct sg2042_clk_data *clk_data = NULL; + + clk_data = devm_kzalloc(&pdev->dev, + struct_size(clk_data, onecell_data.hws, num_clks), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->iobase = devm_platform_ioremap_resource(pdev, 0); + if (WARN_ON(IS_ERR(clk_data->iobase))) + return PTR_ERR(clk_data->iobase); + + clk_data->onecell_data.num = num_clks; + + *pp_clk_data = clk_data; + + return 0; +} + +static int sg2042_clkgen_probe(struct platform_device *pdev) +{ + struct sg2042_clk_data *clk_data = NULL; + int num_clks; + int ret; + + num_clks = ARRAY_SIZE(sg2042_div_clks_level_1) + + ARRAY_SIZE(sg2042_div_clks_level_2) + + ARRAY_SIZE(sg2042_gate_clks_level_1) + + ARRAY_SIZE(sg2042_gate_clks_level_2) + + ARRAY_SIZE(sg2042_mux_clks); + + ret = sg2042_init_clkdata(pdev, num_clks, &clk_data); + if (ret) + goto error_out; + + /* level-1 gates */ + ret = sg2042_clk_register_gates_fw(&pdev->dev, clk_data, + sg2042_gate_clks_level_1, + ARRAY_SIZE(sg2042_gate_clks_level_1)); + if (ret) + goto error_out; + + /* level-1 div */ + ret = sg2042_clk_register_divs(&pdev->dev, clk_data, sg2042_div_clks_level_1, + ARRAY_SIZE(sg2042_div_clks_level_1)); + if (ret) + goto error_out; + + /* mux */ + ret = sg2042_clk_register_muxs(&pdev->dev, clk_data, sg2042_mux_clks, + ARRAY_SIZE(sg2042_mux_clks)); + if (ret) + goto error_out; + + /* level 2 div */ + ret = sg2042_clk_register_divs(&pdev->dev, clk_data, sg2042_div_clks_level_2, + ARRAY_SIZE(sg2042_div_clks_level_2)); + if (ret) + goto error_out; + + /* level 2 gate */ + ret = sg2042_clk_register_gates(&pdev->dev, clk_data, sg2042_gate_clks_level_2, + ARRAY_SIZE(sg2042_gate_clks_level_2)); + if (ret) + goto error_out; + + return devm_of_clk_add_hw_provider(&pdev->dev, + of_clk_hw_onecell_get, + &clk_data->onecell_data); + +error_out: + pr_err("%s failed error number %d\n", __func__, ret); + return ret; +} + +static const struct of_device_id sg2042_clkgen_match[] = { + { .compatible = "sophgo,sg2042-clkgen" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, sg2042_clkgen_match); + +static struct platform_driver sg2042_clkgen_driver = { + .probe = sg2042_clkgen_probe, + .driver = { + .name = "clk-sophgo-sg2042-clkgen", + .of_match_table = sg2042_clkgen_match, + .suppress_bind_attrs = true, + }, +}; +module_platform_driver(sg2042_clkgen_driver); + +MODULE_AUTHOR("Chen Wang"); +MODULE_DESCRIPTION("Sophgo SG2042 clock generator driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sophgo/clk-sg2042-pll.c b/drivers/clk/sophgo/clk-sg2042-pll.c new file mode 100644 index 000000000000..9695e64fc23b --- /dev/null +++ b/drivers/clk/sophgo/clk-sg2042-pll.c @@ -0,0 +1,567 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Sophgo SG2042 PLL clock Driver + * + * Copyright (C) 2024 Sophgo Technology Inc. + * Copyright (C) 2024 Chen Wang <unicorn_wang@outlook.com> + */ + +#include <linux/array_size.h> +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/clk-provider.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/platform_device.h> +#include <asm/div64.h> + +#include <dt-bindings/clock/sophgo,sg2042-pll.h> + +#include "clk-sg2042.h" + +/* Registers defined in SYS_CTRL */ +#define R_PLL_BEGIN 0xC0 +#define R_PLL_STAT (0xC0 - R_PLL_BEGIN) +#define R_PLL_CLKEN_CONTROL (0xC4 - R_PLL_BEGIN) +#define R_MPLL_CONTROL (0xE8 - R_PLL_BEGIN) +#define R_FPLL_CONTROL (0xF4 - R_PLL_BEGIN) +#define R_DPLL0_CONTROL (0xF8 - R_PLL_BEGIN) +#define R_DPLL1_CONTROL (0xFC - R_PLL_BEGIN) + +/** + * struct sg2042_pll_clock - PLL clock + * @hw: clk_hw for initialization + * @id: used to map clk_onecell_data + * @base: used for readl/writel. + * **NOTE**: PLL registers are all in SYS_CTRL! + * @lock: spinlock to protect register access, modification + * of frequency can only be served one at the time. + * @offset_ctrl: offset of pll control registers + * @shift_status_lock: shift of XXX_LOCK in pll status register + * @shift_status_updating: shift of UPDATING_XXX in pll status register + * @shift_enable: shift of XXX_CLK_EN in pll enable register + */ +struct sg2042_pll_clock { + struct clk_hw hw; + + unsigned int id; + void __iomem *base; + /* protect register access */ + spinlock_t *lock; + + u32 offset_ctrl; + u8 shift_status_lock; + u8 shift_status_updating; + u8 shift_enable; +}; + +#define to_sg2042_pll_clk(_hw) container_of(_hw, struct sg2042_pll_clock, hw) + +#define KHZ 1000UL +#define MHZ (KHZ * KHZ) + +#define REFDIV_MIN 1 +#define REFDIV_MAX 63 +#define FBDIV_MIN 16 +#define FBDIV_MAX 320 + +#define PLL_FREF_SG2042 (25 * MHZ) + +#define PLL_FOUTPOSTDIV_MIN (16 * MHZ) +#define PLL_FOUTPOSTDIV_MAX (3200 * MHZ) + +#define PLL_FOUTVCO_MIN (800 * MHZ) +#define PLL_FOUTVCO_MAX (3200 * MHZ) + +struct sg2042_pll_ctrl { + unsigned long freq; + unsigned int fbdiv; + unsigned int postdiv1; + unsigned int postdiv2; + unsigned int refdiv; +}; + +#define PLLCTRL_FBDIV_MASK GENMASK(27, 16) +#define PLLCTRL_POSTDIV2_MASK GENMASK(14, 12) +#define PLLCTRL_POSTDIV1_MASK GENMASK(10, 8) +#define PLLCTRL_REFDIV_MASK GENMASK(5, 0) + +static inline u32 sg2042_pll_ctrl_encode(struct sg2042_pll_ctrl *ctrl) +{ + return FIELD_PREP(PLLCTRL_FBDIV_MASK, ctrl->fbdiv) | + FIELD_PREP(PLLCTRL_POSTDIV2_MASK, ctrl->postdiv2) | + FIELD_PREP(PLLCTRL_POSTDIV1_MASK, ctrl->postdiv1) | + FIELD_PREP(PLLCTRL_REFDIV_MASK, ctrl->refdiv); +} + +static inline void sg2042_pll_ctrl_decode(unsigned int reg_value, + struct sg2042_pll_ctrl *ctrl) +{ + ctrl->fbdiv = FIELD_GET(PLLCTRL_FBDIV_MASK, reg_value); + ctrl->refdiv = FIELD_GET(PLLCTRL_REFDIV_MASK, reg_value); + ctrl->postdiv1 = FIELD_GET(PLLCTRL_POSTDIV1_MASK, reg_value); + ctrl->postdiv2 = FIELD_GET(PLLCTRL_POSTDIV2_MASK, reg_value); +} + +static inline void sg2042_pll_enable(struct sg2042_pll_clock *pll, bool en) +{ + u32 value; + + if (en) { + /* wait pll lock */ + if (readl_poll_timeout_atomic(pll->base + R_PLL_STAT, + value, + ((value >> pll->shift_status_lock) & 0x1), + 0, + 100000)) + pr_warn("%s not locked\n", pll->hw.init->name); + + /* wait pll updating */ + if (readl_poll_timeout_atomic(pll->base + R_PLL_STAT, + value, + !((value >> pll->shift_status_updating) & 0x1), + 0, + 100000)) + pr_warn("%s still updating\n", pll->hw.init->name); + + /* enable pll */ + value = readl(pll->base + R_PLL_CLKEN_CONTROL); + writel(value | (1 << pll->shift_enable), pll->base + R_PLL_CLKEN_CONTROL); + } else { + /* disable pll */ + value = readl(pll->base + R_PLL_CLKEN_CONTROL); + writel(value & (~(1 << pll->shift_enable)), pll->base + R_PLL_CLKEN_CONTROL); + } +} + +/** + * sg2042_pll_recalc_rate() - Calculate rate for plls + * @reg_value: current register value + * @parent_rate: parent frequency + * + * This function is used to calculate below "rate" in equation + * rate = (parent_rate/REFDIV) x FBDIV/POSTDIV1/POSTDIV2 + * = (parent_rate x FBDIV) / (REFDIV x POSTDIV1 x POSTDIV2) + * + * Return: The rate calculated. + */ +static unsigned long sg2042_pll_recalc_rate(unsigned int reg_value, + unsigned long parent_rate) +{ + struct sg2042_pll_ctrl ctrl_table; + u64 numerator, denominator; + + sg2042_pll_ctrl_decode(reg_value, &ctrl_table); + + numerator = parent_rate * ctrl_table.fbdiv; + denominator = ctrl_table.refdiv * ctrl_table.postdiv1 * ctrl_table.postdiv2; + do_div(numerator, denominator); + return numerator; +} + +/** + * sg2042_pll_get_postdiv_1_2() - Based on input rate/prate/fbdiv/refdiv, + * look up the postdiv1_2 table to get the closest postdiiv combination. + * @rate: FOUTPOSTDIV + * @prate: parent rate, i.e. FREF + * @fbdiv: FBDIV + * @refdiv: REFDIV + * @postdiv1: POSTDIV1, output + * @postdiv2: POSTDIV2, output + * + * postdiv1_2 contains all the possible combination lists of POSTDIV1 and POSTDIV2 + * for example: + * postdiv1_2[0] = {2, 4, 8}, where div1 = 2, div2 = 4 , div1 * div2 = 8 + * + * See TRM: + * FOUTPOSTDIV = FREF * FBDIV / REFDIV / (POSTDIV1 * POSTDIV2) + * So we get following formula to get POSTDIV1 and POSTDIV2: + * POSTDIV = (prate/REFDIV) x FBDIV/rate + * above POSTDIV = POSTDIV1*POSTDIV2 + * + * Return: + * %0 - OK + * %-EINVAL - invalid argument, which means Failed to get the postdivs. + */ +static int sg2042_pll_get_postdiv_1_2(unsigned long rate, + unsigned long prate, + unsigned int fbdiv, + unsigned int refdiv, + unsigned int *postdiv1, + unsigned int *postdiv2) +{ + int index; + u64 tmp0; + + /* POSTDIV_RESULT_INDEX point to 3rd element in the array postdiv1_2 */ + #define POSTDIV_RESULT_INDEX 2 + + static const int postdiv1_2[][3] = { + {2, 4, 8}, {3, 3, 9}, {2, 5, 10}, {2, 6, 12}, + {2, 7, 14}, {3, 5, 15}, {4, 4, 16}, {3, 6, 18}, + {4, 5, 20}, {3, 7, 21}, {4, 6, 24}, {5, 5, 25}, + {4, 7, 28}, {5, 6, 30}, {5, 7, 35}, {6, 6, 36}, + {6, 7, 42}, {7, 7, 49} + }; + + /* prate/REFDIV and result save to tmp0 */ + tmp0 = prate; + do_div(tmp0, refdiv); + + /* ((prate/REFDIV) x FBDIV) and result save to tmp0 */ + tmp0 *= fbdiv; + + /* ((prate/REFDIV) x FBDIV)/rate and result save to tmp0 */ + do_div(tmp0, rate); + + /* tmp0 is POSTDIV1*POSTDIV2, now we calculate div1 and div2 value */ + if (tmp0 <= 7) { + /* (div1 * div2) <= 7, no need to use array search */ + *postdiv1 = tmp0; + *postdiv2 = 1; + return 0; + } + + /* (div1 * div2) > 7, use array search */ + for (index = 0; index < ARRAY_SIZE(postdiv1_2); index++) { + if (tmp0 > postdiv1_2[index][POSTDIV_RESULT_INDEX]) { + continue; + } else { + /* found it */ + *postdiv1 = postdiv1_2[index][1]; + *postdiv2 = postdiv1_2[index][0]; + return 0; + } + } + pr_warn("%s can not find in postdiv array!\n", __func__); + return -EINVAL; +} + +/** + * sg2042_get_pll_ctl_setting() - Based on the given FOUTPISTDIV and the input + * FREF to calculate the REFDIV/FBDIV/PSTDIV1/POSTDIV2 combination for pllctrl + * register. + * @req_rate: expected output clock rate, i.e. FOUTPISTDIV + * @parent_rate: input parent clock rate, i.e. FREF + * @best: output to hold calculated combination of REFDIV/FBDIV/PSTDIV1/POSTDIV2 + * + * Return: + * %0 - OK + * %-EINVAL - invalid argument + */ +static int sg2042_get_pll_ctl_setting(struct sg2042_pll_ctrl *best, + unsigned long req_rate, + unsigned long parent_rate) +{ + unsigned int fbdiv, refdiv, postdiv1, postdiv2; + unsigned long foutpostdiv; + u64 foutvco; + int ret; + u64 tmp; + + if (parent_rate != PLL_FREF_SG2042) { + pr_err("INVALID FREF: %ld\n", parent_rate); + return -EINVAL; + } + + if (req_rate < PLL_FOUTPOSTDIV_MIN || req_rate > PLL_FOUTPOSTDIV_MAX) { + pr_alert("INVALID FOUTPOSTDIV: %ld\n", req_rate); + return -EINVAL; + } + + memset(best, 0, sizeof(struct sg2042_pll_ctrl)); + + for (refdiv = REFDIV_MIN; refdiv < REFDIV_MAX + 1; refdiv++) { + /* required by hardware: FREF/REFDIV must > 10 */ + tmp = parent_rate; + do_div(tmp, refdiv); + if (tmp <= 10) + continue; + + for (fbdiv = FBDIV_MIN; fbdiv < FBDIV_MAX + 1; fbdiv++) { + /* + * FOUTVCO = FREF*FBDIV/REFDIV validation + * required by hardware, FOUTVCO must [800MHz, 3200MHz] + */ + foutvco = parent_rate * fbdiv; + do_div(foutvco, refdiv); + if (foutvco < PLL_FOUTVCO_MIN || foutvco > PLL_FOUTVCO_MAX) + continue; + + ret = sg2042_pll_get_postdiv_1_2(req_rate, parent_rate, + fbdiv, refdiv, + &postdiv1, &postdiv2); + if (ret) + continue; + + /* + * FOUTPOSTDIV = FREF*FBDIV/REFDIV/(POSTDIV1*POSTDIV2) + * = FOUTVCO/(POSTDIV1*POSTDIV2) + */ + tmp = foutvco; + do_div(tmp, (postdiv1 * postdiv2)); + foutpostdiv = (unsigned long)tmp; + /* Iterative to approach the expected value */ + if (abs_diff(foutpostdiv, req_rate) < abs_diff(best->freq, req_rate)) { + best->freq = foutpostdiv; + best->refdiv = refdiv; + best->fbdiv = fbdiv; + best->postdiv1 = postdiv1; + best->postdiv2 = postdiv2; + if (foutpostdiv == req_rate) + return 0; + } + continue; + } + } + + if (best->freq == 0) + return -EINVAL; + else + return 0; +} + +/** + * sg2042_clk_pll_recalc_rate() - recalc_rate callback for pll clks + * @hw: ccf use to hook get sg2042_pll_clock + * @parent_rate: parent rate + * + * The is function will be called through clk_get_rate + * and return current rate after decoding reg value + * + * Return: Current rate recalculated. + */ +static unsigned long sg2042_clk_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sg2042_pll_clock *pll = to_sg2042_pll_clk(hw); + unsigned long rate; + u32 value; + + value = readl(pll->base + pll->offset_ctrl); + rate = sg2042_pll_recalc_rate(value, parent_rate); + + pr_debug("--> %s: pll_recalc_rate: val = %ld\n", + clk_hw_get_name(hw), rate); + return rate; +} + +static long sg2042_clk_pll_round_rate(struct clk_hw *hw, + unsigned long req_rate, + unsigned long *prate) +{ + struct sg2042_pll_ctrl pctrl_table; + unsigned int value; + long proper_rate; + int ret; + + ret = sg2042_get_pll_ctl_setting(&pctrl_table, req_rate, *prate); + if (ret) { + proper_rate = 0; + goto out; + } + + value = sg2042_pll_ctrl_encode(&pctrl_table); + proper_rate = (long)sg2042_pll_recalc_rate(value, *prate); + +out: + pr_debug("--> %s: pll_round_rate: val = %ld\n", + clk_hw_get_name(hw), proper_rate); + return proper_rate; +} + +static int sg2042_clk_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + req->rate = sg2042_clk_pll_round_rate(hw, min(req->rate, req->max_rate), + &req->best_parent_rate); + pr_debug("--> %s: pll_determine_rate: val = %ld\n", + clk_hw_get_name(hw), req->rate); + return 0; +} + +static int sg2042_clk_pll_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct sg2042_pll_clock *pll = to_sg2042_pll_clk(hw); + struct sg2042_pll_ctrl pctrl_table; + unsigned long flags; + u32 value; + int ret; + + spin_lock_irqsave(pll->lock, flags); + + sg2042_pll_enable(pll, 0); + + ret = sg2042_get_pll_ctl_setting(&pctrl_table, rate, parent_rate); + if (ret) { + pr_warn("%s: Can't find a proper pll setting\n", pll->hw.init->name); + goto out; + } + + value = sg2042_pll_ctrl_encode(&pctrl_table); + + /* write the value to top register */ + writel(value, pll->base + pll->offset_ctrl); + +out: + sg2042_pll_enable(pll, 1); + + spin_unlock_irqrestore(pll->lock, flags); + + pr_debug("--> %s: pll_set_rate: val = 0x%x\n", + clk_hw_get_name(hw), value); + return ret; +} + +static const struct clk_ops sg2042_clk_pll_ops = { + .recalc_rate = sg2042_clk_pll_recalc_rate, + .round_rate = sg2042_clk_pll_round_rate, + .determine_rate = sg2042_clk_pll_determine_rate, + .set_rate = sg2042_clk_pll_set_rate, +}; + +static const struct clk_ops sg2042_clk_pll_ro_ops = { + .recalc_rate = sg2042_clk_pll_recalc_rate, + .round_rate = sg2042_clk_pll_round_rate, +}; + +/* + * Clock initialization macro naming rules: + * FW: use CLK_HW_INIT_FW_NAME + * RO: means Read-Only + */ +#define SG2042_PLL_FW(_id, _name, _parent, _r_ctrl, _shift) \ + { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_FW_NAME( \ + _name, \ + _parent, \ + &sg2042_clk_pll_ops, \ + CLK_GET_RATE_NOCACHE | CLK_GET_ACCURACY_NOCACHE),\ + .offset_ctrl = _r_ctrl, \ + .shift_status_lock = 8 + (_shift), \ + .shift_status_updating = _shift, \ + .shift_enable = _shift, \ + } + +#define SG2042_PLL_FW_RO(_id, _name, _parent, _r_ctrl, _shift) \ + { \ + .id = _id, \ + .hw.init = CLK_HW_INIT_FW_NAME( \ + _name, \ + _parent, \ + &sg2042_clk_pll_ro_ops, \ + CLK_GET_RATE_NOCACHE | CLK_GET_ACCURACY_NOCACHE),\ + .offset_ctrl = _r_ctrl, \ + .shift_status_lock = 8 + (_shift), \ + .shift_status_updating = _shift, \ + .shift_enable = _shift, \ + } + +static struct sg2042_pll_clock sg2042_pll_clks[] = { + SG2042_PLL_FW(MPLL_CLK, "mpll_clock", "cgi_main", R_MPLL_CONTROL, 0), + SG2042_PLL_FW_RO(FPLL_CLK, "fpll_clock", "cgi_main", R_FPLL_CONTROL, 3), + SG2042_PLL_FW_RO(DPLL0_CLK, "dpll0_clock", "cgi_dpll0", R_DPLL0_CONTROL, 4), + SG2042_PLL_FW_RO(DPLL1_CLK, "dpll1_clock", "cgi_dpll1", R_DPLL1_CONTROL, 5), +}; + +static DEFINE_SPINLOCK(sg2042_clk_lock); + +static int sg2042_clk_register_plls(struct device *dev, + struct sg2042_clk_data *clk_data, + struct sg2042_pll_clock pll_clks[], + int num_pll_clks) +{ + struct sg2042_pll_clock *pll; + struct clk_hw *hw; + int i, ret = 0; + + for (i = 0; i < num_pll_clks; i++) { + pll = &pll_clks[i]; + /* assign these for ops usage during registration */ + pll->base = clk_data->iobase; + pll->lock = &sg2042_clk_lock; + + hw = &pll->hw; + ret = devm_clk_hw_register(dev, hw); + if (ret) { + pr_err("failed to register clock %s\n", pll->hw.init->name); + break; + } + + clk_data->onecell_data.hws[pll->id] = hw; + } + + return ret; +} + +static int sg2042_init_clkdata(struct platform_device *pdev, + int num_clks, + struct sg2042_clk_data **pp_clk_data) +{ + struct sg2042_clk_data *clk_data; + + clk_data = devm_kzalloc(&pdev->dev, + struct_size(clk_data, onecell_data.hws, num_clks), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->iobase = devm_platform_ioremap_resource(pdev, 0); + if (WARN_ON(IS_ERR(clk_data->iobase))) + return PTR_ERR(clk_data->iobase); + + clk_data->onecell_data.num = num_clks; + + *pp_clk_data = clk_data; + + return 0; +} + +static int sg2042_pll_probe(struct platform_device *pdev) +{ + struct sg2042_clk_data *clk_data = NULL; + int num_clks; + int ret; + + num_clks = ARRAY_SIZE(sg2042_pll_clks); + + ret = sg2042_init_clkdata(pdev, num_clks, &clk_data); + if (ret) + goto error_out; + + ret = sg2042_clk_register_plls(&pdev->dev, clk_data, sg2042_pll_clks, + num_clks); + if (ret) + goto error_out; + + return devm_of_clk_add_hw_provider(&pdev->dev, + of_clk_hw_onecell_get, + &clk_data->onecell_data); + +error_out: + pr_err("%s failed error number %d\n", __func__, ret); + return ret; +} + +static const struct of_device_id sg2042_pll_match[] = { + { .compatible = "sophgo,sg2042-pll" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, sg2042_pll_match); + +static struct platform_driver sg2042_pll_driver = { + .probe = sg2042_pll_probe, + .driver = { + .name = "clk-sophgo-sg2042-pll", + .of_match_table = sg2042_pll_match, + .suppress_bind_attrs = true, + }, +}; +module_platform_driver(sg2042_pll_driver); + +MODULE_AUTHOR("Chen Wang"); +MODULE_DESCRIPTION("Sophgo SG2042 pll clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sophgo/clk-sg2042-rpgate.c b/drivers/clk/sophgo/clk-sg2042-rpgate.c new file mode 100644 index 000000000000..5b38d4f15525 --- /dev/null +++ b/drivers/clk/sophgo/clk-sg2042-rpgate.c @@ -0,0 +1,291 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Sophgo SG2042 RP clock Driver + * + * Copyright (C) 2024 Sophgo Technology Inc. + * Copyright (C) 2024 Chen Wang <unicorn_wang@outlook.com> + */ + +#include <linux/array_size.h> +#include <linux/clk-provider.h> +#include <linux/platform_device.h> + +#include <dt-bindings/clock/sophgo,sg2042-rpgate.h> + +#include "clk-sg2042.h" + +#define R_SYSGATE_BEGIN 0x0368 +#define R_RP_RXU_CLK_ENABLE (0x0368 - R_SYSGATE_BEGIN) +#define R_MP0_STATUS_REG (0x0380 - R_SYSGATE_BEGIN) +#define R_MP0_CONTROL_REG (0x0384 - R_SYSGATE_BEGIN) +#define R_MP1_STATUS_REG (0x0388 - R_SYSGATE_BEGIN) +#define R_MP1_CONTROL_REG (0x038C - R_SYSGATE_BEGIN) +#define R_MP2_STATUS_REG (0x0390 - R_SYSGATE_BEGIN) +#define R_MP2_CONTROL_REG (0x0394 - R_SYSGATE_BEGIN) +#define R_MP3_STATUS_REG (0x0398 - R_SYSGATE_BEGIN) +#define R_MP3_CONTROL_REG (0x039C - R_SYSGATE_BEGIN) +#define R_MP4_STATUS_REG (0x03A0 - R_SYSGATE_BEGIN) +#define R_MP4_CONTROL_REG (0x03A4 - R_SYSGATE_BEGIN) +#define R_MP5_STATUS_REG (0x03A8 - R_SYSGATE_BEGIN) +#define R_MP5_CONTROL_REG (0x03AC - R_SYSGATE_BEGIN) +#define R_MP6_STATUS_REG (0x03B0 - R_SYSGATE_BEGIN) +#define R_MP6_CONTROL_REG (0x03B4 - R_SYSGATE_BEGIN) +#define R_MP7_STATUS_REG (0x03B8 - R_SYSGATE_BEGIN) +#define R_MP7_CONTROL_REG (0x03BC - R_SYSGATE_BEGIN) +#define R_MP8_STATUS_REG (0x03C0 - R_SYSGATE_BEGIN) +#define R_MP8_CONTROL_REG (0x03C4 - R_SYSGATE_BEGIN) +#define R_MP9_STATUS_REG (0x03C8 - R_SYSGATE_BEGIN) +#define R_MP9_CONTROL_REG (0x03CC - R_SYSGATE_BEGIN) +#define R_MP10_STATUS_REG (0x03D0 - R_SYSGATE_BEGIN) +#define R_MP10_CONTROL_REG (0x03D4 - R_SYSGATE_BEGIN) +#define R_MP11_STATUS_REG (0x03D8 - R_SYSGATE_BEGIN) +#define R_MP11_CONTROL_REG (0x03DC - R_SYSGATE_BEGIN) +#define R_MP12_STATUS_REG (0x03E0 - R_SYSGATE_BEGIN) +#define R_MP12_CONTROL_REG (0x03E4 - R_SYSGATE_BEGIN) +#define R_MP13_STATUS_REG (0x03E8 - R_SYSGATE_BEGIN) +#define R_MP13_CONTROL_REG (0x03EC - R_SYSGATE_BEGIN) +#define R_MP14_STATUS_REG (0x03F0 - R_SYSGATE_BEGIN) +#define R_MP14_CONTROL_REG (0x03F4 - R_SYSGATE_BEGIN) +#define R_MP15_STATUS_REG (0x03F8 - R_SYSGATE_BEGIN) +#define R_MP15_CONTROL_REG (0x03FC - R_SYSGATE_BEGIN) + +/** + * struct sg2042_rpgate_clock - Gate clock for RP(riscv processors) subsystem + * @hw: clk_hw for initialization + * @id: used to map clk_onecell_data + * @offset_enable: offset of gate enable registers + * @bit_idx: which bit in the register controls gating of this clock + */ +struct sg2042_rpgate_clock { + struct clk_hw hw; + + unsigned int id; + + u32 offset_enable; + u8 bit_idx; +}; + +/* + * Clock initialization macro naming rules: + * FW: use CLK_HW_INIT_FW_NAME + */ +#define SG2042_GATE_FW(_id, _name, _parent, _flags, \ + _r_enable, _bit_idx) { \ + .hw.init = CLK_HW_INIT_FW_NAME( \ + _name, \ + _parent, \ + NULL, \ + _flags), \ + .id = _id, \ + .offset_enable = _r_enable, \ + .bit_idx = _bit_idx, \ + } + +/* + * Gate clocks for RP subsystem (including the MP subsystem), which control + * registers are defined in SYS_CTRL. + */ +static const struct sg2042_rpgate_clock sg2042_gate_rp[] = { + /* downstream of clk_gate_rp_cpu_normal about rxu */ + SG2042_GATE_FW(GATE_CLK_RXU0, "clk_gate_rxu0", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 0), + SG2042_GATE_FW(GATE_CLK_RXU1, "clk_gate_rxu1", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 1), + SG2042_GATE_FW(GATE_CLK_RXU2, "clk_gate_rxu2", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 2), + SG2042_GATE_FW(GATE_CLK_RXU3, "clk_gate_rxu3", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 3), + SG2042_GATE_FW(GATE_CLK_RXU4, "clk_gate_rxu4", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 4), + SG2042_GATE_FW(GATE_CLK_RXU5, "clk_gate_rxu5", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 5), + SG2042_GATE_FW(GATE_CLK_RXU6, "clk_gate_rxu6", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 6), + SG2042_GATE_FW(GATE_CLK_RXU7, "clk_gate_rxu7", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 7), + SG2042_GATE_FW(GATE_CLK_RXU8, "clk_gate_rxu8", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 8), + SG2042_GATE_FW(GATE_CLK_RXU9, "clk_gate_rxu9", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 9), + SG2042_GATE_FW(GATE_CLK_RXU10, "clk_gate_rxu10", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 10), + SG2042_GATE_FW(GATE_CLK_RXU11, "clk_gate_rxu11", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 11), + SG2042_GATE_FW(GATE_CLK_RXU12, "clk_gate_rxu12", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 12), + SG2042_GATE_FW(GATE_CLK_RXU13, "clk_gate_rxu13", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 13), + SG2042_GATE_FW(GATE_CLK_RXU14, "clk_gate_rxu14", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 14), + SG2042_GATE_FW(GATE_CLK_RXU15, "clk_gate_rxu15", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 15), + SG2042_GATE_FW(GATE_CLK_RXU16, "clk_gate_rxu16", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 16), + SG2042_GATE_FW(GATE_CLK_RXU17, "clk_gate_rxu17", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 17), + SG2042_GATE_FW(GATE_CLK_RXU18, "clk_gate_rxu18", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 18), + SG2042_GATE_FW(GATE_CLK_RXU19, "clk_gate_rxu19", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 19), + SG2042_GATE_FW(GATE_CLK_RXU20, "clk_gate_rxu20", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 20), + SG2042_GATE_FW(GATE_CLK_RXU21, "clk_gate_rxu21", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 21), + SG2042_GATE_FW(GATE_CLK_RXU22, "clk_gate_rxu22", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 22), + SG2042_GATE_FW(GATE_CLK_RXU23, "clk_gate_rxu23", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 23), + SG2042_GATE_FW(GATE_CLK_RXU24, "clk_gate_rxu24", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 24), + SG2042_GATE_FW(GATE_CLK_RXU25, "clk_gate_rxu25", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 25), + SG2042_GATE_FW(GATE_CLK_RXU26, "clk_gate_rxu26", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 26), + SG2042_GATE_FW(GATE_CLK_RXU27, "clk_gate_rxu27", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 27), + SG2042_GATE_FW(GATE_CLK_RXU28, "clk_gate_rxu28", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 28), + SG2042_GATE_FW(GATE_CLK_RXU29, "clk_gate_rxu29", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 29), + SG2042_GATE_FW(GATE_CLK_RXU30, "clk_gate_rxu30", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 30), + SG2042_GATE_FW(GATE_CLK_RXU31, "clk_gate_rxu31", "rpgate", + 0, R_RP_RXU_CLK_ENABLE, 31), + + /* downstream of clk_gate_rp_cpu_normal about mp */ + SG2042_GATE_FW(GATE_CLK_MP0, "clk_gate_mp0", "rpgate", + CLK_IS_CRITICAL, R_MP0_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP1, "clk_gate_mp1", "rpgate", + CLK_IS_CRITICAL, R_MP1_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP2, "clk_gate_mp2", "rpgate", + CLK_IS_CRITICAL, R_MP2_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP3, "clk_gate_mp3", "rpgate", + CLK_IS_CRITICAL, R_MP3_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP4, "clk_gate_mp4", "rpgate", + CLK_IS_CRITICAL, R_MP4_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP5, "clk_gate_mp5", "rpgate", + CLK_IS_CRITICAL, R_MP5_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP6, "clk_gate_mp6", "rpgate", + CLK_IS_CRITICAL, R_MP6_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP7, "clk_gate_mp7", "rpgate", + CLK_IS_CRITICAL, R_MP7_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP8, "clk_gate_mp8", "rpgate", + CLK_IS_CRITICAL, R_MP8_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP9, "clk_gate_mp9", "rpgate", + CLK_IS_CRITICAL, R_MP9_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP10, "clk_gate_mp10", "rpgate", + CLK_IS_CRITICAL, R_MP10_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP11, "clk_gate_mp11", "rpgate", + CLK_IS_CRITICAL, R_MP11_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP12, "clk_gate_mp12", "rpgate", + CLK_IS_CRITICAL, R_MP12_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP13, "clk_gate_mp13", "rpgate", + CLK_IS_CRITICAL, R_MP13_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP14, "clk_gate_mp14", "rpgate", + CLK_IS_CRITICAL, R_MP14_CONTROL_REG, 0), + SG2042_GATE_FW(GATE_CLK_MP15, "clk_gate_mp15", "rpgate", + CLK_IS_CRITICAL, R_MP15_CONTROL_REG, 0), +}; + +static DEFINE_SPINLOCK(sg2042_clk_lock); + +static int sg2042_clk_register_rpgates(struct device *dev, + struct sg2042_clk_data *clk_data, + const struct sg2042_rpgate_clock gate_clks[], + int num_gate_clks) +{ + const struct sg2042_rpgate_clock *gate; + struct clk_hw *hw; + int i, ret = 0; + + for (i = 0; i < num_gate_clks; i++) { + gate = &gate_clks[i]; + hw = devm_clk_hw_register_gate_parent_data + (dev, + gate->hw.init->name, + gate->hw.init->parent_data, + gate->hw.init->flags, + clk_data->iobase + gate->offset_enable, + gate->bit_idx, + 0, + &sg2042_clk_lock); + if (IS_ERR(hw)) { + pr_err("failed to register clock %s\n", gate->hw.init->name); + ret = PTR_ERR(hw); + break; + } + + clk_data->onecell_data.hws[gate->id] = hw; + } + + return ret; +} + +static int sg2042_init_clkdata(struct platform_device *pdev, + int num_clks, + struct sg2042_clk_data **pp_clk_data) +{ + struct sg2042_clk_data *clk_data; + + clk_data = devm_kzalloc(&pdev->dev, + struct_size(clk_data, onecell_data.hws, num_clks), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->iobase = devm_platform_ioremap_resource(pdev, 0); + if (WARN_ON(IS_ERR(clk_data->iobase))) + return PTR_ERR(clk_data->iobase); + + clk_data->onecell_data.num = num_clks; + + *pp_clk_data = clk_data; + + return 0; +} + +static int sg2042_rpgate_probe(struct platform_device *pdev) +{ + struct sg2042_clk_data *clk_data = NULL; + int num_clks; + int ret; + + num_clks = ARRAY_SIZE(sg2042_gate_rp); + + ret = sg2042_init_clkdata(pdev, num_clks, &clk_data); + if (ret) + goto error_out; + + ret = sg2042_clk_register_rpgates(&pdev->dev, clk_data, sg2042_gate_rp, + num_clks); + if (ret) + goto error_out; + + return devm_of_clk_add_hw_provider(&pdev->dev, + of_clk_hw_onecell_get, + &clk_data->onecell_data); + +error_out: + pr_err("%s failed error number %d\n", __func__, ret); + return ret; +} + +static const struct of_device_id sg2042_rpgate_match[] = { + { .compatible = "sophgo,sg2042-rpgate" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, sg2042_rpgate_match); + +static struct platform_driver sg2042_rpgate_driver = { + .probe = sg2042_rpgate_probe, + .driver = { + .name = "clk-sophgo-sg2042-rpgate", + .of_match_table = sg2042_rpgate_match, + .suppress_bind_attrs = true, + }, +}; +module_platform_driver(sg2042_rpgate_driver); + +MODULE_AUTHOR("Chen Wang"); +MODULE_DESCRIPTION("Sophgo SG2042 rp subsystem clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sophgo/clk-sg2042.h b/drivers/clk/sophgo/clk-sg2042.h new file mode 100644 index 000000000000..f13fed399c6e --- /dev/null +++ b/drivers/clk/sophgo/clk-sg2042.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _CLK_SOPHGO_SG2042_H_ +#define _CLK_SOPHGO_SG2042_H_ + +#include <linux/io.h> +#include <linux/clk-provider.h> + +/** + * struct sg2042_clk_data - Common data of clock-controller + * @iobase: base address of clock-controller + * @onecell_data: used for adding providers. + */ +struct sg2042_clk_data { + void __iomem *iobase; + struct clk_hw_onecell_data onecell_data; +}; + +#endif /* _CLK_SOPHGO_SG2042_H_ */ diff --git a/drivers/clk/thead/Kconfig b/drivers/clk/thead/Kconfig new file mode 100644 index 000000000000..1710d50bf9d4 --- /dev/null +++ b/drivers/clk/thead/Kconfig @@ -0,0 +1,12 @@ +#SPDX-License-Identifier: GPL-2.0 + +config CLK_THEAD_TH1520_AP + bool "T-HEAD TH1520 AP clock support" + depends on ARCH_THEAD || COMPILE_TEST + default ARCH_THEAD + select REGMAP_MMIO + help + Say yes here to support the AP sub system clock controller + on the T-HEAD TH1520 SoC. This includes configuration of + both CPU PLLs, both DPU PLLs as well as the GMAC, VIDEO, + and TEE PLLs. diff --git a/drivers/clk/thead/Makefile b/drivers/clk/thead/Makefile new file mode 100644 index 000000000000..7ee0bec1f251 --- /dev/null +++ b/drivers/clk/thead/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_CLK_THEAD_TH1520_AP) += clk-th1520-ap.o diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c new file mode 100644 index 000000000000..cbc176b27c09 --- /dev/null +++ b/drivers/clk/thead/clk-th1520-ap.c @@ -0,0 +1,1089 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org> + * Copyright (C) 2023 Vivo Communication Technology Co. Ltd. + * Authors: Yangtao Li <frank.li@vivo.com> + */ + +#include <dt-bindings/clock/thead,th1520-clk-ap.h> +#include <linux/bitfield.h> +#include <linux/clk-provider.h> +#include <linux/device.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define TH1520_PLL_POSTDIV2 GENMASK(26, 24) +#define TH1520_PLL_POSTDIV1 GENMASK(22, 20) +#define TH1520_PLL_FBDIV GENMASK(19, 8) +#define TH1520_PLL_REFDIV GENMASK(5, 0) +#define TH1520_PLL_BYPASS BIT(30) +#define TH1520_PLL_DSMPD BIT(24) +#define TH1520_PLL_FRAC GENMASK(23, 0) +#define TH1520_PLL_FRAC_BITS 24 + +struct ccu_internal { + u8 shift; + u8 width; +}; + +struct ccu_div_internal { + u8 shift; + u8 width; + u32 flags; +}; + +struct ccu_common { + int clkid; + struct regmap *map; + u16 cfg0; + u16 cfg1; + struct clk_hw hw; +}; + +struct ccu_mux { + struct ccu_internal mux; + struct ccu_common common; +}; + +struct ccu_gate { + u32 enable; + struct ccu_common common; +}; + +struct ccu_div { + u32 enable; + struct ccu_div_internal div; + struct ccu_internal mux; + struct ccu_common common; +}; + +struct ccu_pll { + struct ccu_common common; +}; + +#define TH_CCU_ARG(_shift, _width) \ + { \ + .shift = _shift, \ + .width = _width, \ + } + +#define TH_CCU_DIV_FLAGS(_shift, _width, _flags) \ + { \ + .shift = _shift, \ + .width = _width, \ + .flags = _flags, \ + } + +#define CCU_GATE(_clkid, _struct, _name, _parent, _reg, _gate, _flags) \ + struct ccu_gate _struct = { \ + .enable = _gate, \ + .common = { \ + .clkid = _clkid, \ + .cfg0 = _reg, \ + .hw.init = CLK_HW_INIT_PARENTS_DATA( \ + _name, \ + _parent, \ + &clk_gate_ops, \ + _flags), \ + } \ + } + +static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw) +{ + return container_of(hw, struct ccu_common, hw); +} + +static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + return container_of(common, struct ccu_mux, common); +} + +static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + return container_of(common, struct ccu_pll, common); +} + +static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + return container_of(common, struct ccu_div, common); +} + +static inline struct ccu_gate *hw_to_ccu_gate(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + return container_of(common, struct ccu_gate, common); +} + +static u8 ccu_get_parent_helper(struct ccu_common *common, + struct ccu_internal *mux) +{ + unsigned int val; + u8 parent; + + regmap_read(common->map, common->cfg0, &val); + parent = val >> mux->shift; + parent &= GENMASK(mux->width - 1, 0); + + return parent; +} + +static int ccu_set_parent_helper(struct ccu_common *common, + struct ccu_internal *mux, + u8 index) +{ + return regmap_update_bits(common->map, common->cfg0, + GENMASK(mux->width - 1, 0) << mux->shift, + index << mux->shift); +} + +static void ccu_disable_helper(struct ccu_common *common, u32 gate) +{ + if (!gate) + return; + regmap_update_bits(common->map, common->cfg0, + gate, ~gate); +} + +static int ccu_enable_helper(struct ccu_common *common, u32 gate) +{ + unsigned int val; + int ret; + + if (!gate) + return 0; + + ret = regmap_update_bits(common->map, common->cfg0, gate, gate); + regmap_read(common->map, common->cfg0, &val); + return ret; +} + +static int ccu_is_enabled_helper(struct ccu_common *common, u32 gate) +{ + unsigned int val; + + if (!gate) + return true; + + regmap_read(common->map, common->cfg0, &val); + return val & gate; +} + +static unsigned long ccu_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ccu_div *cd = hw_to_ccu_div(hw); + unsigned long rate; + unsigned int val; + + regmap_read(cd->common.map, cd->common.cfg0, &val); + val = val >> cd->div.shift; + val &= GENMASK(cd->div.width - 1, 0); + rate = divider_recalc_rate(hw, parent_rate, val, NULL, + cd->div.flags, cd->div.width); + + return rate; +} + +static u8 ccu_div_get_parent(struct clk_hw *hw) +{ + struct ccu_div *cd = hw_to_ccu_div(hw); + + return ccu_get_parent_helper(&cd->common, &cd->mux); +} + +static int ccu_div_set_parent(struct clk_hw *hw, u8 index) +{ + struct ccu_div *cd = hw_to_ccu_div(hw); + + return ccu_set_parent_helper(&cd->common, &cd->mux, index); +} + +static void ccu_div_disable(struct clk_hw *hw) +{ + struct ccu_div *cd = hw_to_ccu_div(hw); + + ccu_disable_helper(&cd->common, cd->enable); +} + +static int ccu_div_enable(struct clk_hw *hw) +{ + struct ccu_div *cd = hw_to_ccu_div(hw); + + return ccu_enable_helper(&cd->common, cd->enable); +} + +static int ccu_div_is_enabled(struct clk_hw *hw) +{ + struct ccu_div *cd = hw_to_ccu_div(hw); + + return ccu_is_enabled_helper(&cd->common, cd->enable); +} + +static const struct clk_ops ccu_div_ops = { + .disable = ccu_div_disable, + .enable = ccu_div_enable, + .is_enabled = ccu_div_is_enabled, + .get_parent = ccu_div_get_parent, + .set_parent = ccu_div_set_parent, + .recalc_rate = ccu_div_recalc_rate, + .determine_rate = clk_hw_determine_rate_no_reparent, +}; + +static unsigned long th1520_pll_vco_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + unsigned long div, mul, frac; + unsigned int cfg0, cfg1; + u64 rate = parent_rate; + + regmap_read(pll->common.map, pll->common.cfg0, &cfg0); + regmap_read(pll->common.map, pll->common.cfg1, &cfg1); + + mul = FIELD_GET(TH1520_PLL_FBDIV, cfg0); + div = FIELD_GET(TH1520_PLL_REFDIV, cfg0); + if (!(cfg1 & TH1520_PLL_DSMPD)) { + mul <<= TH1520_PLL_FRAC_BITS; + frac = FIELD_GET(TH1520_PLL_FRAC, cfg1); + mul += frac; + div <<= TH1520_PLL_FRAC_BITS; + } + rate = parent_rate * mul; + rate = rate / div; + return rate; +} + +static unsigned long th1520_pll_postdiv_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + unsigned long div, rate = parent_rate; + unsigned int cfg0, cfg1; + + regmap_read(pll->common.map, pll->common.cfg0, &cfg0); + regmap_read(pll->common.map, pll->common.cfg1, &cfg1); + + if (cfg1 & TH1520_PLL_BYPASS) + return rate; + + div = FIELD_GET(TH1520_PLL_POSTDIV1, cfg0) * + FIELD_GET(TH1520_PLL_POSTDIV2, cfg0); + + rate = rate / div; + + return rate; +} + +static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + unsigned long rate = parent_rate; + + rate = th1520_pll_vco_recalc_rate(hw, rate); + rate = th1520_pll_postdiv_recalc_rate(hw, rate); + + return rate; +} + +static const struct clk_ops clk_pll_ops = { + .recalc_rate = ccu_pll_recalc_rate, +}; + +static const struct clk_parent_data osc_24m_clk[] = { + { .index = 0 } +}; + +static struct ccu_pll cpu_pll0_clk = { + .common = { + .clkid = CLK_CPU_PLL0, + .cfg0 = 0x000, + .cfg1 = 0x004, + .hw.init = CLK_HW_INIT_PARENTS_DATA("cpu-pll0", + osc_24m_clk, + &clk_pll_ops, + 0), + }, +}; + +static struct ccu_pll cpu_pll1_clk = { + .common = { + .clkid = CLK_CPU_PLL1, + .cfg0 = 0x010, + .cfg1 = 0x014, + .hw.init = CLK_HW_INIT_PARENTS_DATA("cpu-pll1", + osc_24m_clk, + &clk_pll_ops, + 0), + }, +}; + +static struct ccu_pll gmac_pll_clk = { + .common = { + .clkid = CLK_GMAC_PLL, + .cfg0 = 0x020, + .cfg1 = 0x024, + .hw.init = CLK_HW_INIT_PARENTS_DATA("gmac-pll", + osc_24m_clk, + &clk_pll_ops, + 0), + }, +}; + +static const struct clk_hw *gmac_pll_clk_parent[] = { + &gmac_pll_clk.common.hw +}; + +static const struct clk_parent_data gmac_pll_clk_pd[] = { + { .hw = &gmac_pll_clk.common.hw } +}; + +static struct ccu_pll video_pll_clk = { + .common = { + .clkid = CLK_VIDEO_PLL, + .cfg0 = 0x030, + .cfg1 = 0x034, + .hw.init = CLK_HW_INIT_PARENTS_DATA("video-pll", + osc_24m_clk, + &clk_pll_ops, + 0), + }, +}; + +static const struct clk_hw *video_pll_clk_parent[] = { + &video_pll_clk.common.hw +}; + +static const struct clk_parent_data video_pll_clk_pd[] = { + { .hw = &video_pll_clk.common.hw } +}; + +static struct ccu_pll dpu0_pll_clk = { + .common = { + .clkid = CLK_DPU0_PLL, + .cfg0 = 0x040, + .cfg1 = 0x044, + .hw.init = CLK_HW_INIT_PARENTS_DATA("dpu0-pll", + osc_24m_clk, + &clk_pll_ops, + 0), + }, +}; + +static const struct clk_hw *dpu0_pll_clk_parent[] = { + &dpu0_pll_clk.common.hw +}; + +static struct ccu_pll dpu1_pll_clk = { + .common = { + .clkid = CLK_DPU1_PLL, + .cfg0 = 0x050, + .cfg1 = 0x054, + .hw.init = CLK_HW_INIT_PARENTS_DATA("dpu1-pll", + osc_24m_clk, + &clk_pll_ops, + 0), + }, +}; + +static const struct clk_hw *dpu1_pll_clk_parent[] = { + &dpu1_pll_clk.common.hw +}; + +static struct ccu_pll tee_pll_clk = { + .common = { + .clkid = CLK_TEE_PLL, + .cfg0 = 0x060, + .cfg1 = 0x064, + .hw.init = CLK_HW_INIT_PARENTS_DATA("tee-pll", + osc_24m_clk, + &clk_pll_ops, + 0), + }, +}; + +static const struct clk_parent_data c910_i0_parents[] = { + { .hw = &cpu_pll0_clk.common.hw }, + { .index = 0 } +}; + +static struct ccu_mux c910_i0_clk = { + .mux = TH_CCU_ARG(1, 1), + .common = { + .clkid = CLK_C910_I0, + .cfg0 = 0x100, + .hw.init = CLK_HW_INIT_PARENTS_DATA("c910-i0", + c910_i0_parents, + &clk_mux_ops, + 0), + } +}; + +static const struct clk_parent_data c910_parents[] = { + { .hw = &c910_i0_clk.common.hw }, + { .hw = &cpu_pll1_clk.common.hw } +}; + +static struct ccu_mux c910_clk = { + .mux = TH_CCU_ARG(0, 1), + .common = { + .clkid = CLK_C910, + .cfg0 = 0x100, + .hw.init = CLK_HW_INIT_PARENTS_DATA("c910", + c910_parents, + &clk_mux_ops, + 0), + } +}; + +static const struct clk_parent_data ahb2_cpusys_parents[] = { + { .hw = &gmac_pll_clk.common.hw }, + { .index = 0 } +}; + +static struct ccu_div ahb2_cpusys_hclk = { + .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED), + .mux = TH_CCU_ARG(5, 1), + .common = { + .clkid = CLK_AHB2_CPUSYS_HCLK, + .cfg0 = 0x120, + .hw.init = CLK_HW_INIT_PARENTS_DATA("ahb2-cpusys-hclk", + ahb2_cpusys_parents, + &ccu_div_ops, + 0), + }, +}; + +static const struct clk_parent_data ahb2_cpusys_hclk_pd[] = { + { .hw = &ahb2_cpusys_hclk.common.hw } +}; + +static const struct clk_hw *ahb2_cpusys_hclk_parent[] = { + &ahb2_cpusys_hclk.common.hw, +}; + +static struct ccu_div apb3_cpusys_pclk = { + .div = TH_CCU_ARG(0, 3), + .common = { + .clkid = CLK_APB3_CPUSYS_PCLK, + .cfg0 = 0x130, + .hw.init = CLK_HW_INIT_PARENTS_HW("apb3-cpusys-pclk", + ahb2_cpusys_hclk_parent, + &ccu_div_ops, + 0), + }, +}; + +static const struct clk_parent_data apb3_cpusys_pclk_pd[] = { + { .hw = &apb3_cpusys_pclk.common.hw } +}; + +static struct ccu_div axi4_cpusys2_aclk = { + .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED), + .common = { + .clkid = CLK_AXI4_CPUSYS2_ACLK, + .cfg0 = 0x134, + .hw.init = CLK_HW_INIT_PARENTS_HW("axi4-cpusys2-aclk", + gmac_pll_clk_parent, + &ccu_div_ops, + 0), + }, +}; + +static const struct clk_parent_data axi4_cpusys2_aclk_pd[] = { + { .hw = &axi4_cpusys2_aclk.common.hw } +}; + +static const struct clk_parent_data axi_parents[] = { + { .hw = &video_pll_clk.common.hw }, + { .index = 0 } +}; + +static struct ccu_div axi_aclk = { + .div = TH_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ONE_BASED), + .mux = TH_CCU_ARG(5, 1), + .common = { + .clkid = CLK_AXI_ACLK, + .cfg0 = 0x138, + .hw.init = CLK_HW_INIT_PARENTS_DATA("axi-aclk", + axi_parents, + &ccu_div_ops, + 0), + }, +}; + +static const struct clk_parent_data axi_aclk_pd[] = { + { .hw = &axi_aclk.common.hw } +}; + +static const struct clk_parent_data perisys_ahb_hclk_parents[] = { + { .hw = &gmac_pll_clk.common.hw }, + { .index = 0 }, +}; + +static struct ccu_div perisys_ahb_hclk = { + .enable = BIT(6), + .div = TH_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ONE_BASED), + .mux = TH_CCU_ARG(5, 1), + .common = { + .clkid = CLK_PERI_AHB_HCLK, + .cfg0 = 0x140, + .hw.init = CLK_HW_INIT_PARENTS_DATA("perisys-ahb-hclk", + perisys_ahb_hclk_parents, + &ccu_div_ops, + 0), + }, +}; + +static const struct clk_parent_data perisys_ahb_hclk_pd[] = { + { .hw = &perisys_ahb_hclk.common.hw } +}; + +static const struct clk_hw *perisys_ahb_hclk_parent[] = { + &perisys_ahb_hclk.common.hw +}; + +static struct ccu_div perisys_apb_pclk = { + .div = TH_CCU_ARG(0, 3), + .common = { + .clkid = CLK_PERI_APB_PCLK, + .cfg0 = 0x150, + .hw.init = CLK_HW_INIT_PARENTS_HW("perisys-apb-pclk", + perisys_ahb_hclk_parent, + &ccu_div_ops, + 0), + }, +}; + +static const struct clk_parent_data perisys_apb_pclk_pd[] = { + { .hw = &perisys_apb_pclk.common.hw } +}; + +static struct ccu_div peri2sys_apb_pclk = { + .div = TH_CCU_DIV_FLAGS(4, 3, CLK_DIVIDER_ONE_BASED), + .common = { + .clkid = CLK_PERI2APB_PCLK, + .cfg0 = 0x150, + .hw.init = CLK_HW_INIT_PARENTS_HW("peri2sys-apb-pclk", + gmac_pll_clk_parent, + &ccu_div_ops, + 0), + }, +}; + +static const struct clk_parent_data peri2sys_apb_pclk_pd[] = { + { .hw = &peri2sys_apb_pclk.common.hw } +}; + +static CLK_FIXED_FACTOR_FW_NAME(osc12m_clk, "osc_12m", "osc_24m", 2, 1, 0); + +static const char * const out_parents[] = { "osc_24m", "osc_12m" }; + +static struct ccu_div out1_clk = { + .enable = BIT(5), + .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED), + .mux = TH_CCU_ARG(4, 1), + .common = { + .clkid = CLK_OUT1, + .cfg0 = 0x1b4, + .hw.init = CLK_HW_INIT_PARENTS("out1", + out_parents, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div out2_clk = { + .enable = BIT(5), + .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED), + .mux = TH_CCU_ARG(4, 1), + .common = { + .clkid = CLK_OUT2, + .cfg0 = 0x1b8, + .hw.init = CLK_HW_INIT_PARENTS("out2", + out_parents, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div out3_clk = { + .enable = BIT(5), + .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED), + .mux = TH_CCU_ARG(4, 1), + .common = { + .clkid = CLK_OUT3, + .cfg0 = 0x1bc, + .hw.init = CLK_HW_INIT_PARENTS("out3", + out_parents, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div out4_clk = { + .enable = BIT(5), + .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED), + .mux = TH_CCU_ARG(4, 1), + .common = { + .clkid = CLK_OUT4, + .cfg0 = 0x1c0, + .hw.init = CLK_HW_INIT_PARENTS("out4", + out_parents, + &ccu_div_ops, + 0), + }, +}; + +static const struct clk_parent_data apb_parents[] = { + { .hw = &gmac_pll_clk.common.hw }, + { .index = 0 }, +}; + +static struct ccu_div apb_pclk = { + .enable = BIT(5), + .div = TH_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ONE_BASED), + .mux = TH_CCU_ARG(7, 1), + .common = { + .clkid = CLK_APB_PCLK, + .cfg0 = 0x1c4, + .hw.init = CLK_HW_INIT_PARENTS_DATA("apb-pclk", + apb_parents, + &ccu_div_ops, + 0), + }, +}; + +static const struct clk_hw *npu_parents[] = { + &gmac_pll_clk.common.hw, + &video_pll_clk.common.hw +}; + +static struct ccu_div npu_clk = { + .enable = BIT(4), + .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED), + .mux = TH_CCU_ARG(6, 1), + .common = { + .clkid = CLK_NPU, + .cfg0 = 0x1c8, + .hw.init = CLK_HW_INIT_PARENTS_HW("npu", + npu_parents, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div vi_clk = { + .div = TH_CCU_DIV_FLAGS(16, 4, CLK_DIVIDER_ONE_BASED), + .common = { + .clkid = CLK_VI, + .cfg0 = 0x1d0, + .hw.init = CLK_HW_INIT_PARENTS_HW("vi", + video_pll_clk_parent, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div vi_ahb_clk = { + .div = TH_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ONE_BASED), + .common = { + .clkid = CLK_VI_AHB, + .cfg0 = 0x1d0, + .hw.init = CLK_HW_INIT_PARENTS_HW("vi-ahb", + video_pll_clk_parent, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div vo_axi_clk = { + .enable = BIT(5), + .div = TH_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ONE_BASED), + .common = { + .clkid = CLK_VO_AXI, + .cfg0 = 0x1dc, + .hw.init = CLK_HW_INIT_PARENTS_HW("vo-axi", + video_pll_clk_parent, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div vp_apb_clk = { + .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED), + .common = { + .clkid = CLK_VP_APB, + .cfg0 = 0x1e0, + .hw.init = CLK_HW_INIT_PARENTS_HW("vp-apb", + gmac_pll_clk_parent, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div vp_axi_clk = { + .enable = BIT(15), + .div = TH_CCU_DIV_FLAGS(8, 4, CLK_DIVIDER_ONE_BASED), + .common = { + .clkid = CLK_VP_AXI, + .cfg0 = 0x1e0, + .hw.init = CLK_HW_INIT_PARENTS_HW("vp-axi", + video_pll_clk_parent, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div venc_clk = { + .enable = BIT(5), + .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED), + .common = { + .clkid = CLK_VENC, + .cfg0 = 0x1e4, + .hw.init = CLK_HW_INIT_PARENTS_HW("venc", + gmac_pll_clk_parent, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div dpu0_clk = { + .div = TH_CCU_DIV_FLAGS(0, 8, CLK_DIVIDER_ONE_BASED), + .common = { + .clkid = CLK_DPU0, + .cfg0 = 0x1e8, + .hw.init = CLK_HW_INIT_PARENTS_HW("dpu0", + dpu0_pll_clk_parent, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div dpu1_clk = { + .div = TH_CCU_DIV_FLAGS(0, 8, CLK_DIVIDER_ONE_BASED), + .common = { + .clkid = CLK_DPU1, + .cfg0 = 0x1ec, + .hw.init = CLK_HW_INIT_PARENTS_HW("dpu1", + dpu1_pll_clk_parent, + &ccu_div_ops, + 0), + }, +}; + +static CCU_GATE(CLK_BROM, brom_clk, "brom", ahb2_cpusys_hclk_pd, 0x100, BIT(4), 0); +static CCU_GATE(CLK_BMU, bmu_clk, "bmu", axi4_cpusys2_aclk_pd, 0x100, BIT(5), 0); +static CCU_GATE(CLK_AON2CPU_A2X, aon2cpu_a2x_clk, "aon2cpu-a2x", axi4_cpusys2_aclk_pd, + 0x134, BIT(8), 0); +static CCU_GATE(CLK_X2X_CPUSYS, x2x_cpusys_clk, "x2x-cpusys", axi4_cpusys2_aclk_pd, + 0x134, BIT(7), 0); +static CCU_GATE(CLK_CPU2AON_X2H, cpu2aon_x2h_clk, "cpu2aon-x2h", axi_aclk_pd, 0x138, BIT(8), 0); +static CCU_GATE(CLK_CPU2PERI_X2H, cpu2peri_x2h_clk, "cpu2peri-x2h", axi4_cpusys2_aclk_pd, + 0x140, BIT(9), 0); +static CCU_GATE(CLK_PERISYS_APB1_HCLK, perisys_apb1_hclk, "perisys-apb1-hclk", perisys_ahb_hclk_pd, + 0x150, BIT(9), 0); +static CCU_GATE(CLK_PERISYS_APB2_HCLK, perisys_apb2_hclk, "perisys-apb2-hclk", perisys_ahb_hclk_pd, + 0x150, BIT(10), 0); +static CCU_GATE(CLK_PERISYS_APB3_HCLK, perisys_apb3_hclk, "perisys-apb3-hclk", perisys_ahb_hclk_pd, + 0x150, BIT(11), 0); +static CCU_GATE(CLK_PERISYS_APB4_HCLK, perisys_apb4_hclk, "perisys-apb4-hclk", perisys_ahb_hclk_pd, + 0x150, BIT(12), 0); +static CCU_GATE(CLK_NPU_AXI, npu_axi_clk, "npu-axi", axi_aclk_pd, 0x1c8, BIT(5), 0); +static CCU_GATE(CLK_CPU2VP, cpu2vp_clk, "cpu2vp", axi_aclk_pd, 0x1e0, BIT(13), 0); +static CCU_GATE(CLK_EMMC_SDIO, emmc_sdio_clk, "emmc-sdio", video_pll_clk_pd, 0x204, BIT(30), 0); +static CCU_GATE(CLK_GMAC1, gmac1_clk, "gmac1", gmac_pll_clk_pd, 0x204, BIT(26), 0); +static CCU_GATE(CLK_PADCTRL1, padctrl1_clk, "padctrl1", perisys_apb_pclk_pd, 0x204, BIT(24), 0); +static CCU_GATE(CLK_DSMART, dsmart_clk, "dsmart", perisys_apb_pclk_pd, 0x204, BIT(23), 0); +static CCU_GATE(CLK_PADCTRL0, padctrl0_clk, "padctrl0", perisys_apb_pclk_pd, 0x204, BIT(22), 0); +static CCU_GATE(CLK_GMAC_AXI, gmac_axi_clk, "gmac-axi", axi4_cpusys2_aclk_pd, 0x204, BIT(21), 0); +static CCU_GATE(CLK_GPIO3, gpio3_clk, "gpio3-clk", peri2sys_apb_pclk_pd, 0x204, BIT(20), 0); +static CCU_GATE(CLK_GMAC0, gmac0_clk, "gmac0", gmac_pll_clk_pd, 0x204, BIT(19), 0); +static CCU_GATE(CLK_PWM, pwm_clk, "pwm", perisys_apb_pclk_pd, 0x204, BIT(18), 0); +static CCU_GATE(CLK_QSPI0, qspi0_clk, "qspi0", video_pll_clk_pd, 0x204, BIT(17), 0); +static CCU_GATE(CLK_QSPI1, qspi1_clk, "qspi1", video_pll_clk_pd, 0x204, BIT(16), 0); +static CCU_GATE(CLK_SPI, spi_clk, "spi", video_pll_clk_pd, 0x204, BIT(15), 0); +static CCU_GATE(CLK_UART0_PCLK, uart0_pclk, "uart0-pclk", perisys_apb_pclk_pd, 0x204, BIT(14), 0); +static CCU_GATE(CLK_UART1_PCLK, uart1_pclk, "uart1-pclk", perisys_apb_pclk_pd, 0x204, BIT(13), 0); +static CCU_GATE(CLK_UART2_PCLK, uart2_pclk, "uart2-pclk", perisys_apb_pclk_pd, 0x204, BIT(12), 0); +static CCU_GATE(CLK_UART3_PCLK, uart3_pclk, "uart3-pclk", perisys_apb_pclk_pd, 0x204, BIT(11), 0); +static CCU_GATE(CLK_UART4_PCLK, uart4_pclk, "uart4-pclk", perisys_apb_pclk_pd, 0x204, BIT(10), 0); +static CCU_GATE(CLK_UART5_PCLK, uart5_pclk, "uart5-pclk", perisys_apb_pclk_pd, 0x204, BIT(9), 0); +static CCU_GATE(CLK_GPIO0, gpio0_clk, "gpio0-clk", perisys_apb_pclk_pd, 0x204, BIT(8), 0); +static CCU_GATE(CLK_GPIO1, gpio1_clk, "gpio1-clk", perisys_apb_pclk_pd, 0x204, BIT(7), 0); +static CCU_GATE(CLK_GPIO2, gpio2_clk, "gpio2-clk", peri2sys_apb_pclk_pd, 0x204, BIT(6), 0); +static CCU_GATE(CLK_I2C0, i2c0_clk, "i2c0", perisys_apb_pclk_pd, 0x204, BIT(5), 0); +static CCU_GATE(CLK_I2C1, i2c1_clk, "i2c1", perisys_apb_pclk_pd, 0x204, BIT(4), 0); +static CCU_GATE(CLK_I2C2, i2c2_clk, "i2c2", perisys_apb_pclk_pd, 0x204, BIT(3), 0); +static CCU_GATE(CLK_I2C3, i2c3_clk, "i2c3", perisys_apb_pclk_pd, 0x204, BIT(2), 0); +static CCU_GATE(CLK_I2C4, i2c4_clk, "i2c4", perisys_apb_pclk_pd, 0x204, BIT(1), 0); +static CCU_GATE(CLK_I2C5, i2c5_clk, "i2c5", perisys_apb_pclk_pd, 0x204, BIT(0), 0); +static CCU_GATE(CLK_SPINLOCK, spinlock_clk, "spinlock", ahb2_cpusys_hclk_pd, 0x208, BIT(10), 0); +static CCU_GATE(CLK_DMA, dma_clk, "dma", axi4_cpusys2_aclk_pd, 0x208, BIT(8), 0); +static CCU_GATE(CLK_MBOX0, mbox0_clk, "mbox0", apb3_cpusys_pclk_pd, 0x208, BIT(7), 0); +static CCU_GATE(CLK_MBOX1, mbox1_clk, "mbox1", apb3_cpusys_pclk_pd, 0x208, BIT(6), 0); +static CCU_GATE(CLK_MBOX2, mbox2_clk, "mbox2", apb3_cpusys_pclk_pd, 0x208, BIT(5), 0); +static CCU_GATE(CLK_MBOX3, mbox3_clk, "mbox3", apb3_cpusys_pclk_pd, 0x208, BIT(4), 0); +static CCU_GATE(CLK_WDT0, wdt0_clk, "wdt0", apb3_cpusys_pclk_pd, 0x208, BIT(3), 0); +static CCU_GATE(CLK_WDT1, wdt1_clk, "wdt1", apb3_cpusys_pclk_pd, 0x208, BIT(2), 0); +static CCU_GATE(CLK_TIMER0, timer0_clk, "timer0", apb3_cpusys_pclk_pd, 0x208, BIT(1), 0); +static CCU_GATE(CLK_TIMER1, timer1_clk, "timer1", apb3_cpusys_pclk_pd, 0x208, BIT(0), 0); +static CCU_GATE(CLK_SRAM0, sram0_clk, "sram0", axi_aclk_pd, 0x20c, BIT(4), 0); +static CCU_GATE(CLK_SRAM1, sram1_clk, "sram1", axi_aclk_pd, 0x20c, BIT(3), 0); +static CCU_GATE(CLK_SRAM2, sram2_clk, "sram2", axi_aclk_pd, 0x20c, BIT(2), 0); +static CCU_GATE(CLK_SRAM3, sram3_clk, "sram3", axi_aclk_pd, 0x20c, BIT(1), 0); + +static CLK_FIXED_FACTOR_HW(gmac_pll_clk_100m, "gmac-pll-clk-100m", + &gmac_pll_clk.common.hw, 10, 1, 0); + +static const struct clk_parent_data uart_sclk_parents[] = { + { .hw = &gmac_pll_clk_100m.hw }, + { .index = 0 }, +}; + +static struct ccu_mux uart_sclk = { + .mux = TH_CCU_ARG(0, 1), + .common = { + .clkid = CLK_UART_SCLK, + .cfg0 = 0x210, + .hw.init = CLK_HW_INIT_PARENTS_DATA("uart-sclk", + uart_sclk_parents, + &clk_mux_ops, + 0), + } +}; + +static struct ccu_common *th1520_pll_clks[] = { + &cpu_pll0_clk.common, + &cpu_pll1_clk.common, + &gmac_pll_clk.common, + &video_pll_clk.common, + &dpu0_pll_clk.common, + &dpu1_pll_clk.common, + &tee_pll_clk.common, +}; + +static struct ccu_common *th1520_div_clks[] = { + &ahb2_cpusys_hclk.common, + &apb3_cpusys_pclk.common, + &axi4_cpusys2_aclk.common, + &perisys_ahb_hclk.common, + &perisys_apb_pclk.common, + &axi_aclk.common, + &peri2sys_apb_pclk.common, + &out1_clk.common, + &out2_clk.common, + &out3_clk.common, + &out4_clk.common, + &apb_pclk.common, + &npu_clk.common, + &vi_clk.common, + &vi_ahb_clk.common, + &vo_axi_clk.common, + &vp_apb_clk.common, + &vp_axi_clk.common, + &cpu2vp_clk.common, + &venc_clk.common, + &dpu0_clk.common, + &dpu1_clk.common, +}; + +static struct ccu_common *th1520_mux_clks[] = { + &c910_i0_clk.common, + &c910_clk.common, + &uart_sclk.common, +}; + +static struct ccu_common *th1520_gate_clks[] = { + &emmc_sdio_clk.common, + &aon2cpu_a2x_clk.common, + &x2x_cpusys_clk.common, + &brom_clk.common, + &bmu_clk.common, + &cpu2aon_x2h_clk.common, + &cpu2peri_x2h_clk.common, + &perisys_apb1_hclk.common, + &perisys_apb2_hclk.common, + &perisys_apb3_hclk.common, + &perisys_apb4_hclk.common, + &npu_axi_clk.common, + &gmac1_clk.common, + &padctrl1_clk.common, + &dsmart_clk.common, + &padctrl0_clk.common, + &gmac_axi_clk.common, + &gpio3_clk.common, + &gmac0_clk.common, + &pwm_clk.common, + &qspi0_clk.common, + &qspi1_clk.common, + &spi_clk.common, + &uart0_pclk.common, + &uart1_pclk.common, + &uart2_pclk.common, + &uart3_pclk.common, + &uart4_pclk.common, + &uart5_pclk.common, + &gpio0_clk.common, + &gpio1_clk.common, + &gpio2_clk.common, + &i2c0_clk.common, + &i2c1_clk.common, + &i2c2_clk.common, + &i2c3_clk.common, + &i2c4_clk.common, + &i2c5_clk.common, + &spinlock_clk.common, + &dma_clk.common, + &mbox0_clk.common, + &mbox1_clk.common, + &mbox2_clk.common, + &mbox3_clk.common, + &wdt0_clk.common, + &wdt1_clk.common, + &timer0_clk.common, + &timer1_clk.common, + &sram0_clk.common, + &sram1_clk.common, + &sram2_clk.common, + &sram3_clk.common, +}; + +#define NR_CLKS (CLK_UART_SCLK + 1) + +static const struct regmap_config th1520_clk_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .fast_io = true, +}; + +static int th1520_clk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct clk_hw_onecell_data *priv; + + struct regmap *map; + void __iomem *base; + struct clk_hw *hw; + int ret, i; + + priv = devm_kzalloc(dev, struct_size(priv, hws, NR_CLKS), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->num = NR_CLKS; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + map = devm_regmap_init_mmio(dev, base, &th1520_clk_regmap_config); + if (IS_ERR(map)) + return PTR_ERR(map); + + for (i = 0; i < ARRAY_SIZE(th1520_pll_clks); i++) { + struct ccu_pll *cp = hw_to_ccu_pll(&th1520_pll_clks[i]->hw); + + th1520_pll_clks[i]->map = map; + + ret = devm_clk_hw_register(dev, &th1520_pll_clks[i]->hw); + if (ret) + return ret; + + priv->hws[cp->common.clkid] = &cp->common.hw; + } + + for (i = 0; i < ARRAY_SIZE(th1520_div_clks); i++) { + struct ccu_div *cd = hw_to_ccu_div(&th1520_div_clks[i]->hw); + + th1520_div_clks[i]->map = map; + + ret = devm_clk_hw_register(dev, &th1520_div_clks[i]->hw); + if (ret) + return ret; + + priv->hws[cd->common.clkid] = &cd->common.hw; + } + + for (i = 0; i < ARRAY_SIZE(th1520_mux_clks); i++) { + struct ccu_mux *cm = hw_to_ccu_mux(&th1520_mux_clks[i]->hw); + const struct clk_init_data *init = cm->common.hw.init; + + th1520_mux_clks[i]->map = map; + hw = devm_clk_hw_register_mux_parent_data_table(dev, + init->name, + init->parent_data, + init->num_parents, + 0, + base + cm->common.cfg0, + cm->mux.shift, + cm->mux.width, + 0, NULL, NULL); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + priv->hws[cm->common.clkid] = hw; + } + + for (i = 0; i < ARRAY_SIZE(th1520_gate_clks); i++) { + struct ccu_gate *cg = hw_to_ccu_gate(&th1520_gate_clks[i]->hw); + + th1520_gate_clks[i]->map = map; + + hw = devm_clk_hw_register_gate_parent_data(dev, + cg->common.hw.init->name, + cg->common.hw.init->parent_data, + 0, base + cg->common.cfg0, + ffs(cg->enable) - 1, 0, NULL); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + priv->hws[cg->common.clkid] = hw; + } + + ret = devm_clk_hw_register(dev, &osc12m_clk.hw); + if (ret) + return ret; + priv->hws[CLK_OSC12M] = &osc12m_clk.hw; + + ret = devm_clk_hw_register(dev, &gmac_pll_clk_100m.hw); + if (ret) + return ret; + priv->hws[CLK_PLL_GMAC_100M] = &gmac_pll_clk_100m.hw; + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, priv); + if (ret) + return ret; + + return 0; +} + +static const struct of_device_id th1520_clk_match[] = { + { + .compatible = "thead,th1520-clk-ap", + }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, th1520_clk_match); + +static struct platform_driver th1520_clk_driver = { + .probe = th1520_clk_probe, + .driver = { + .name = "th1520-clk", + .of_match_table = th1520_clk_match, + }, +}; +module_platform_driver(th1520_clk_driver); + +MODULE_DESCRIPTION("T-HEAD TH1520 AP Clock driver"); +MODULE_AUTHOR("Yangtao Li <frank.li@vivo.com>"); +MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>"); +MODULE_LICENSE("GPL"); |