diff options
Diffstat (limited to 'drivers/clk/qcom')
-rw-r--r-- | drivers/clk/qcom/Kconfig | 53 | ||||
-rw-r--r-- | drivers/clk/qcom/Makefile | 8 | ||||
-rw-r--r-- | drivers/clk/qcom/camcc-sdm845.c | 1745 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-alpha-pll.c | 1 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-branch.c | 2 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-hfpll.c | 244 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-hfpll.h | 44 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-krait.c | 126 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-krait.h | 40 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-rcg.h | 11 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-rcg2.c | 195 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-ipq806x.c | 82 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-msm8960.c | 172 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-msm8996.c | 152 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-qcs404.c | 2744 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-sdm660.c | 2480 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-sdm845.c | 305 | ||||
-rw-r--r-- | drivers/clk/qcom/hfpll.c | 96 | ||||
-rw-r--r-- | drivers/clk/qcom/kpss-xcc.c | 87 | ||||
-rw-r--r-- | drivers/clk/qcom/krait-cc.c | 397 |
20 files changed, 8887 insertions, 97 deletions
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 064768699fe7..a611531df115 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1,3 +1,7 @@ +config KRAIT_CLOCKS + bool + select KRAIT_L2_ACCESSORS + config QCOM_GDSC bool select PM_GENERIC_DOMAINS if PM @@ -235,6 +239,31 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config QCS_GCC_404 + tristate "QCS404 Global Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on QCS404 devices. + Say Y if you want to use multimedia devices or peripheral + devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc. + +config SDM_CAMCC_845 + tristate "SDM845 Camera Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the camera clock controller on SDM845 devices. + Say Y if you want to support camera devices and camera functionality. + +config SDM_GCC_660 + tristate "SDM660 Global Clock Controller" + select QCOM_GDSC + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on SDM660 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2C, USB, UFS, SDDC, PCIe, etc. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC @@ -272,3 +301,27 @@ config SPMI_PMIC_CLKDIV Technologies, Inc. SPMI PMIC. It configures the frequency of clkdiv outputs of the PMIC. These clocks are typically wired through alternate functions on GPIO pins. + +config QCOM_HFPLL + tristate "High-Frequency PLL (HFPLL) Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the high-frequency PLLs present on Qualcomm devices. + Say Y if you want to support CPU frequency scaling on devices + such as MSM8974, APQ8084, etc. + +config KPSS_XCC + tristate "KPSS Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the Krait ACC and GCC clock controllers. Say Y + if you want to support CPU frequency scaling on devices such + as MSM8960, APQ8064, etc. + +config KRAITCC + tristate "Krait Clock Controller" + depends on COMMON_CLK_QCOM && ARM + select KRAIT_CLOCKS + help + Support for the Krait CPU clocks on Qualcomm devices. + Say Y if you want to support CPU frequency scaling. diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 21a45035930d..981882e16189 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -11,6 +11,8 @@ clk-qcom-y += clk-branch.o clk-qcom-y += clk-regmap-divider.o clk-qcom-y += clk-regmap-mux.o clk-qcom-y += clk-regmap-mux-div.o +clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o +clk-qcom-y += clk-hfpll.o clk-qcom-y += reset.o clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o @@ -39,7 +41,13 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o +obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o +obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o +obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o +obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o +obj-$(CONFIG_QCOM_HFPLL) += hfpll.o +obj-$(CONFIG_KRAITCC) += krait-cc.o diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000000000000..1b2cefef7431 --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1745 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,camcc-sdm845.h> + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CORE_BI_PLL_TEST_SE, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const cam_cc_parent_names_0[] = { + "bi_tcxo", + "cam_cc_pll2_out_even", + "cam_cc_pll1_out_even", + "cam_cc_pll3_out_even", + "cam_cc_pll0_out_even", + "core_bi_pll_test_se", +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_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){ + .name = "cam_cc_pll0_out_even", + .parent_names = (const char *[]){ "cam_cc_pll0" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_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){ + .name = "cam_cc_pll1_out_even", + .parent_names = (const char *[]){ "cam_cc_pll1" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll2", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { + .offset = 0x2000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_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){ + .name = "cam_cc_pll2_out_even", + .parent_names = (const char *[]){ "cam_cc_pll2" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll3", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = { + .offset = 0x3000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_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){ + .name = "cam_cc_pll3_out_even", + .parent_names = (const char *[]){ "cam_cc_pll3" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(404000000, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0), + F(480000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +/* + * As per HW design, some of the CAMCC RCGs needs to + * move to XO clock during their clock disable so using + * clk_rcg2_shared_ops for such RCGs. This is required + * to power down the camera memories gracefully. + * Also, use CLK_SET_RATE_PARENT flag for the RCGs which + * have CAM_CC_PLL2_OUT_EVEN PLL as parent in frequency + * table and requires reconfiguration of the PLL frequency. + */ +static struct clk_rcg2 cam_cc_bps_clk_src = { + .cmd_rcgr = 0x600c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_bps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cci_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + F(50000000, P_CAM_CC_PLL0_OUT_EVEN, 12, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_clk_src = { + .cmd_rcgr = 0xb0d8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_cci_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { + .cmd_rcgr = 0x9060, + .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 = &(struct clk_init_data){ + .name = "cam_cc_cphy_rx_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(240000000, P_CAM_CC_PLL2_OUT_EVEN, 2, 0, 0), + F(269333333, P_CAM_CC_PLL1_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x5004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi0phytimer_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { + .cmd_rcgr = 0x5028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi1phytimer_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { + .cmd_rcgr = 0x504c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi2phytimer_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { + .cmd_rcgr = 0x5070, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi3phytimer_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(50000000, P_CAM_CC_PLL0_OUT_EVEN, 12, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { + .cmd_rcgr = 0x6038, + .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 = &(struct clk_init_data){ + .name = "cam_cc_fast_ahb_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_fd_core_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_fd_core_clk_src = { + .cmd_rcgr = 0xb0b0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fd_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_fd_core_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .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(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_clk_src = { + .cmd_rcgr = 0xb088, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_icp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .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(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(320000000, P_CAM_CC_PLL2_OUT_EVEN, 1.5, 0, 0), + F(404000000, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0), + F(480000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_0_clk_src = { + .cmd_rcgr = 0x900c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_0_csid_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(75000000, P_CAM_CC_PLL0_OUT_EVEN, 8, 0, 0), + F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = { + .cmd_rcgr = 0x9038, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_csid_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_1_clk_src = { + .cmd_rcgr = 0xa00c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = { + .cmd_rcgr = 0xa030, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_csid_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .cmd_rcgr = 0xb004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { + .cmd_rcgr = 0xb024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_csid_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ipe_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(240000000, P_CAM_CC_PLL0_OUT_EVEN, 2.5, 0, 0), + F(404000000, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0), + F(480000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_0_clk_src = { + .cmd_rcgr = 0x700c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ipe_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ipe_1_clk_src = { + .cmd_rcgr = 0x800c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ipe_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_1_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0xb04c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_bps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_jpeg_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_lrme_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(269333333, P_CAM_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(320000000, P_CAM_CC_PLL2_OUT_EVEN, 1.5, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_lrme_clk_src = { + .cmd_rcgr = 0xb0f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_lrme_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_lrme_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .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, 2), + F(33333333, P_CAM_CC_PLL0_OUT_EVEN, 2, 1, 9), + F(34285714, P_CAM_CC_PLL2_OUT_EVEN, 14, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_mclk0_clk_src = { + .cmd_rcgr = 0x4004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk0_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk1_clk_src = { + .cmd_rcgr = 0x4024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk1_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk2_clk_src = { + .cmd_rcgr = 0x4044, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk2_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk3_clk_src = { + .cmd_rcgr = 0x4064, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk3_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_CAM_CC_PLL0_OUT_EVEN, 10, 0, 0), + F(66666667, P_CAM_CC_PLL0_OUT_EVEN, 9, 0, 0), + F(73846154, P_CAM_CC_PLL2_OUT_EVEN, 6.5, 0, 0), + F(80000000, P_CAM_CC_PLL2_OUT_EVEN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { + .cmd_rcgr = 0x6054, + .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 = &(struct clk_init_data){ + .name = "cam_cc_slow_ahb_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch cam_cc_bps_ahb_clk = { + .halt_reg = 0x606c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x606c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_ahb_clk", + .parent_names = (const char *[]){ + "cam_cc_slow_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_areg_clk = { + .halt_reg = 0x6050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_areg_clk", + .parent_names = (const char *[]){ + "cam_cc_fast_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_axi_clk = { + .halt_reg = 0x6034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_clk = { + .halt_reg = 0x6024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_clk", + .parent_names = (const char *[]){ + "cam_cc_bps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_atb_clk = { + .halt_reg = 0xb12c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb12c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_camnoc_atb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_axi_clk = { + .halt_reg = 0xb124, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb124, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_camnoc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_clk = { + .halt_reg = 0xb0f0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0f0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_cci_clk", + .parent_names = (const char *[]){ + "cam_cc_cci_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ahb_clk = { + .halt_reg = 0xb11c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb11c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_cpas_ahb_clk", + .parent_names = (const char *[]){ + "cam_cc_slow_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi0phytimer_clk = { + .halt_reg = 0x501c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x501c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi0phytimer_clk", + .parent_names = (const char *[]){ + "cam_cc_csi0phytimer_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi1phytimer_clk = { + .halt_reg = 0x5040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi1phytimer_clk", + .parent_names = (const char *[]){ + "cam_cc_csi1phytimer_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi2phytimer_clk = { + .halt_reg = 0x5064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi2phytimer_clk", + .parent_names = (const char *[]){ + "cam_cc_csi2phytimer_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi3phytimer_clk = { + .halt_reg = 0x5088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5088, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi3phytimer_clk", + .parent_names = (const char *[]){ + "cam_cc_csi3phytimer_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy0_clk = { + .halt_reg = 0x5020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy0_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy1_clk = { + .halt_reg = 0x5044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy1_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy2_clk = { + .halt_reg = 0x5068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5068, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy2_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy3_clk = { + .halt_reg = 0x508c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x508c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy3_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_fd_core_clk = { + .halt_reg = 0xb0c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0c8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_fd_core_clk", + .parent_names = (const char *[]){ + "cam_cc_fd_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_fd_core_uar_clk = { + .halt_reg = 0xb0d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0d0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_fd_core_uar_clk", + .parent_names = (const char *[]){ + "cam_cc_fd_core_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_apb_clk = { + .halt_reg = 0xb084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_apb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_atb_clk = { + .halt_reg = 0xb078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb078, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_atb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_clk = { + .halt_reg = 0xb0a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0a0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_clk", + .parent_names = (const char *[]){ + "cam_cc_icp_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_cti_clk = { + .halt_reg = 0xb07c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb07c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_cti_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_ts_clk = { + .halt_reg = 0xb080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_ts_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_axi_clk = { + .halt_reg = 0x907c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x907c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_clk = { + .halt_reg = 0x9024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_cphy_rx_clk = { + .halt_reg = 0x9078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9078, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_cphy_rx_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_csid_clk = { + .halt_reg = 0x9050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_csid_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_0_csid_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_dsp_clk = { + .halt_reg = 0x9034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_dsp_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_0_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_axi_clk = { + .halt_reg = 0xa054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_clk = { + .halt_reg = 0xa024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_cphy_rx_clk = { + .halt_reg = 0xa050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_cphy_rx_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_csid_clk = { + .halt_reg = 0xa048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_csid_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_1_csid_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_dsp_clk = { + .halt_reg = 0xa02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_dsp_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_1_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_clk = { + .halt_reg = 0xb01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb01c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_lite_clk_src", + }, + .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 = 0xb044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_cphy_rx_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_csid_clk = { + .halt_reg = 0xb03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_csid_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_lite_csid_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_ahb_clk = { + .halt_reg = 0x703c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x703c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_ahb_clk", + .parent_names = (const char *[]){ + "cam_cc_slow_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_areg_clk = { + .halt_reg = 0x7038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_areg_clk", + .parent_names = (const char *[]){ + "cam_cc_fast_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_axi_clk = { + .halt_reg = 0x7034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_clk = { + .halt_reg = 0x7024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_clk", + .parent_names = (const char *[]){ + "cam_cc_ipe_0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_1_ahb_clk = { + .halt_reg = 0x803c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x803c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_1_ahb_clk", + .parent_names = (const char *[]){ + "cam_cc_slow_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_1_areg_clk = { + .halt_reg = 0x8038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_1_areg_clk", + .parent_names = (const char *[]){ + "cam_cc_fast_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_1_axi_clk = { + .halt_reg = 0x8034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_1_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_1_clk = { + .halt_reg = 0x8024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_1_clk", + .parent_names = (const char *[]){ + "cam_cc_ipe_1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_jpeg_clk = { + .halt_reg = 0xb064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_jpeg_clk", + .parent_names = (const char *[]){ + "cam_cc_jpeg_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_lrme_clk = { + .halt_reg = 0xb110, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb110, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_lrme_clk", + .parent_names = (const char *[]){ + "cam_cc_lrme_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk0_clk = { + .halt_reg = 0x401c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x401c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk0_clk", + .parent_names = (const char *[]){ + "cam_cc_mclk0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk1_clk = { + .halt_reg = 0x403c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x403c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk1_clk", + .parent_names = (const char *[]){ + "cam_cc_mclk1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk2_clk = { + .halt_reg = 0x405c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x405c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk2_clk", + .parent_names = (const char *[]){ + "cam_cc_mclk2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk3_clk = { + .halt_reg = 0x407c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x407c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk3_clk", + .parent_names = (const char *[]){ + "cam_cc_mclk3_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_soc_ahb_clk = { + .halt_reg = 0xb13c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb13c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_soc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sys_tmr_clk = { + .halt_reg = 0xb0a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0a8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_sys_tmr_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc bps_gdsc = { + .gdscr = 0x6004, + .pd = { + .name = "bps_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ipe_0_gdsc = { + .gdscr = 0x7004, + .pd = { + .name = "ipe_0_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ipe_1_gdsc = { + .gdscr = 0x8004, + .pd = { + .name = "ipe_1_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ife_0_gdsc = { + .gdscr = 0x9004, + .pd = { + .name = "ife_0_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ife_1_gdsc = { + .gdscr = 0xa004, + .pd = { + .name = "ife_1_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc titan_top_gdsc = { + .gdscr = 0xb134, + .pd = { + .name = "titan_top_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct clk_regmap *cam_cc_sdm845_clocks[] = { + [CAM_CC_BPS_AHB_CLK] = &cam_cc_bps_ahb_clk.clkr, + [CAM_CC_BPS_AREG_CLK] = &cam_cc_bps_areg_clk.clkr, + [CAM_CC_BPS_AXI_CLK] = &cam_cc_bps_axi_clk.clkr, + [CAM_CC_BPS_CLK] = &cam_cc_bps_clk.clkr, + [CAM_CC_BPS_CLK_SRC] = &cam_cc_bps_clk_src.clkr, + [CAM_CC_CAMNOC_ATB_CLK] = &cam_cc_camnoc_atb_clk.clkr, + [CAM_CC_CAMNOC_AXI_CLK] = &cam_cc_camnoc_axi_clk.clkr, + [CAM_CC_CCI_CLK] = &cam_cc_cci_clk.clkr, + [CAM_CC_CCI_CLK_SRC] = &cam_cc_cci_clk_src.clkr, + [CAM_CC_CPAS_AHB_CLK] = &cam_cc_cpas_ahb_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr, + [CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr, + [CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr, + [CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr, + [CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr, + [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr, + [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr, + [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_clk_src.clkr, + [CAM_CC_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_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, + [CAM_CC_FD_CORE_CLK] = &cam_cc_fd_core_clk.clkr, + [CAM_CC_FD_CORE_CLK_SRC] = &cam_cc_fd_core_clk_src.clkr, + [CAM_CC_FD_CORE_UAR_CLK] = &cam_cc_fd_core_uar_clk.clkr, + [CAM_CC_ICP_APB_CLK] = &cam_cc_icp_apb_clk.clkr, + [CAM_CC_ICP_ATB_CLK] = &cam_cc_icp_atb_clk.clkr, + [CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr, + [CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr, + [CAM_CC_ICP_CTI_CLK] = &cam_cc_icp_cti_clk.clkr, + [CAM_CC_ICP_TS_CLK] = &cam_cc_icp_ts_clk.clkr, + [CAM_CC_IFE_0_AXI_CLK] = &cam_cc_ife_0_axi_clk.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_CPHY_RX_CLK] = &cam_cc_ife_0_cphy_rx_clk.clkr, + [CAM_CC_IFE_0_CSID_CLK] = &cam_cc_ife_0_csid_clk.clkr, + [CAM_CC_IFE_0_CSID_CLK_SRC] = &cam_cc_ife_0_csid_clk_src.clkr, + [CAM_CC_IFE_0_DSP_CLK] = &cam_cc_ife_0_dsp_clk.clkr, + [CAM_CC_IFE_1_AXI_CLK] = &cam_cc_ife_1_axi_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_CPHY_RX_CLK] = &cam_cc_ife_1_cphy_rx_clk.clkr, + [CAM_CC_IFE_1_CSID_CLK] = &cam_cc_ife_1_csid_clk.clkr, + [CAM_CC_IFE_1_CSID_CLK_SRC] = &cam_cc_ife_1_csid_clk_src.clkr, + [CAM_CC_IFE_1_DSP_CLK] = &cam_cc_ife_1_dsp_clk.clkr, + [CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr, + [CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr, + [CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr, + [CAM_CC_IPE_0_AHB_CLK] = &cam_cc_ipe_0_ahb_clk.clkr, + [CAM_CC_IPE_0_AREG_CLK] = &cam_cc_ipe_0_areg_clk.clkr, + [CAM_CC_IPE_0_AXI_CLK] = &cam_cc_ipe_0_axi_clk.clkr, + [CAM_CC_IPE_0_CLK] = &cam_cc_ipe_0_clk.clkr, + [CAM_CC_IPE_0_CLK_SRC] = &cam_cc_ipe_0_clk_src.clkr, + [CAM_CC_IPE_1_AHB_CLK] = &cam_cc_ipe_1_ahb_clk.clkr, + [CAM_CC_IPE_1_AREG_CLK] = &cam_cc_ipe_1_areg_clk.clkr, + [CAM_CC_IPE_1_AXI_CLK] = &cam_cc_ipe_1_axi_clk.clkr, + [CAM_CC_IPE_1_CLK] = &cam_cc_ipe_1_clk.clkr, + [CAM_CC_IPE_1_CLK_SRC] = &cam_cc_ipe_1_clk_src.clkr, + [CAM_CC_JPEG_CLK] = &cam_cc_jpeg_clk.clkr, + [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr, + [CAM_CC_LRME_CLK] = &cam_cc_lrme_clk.clkr, + [CAM_CC_LRME_CLK_SRC] = &cam_cc_lrme_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_PLL0] = &cam_cc_pll0.clkr, + [CAM_CC_PLL0_OUT_EVEN] = &cam_cc_pll0_out_even.clkr, + [CAM_CC_PLL1] = &cam_cc_pll1.clkr, + [CAM_CC_PLL1_OUT_EVEN] = &cam_cc_pll1_out_even.clkr, + [CAM_CC_PLL2] = &cam_cc_pll2.clkr, + [CAM_CC_PLL2_OUT_EVEN] = &cam_cc_pll2_out_even.clkr, + [CAM_CC_PLL3] = &cam_cc_pll3.clkr, + [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr, + [CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, + [CAM_CC_SOC_AHB_CLK] = &cam_cc_soc_ahb_clk.clkr, + [CAM_CC_SYS_TMR_CLK] = &cam_cc_sys_tmr_clk.clkr, +}; + +static struct gdsc *cam_cc_sdm845_gdscs[] = { + [BPS_GDSC] = &bps_gdsc, + [IPE_0_GDSC] = &ipe_0_gdsc, + [IPE_1_GDSC] = &ipe_1_gdsc, + [IFE_0_GDSC] = &ife_0_gdsc, + [IFE_1_GDSC] = &ife_1_gdsc, + [TITAN_TOP_GDSC] = &titan_top_gdsc, +}; + +static const struct regmap_config cam_cc_sdm845_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xd004, + .fast_io = true, +}; + +static const struct qcom_cc_desc cam_cc_sdm845_desc = { + .config = &cam_cc_sdm845_regmap_config, + .clks = cam_cc_sdm845_clocks, + .num_clks = ARRAY_SIZE(cam_cc_sdm845_clocks), + .gdscs = cam_cc_sdm845_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_sdm845_gdscs), +}; + +static const struct of_device_id cam_cc_sdm845_match_table[] = { + { .compatible = "qcom,sdm845-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_sdm845_match_table); + +static int cam_cc_sdm845_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + struct alpha_pll_config cam_cc_pll_config = { }; + + regmap = qcom_cc_map(pdev, &cam_cc_sdm845_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + cam_cc_pll_config.l = 0x1f; + cam_cc_pll_config.alpha = 0x4000; + clk_fabia_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll_config); + + cam_cc_pll_config.l = 0x2a; + cam_cc_pll_config.alpha = 0x1556; + clk_fabia_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll_config); + + cam_cc_pll_config.l = 0x32; + cam_cc_pll_config.alpha = 0x0; + clk_fabia_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll_config); + + 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); +} + +static struct platform_driver cam_cc_sdm845_driver = { + .probe = cam_cc_sdm845_probe, + .driver = { + .name = "sdm845-camcc", + .of_match_table = cam_cc_sdm845_match_table, + }, +}; + +static int __init cam_cc_sdm845_init(void) +{ + return platform_driver_register(&cam_cc_sdm845_driver); +} +subsys_initcall(cam_cc_sdm845_init); + +static void __exit cam_cc_sdm845_exit(void) +{ + platform_driver_unregister(&cam_cc_sdm845_driver); +} +module_exit(cam_cc_sdm845_exit); + +MODULE_DESCRIPTION("QTI CAM_CC SDM845 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index a91d97cecbad..0ced4a5a9a17 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -220,6 +220,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, if (pll->flags & SUPPORTS_FSM_MODE) qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0); } +EXPORT_SYMBOL_GPL(clk_alpha_pll_configure); static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw) { diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c index bc2205c450b6..99446bf630aa 100644 --- a/drivers/clk/qcom/clk-branch.c +++ b/drivers/clk/qcom/clk-branch.c @@ -18,7 +18,7 @@ static bool clk_branch_in_hwcg_mode(const struct clk_branch *br) u32 val; if (!br->hwcg_reg) - return 0; + return false; regmap_read(br->clkr.regmap, br->hwcg_reg, &val); diff --git a/drivers/clk/qcom/clk-hfpll.c b/drivers/clk/qcom/clk-hfpll.c new file mode 100644 index 000000000000..3c04805f2a55 --- /dev/null +++ b/drivers/clk/qcom/clk-hfpll.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018, The Linux Foundation. All rights reserved. + +#include <linux/kernel.h> +#include <linux/export.h> +#include <linux/regmap.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/clk-provider.h> +#include <linux/spinlock.h> + +#include "clk-regmap.h" +#include "clk-hfpll.h" + +#define PLL_OUTCTRL BIT(0) +#define PLL_BYPASSNL BIT(1) +#define PLL_RESET_N BIT(2) + +/* Initialize a HFPLL at a given rate and enable it. */ +static void __clk_hfpll_init_once(struct clk_hw *hw) +{ + struct clk_hfpll *h = to_clk_hfpll(hw); + struct hfpll_data const *hd = h->d; + struct regmap *regmap = h->clkr.regmap; + + if (likely(h->init_done)) + return; + + /* Configure PLL parameters for integer mode. */ + if (hd->config_val) + regmap_write(regmap, hd->config_reg, hd->config_val); + regmap_write(regmap, hd->m_reg, 0); + regmap_write(regmap, hd->n_reg, 1); + + if (hd->user_reg) { + u32 regval = hd->user_val; + unsigned long rate; + + rate = clk_hw_get_rate(hw); + + /* Pick the right VCO. */ + if (hd->user_vco_mask && rate > hd->low_vco_max_rate) + regval |= hd->user_vco_mask; + regmap_write(regmap, hd->user_reg, regval); + } + + if (hd->droop_reg) + regmap_write(regmap, hd->droop_reg, hd->droop_val); + + h->init_done = true; +} + +static void __clk_hfpll_enable(struct clk_hw *hw) +{ + struct clk_hfpll *h = to_clk_hfpll(hw); + struct hfpll_data const *hd = h->d; + struct regmap *regmap = h->clkr.regmap; + u32 val; + + __clk_hfpll_init_once(hw); + + /* Disable PLL bypass mode. */ + regmap_update_bits(regmap, hd->mode_reg, PLL_BYPASSNL, PLL_BYPASSNL); + + /* + * H/W requires a 5us delay between disabling the bypass and + * de-asserting the reset. Delay 10us just to be safe. + */ + udelay(10); + + /* De-assert active-low PLL reset. */ + regmap_update_bits(regmap, hd->mode_reg, PLL_RESET_N, PLL_RESET_N); + + /* Wait for PLL to lock. */ + if (hd->status_reg) { + do { + regmap_read(regmap, hd->status_reg, &val); + } while (!(val & BIT(hd->lock_bit))); + } else { + udelay(60); + } + + /* Enable PLL output. */ + regmap_update_bits(regmap, hd->mode_reg, PLL_OUTCTRL, PLL_OUTCTRL); +} + +/* Enable an already-configured HFPLL. */ +static int clk_hfpll_enable(struct clk_hw *hw) +{ + unsigned long flags; + struct clk_hfpll *h = to_clk_hfpll(hw); + struct hfpll_data const *hd = h->d; + struct regmap *regmap = h->clkr.regmap; + u32 mode; + + spin_lock_irqsave(&h->lock, flags); + regmap_read(regmap, hd->mode_reg, &mode); + if (!(mode & (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL))) + __clk_hfpll_enable(hw); + spin_unlock_irqrestore(&h->lock, flags); + + return 0; +} + +static void __clk_hfpll_disable(struct clk_hfpll *h) +{ + struct hfpll_data const *hd = h->d; + struct regmap *regmap = h->clkr.regmap; + + /* + * Disable the PLL output, disable test mode, enable the bypass mode, + * and assert the reset. + */ + regmap_update_bits(regmap, hd->mode_reg, + PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL, 0); +} + +static void clk_hfpll_disable(struct clk_hw *hw) +{ + struct clk_hfpll *h = to_clk_hfpll(hw); + unsigned long flags; + + spin_lock_irqsave(&h->lock, flags); + __clk_hfpll_disable(h); + spin_unlock_irqrestore(&h->lock, flags); +} + +static long clk_hfpll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct clk_hfpll *h = to_clk_hfpll(hw); + struct hfpll_data const *hd = h->d; + unsigned long rrate; + + rate = clamp(rate, hd->min_rate, hd->max_rate); + + rrate = DIV_ROUND_UP(rate, *parent_rate) * *parent_rate; + if (rrate > hd->max_rate) + rrate -= *parent_rate; + + return rrate; +} + +/* + * For optimization reasons, assumes no downstream clocks are actively using + * it. + */ +static int clk_hfpll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_hfpll *h = to_clk_hfpll(hw); + struct hfpll_data const *hd = h->d; + struct regmap *regmap = h->clkr.regmap; + unsigned long flags; + u32 l_val, val; + bool enabled; + + l_val = rate / parent_rate; + + spin_lock_irqsave(&h->lock, flags); + + enabled = __clk_is_enabled(hw->clk); + if (enabled) + __clk_hfpll_disable(h); + + /* Pick the right VCO. */ + if (hd->user_reg && hd->user_vco_mask) { + regmap_read(regmap, hd->user_reg, &val); + if (rate <= hd->low_vco_max_rate) + val &= ~hd->user_vco_mask; + else + val |= hd->user_vco_mask; + regmap_write(regmap, hd->user_reg, val); + } + + regmap_write(regmap, hd->l_reg, l_val); + + if (enabled) + __clk_hfpll_enable(hw); + + spin_unlock_irqrestore(&h->lock, flags); + + return 0; +} + +static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_hfpll *h = to_clk_hfpll(hw); + struct hfpll_data const *hd = h->d; + struct regmap *regmap = h->clkr.regmap; + u32 l_val; + + regmap_read(regmap, hd->l_reg, &l_val); + + return l_val * parent_rate; +} + +static void clk_hfpll_init(struct clk_hw *hw) +{ + struct clk_hfpll *h = to_clk_hfpll(hw); + struct hfpll_data const *hd = h->d; + struct regmap *regmap = h->clkr.regmap; + u32 mode, status; + + regmap_read(regmap, hd->mode_reg, &mode); + if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) { + __clk_hfpll_init_once(hw); + return; + } + + if (hd->status_reg) { + regmap_read(regmap, hd->status_reg, &status); + if (!(status & BIT(hd->lock_bit))) { + WARN(1, "HFPLL %s is ON, but not locked!\n", + __clk_get_name(hw->clk)); + clk_hfpll_disable(hw); + __clk_hfpll_init_once(hw); + } + } +} + +static int hfpll_is_enabled(struct clk_hw *hw) +{ + struct clk_hfpll *h = to_clk_hfpll(hw); + struct hfpll_data const *hd = h->d; + struct regmap *regmap = h->clkr.regmap; + u32 mode; + + regmap_read(regmap, hd->mode_reg, &mode); + mode &= 0x7; + return mode == (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL); +} + +const struct clk_ops clk_ops_hfpll = { + .enable = clk_hfpll_enable, + .disable = clk_hfpll_disable, + .is_enabled = hfpll_is_enabled, + .round_rate = clk_hfpll_round_rate, + .set_rate = clk_hfpll_set_rate, + .recalc_rate = clk_hfpll_recalc_rate, + .init = clk_hfpll_init, +}; +EXPORT_SYMBOL_GPL(clk_ops_hfpll); diff --git a/drivers/clk/qcom/clk-hfpll.h b/drivers/clk/qcom/clk-hfpll.h new file mode 100644 index 000000000000..2a57b2fb2f2f --- /dev/null +++ b/drivers/clk/qcom/clk-hfpll.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __QCOM_CLK_HFPLL_H__ +#define __QCOM_CLK_HFPLL_H__ + +#include <linux/clk-provider.h> +#include <linux/spinlock.h> +#include "clk-regmap.h" + +struct hfpll_data { + u32 mode_reg; + u32 l_reg; + u32 m_reg; + u32 n_reg; + u32 user_reg; + u32 droop_reg; + u32 config_reg; + u32 status_reg; + u8 lock_bit; + + u32 droop_val; + u32 config_val; + u32 user_val; + u32 user_vco_mask; + unsigned long low_vco_max_rate; + + unsigned long min_rate; + unsigned long max_rate; +}; + +struct clk_hfpll { + struct hfpll_data const *d; + int init_done; + + struct clk_regmap clkr; + spinlock_t lock; +}; + +#define to_clk_hfpll(_hw) \ + container_of(to_clk_regmap(_hw), struct clk_hfpll, clkr) + +extern const struct clk_ops clk_ops_hfpll; + +#endif diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c new file mode 100644 index 000000000000..59f1af415b58 --- /dev/null +++ b/drivers/clk/qcom/clk-krait.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018, The Linux Foundation. All rights reserved. + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/clk-provider.h> +#include <linux/spinlock.h> + +#include <asm/krait-l2-accessors.h> + +#include "clk-krait.h" + +/* Secondary and primary muxes share the same cp15 register */ +static DEFINE_SPINLOCK(krait_clock_reg_lock); + +#define LPL_SHIFT 8 +static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel) +{ + unsigned long flags; + u32 regval; + + spin_lock_irqsave(&krait_clock_reg_lock, flags); + regval = krait_get_l2_indirect_reg(mux->offset); + regval &= ~(mux->mask << mux->shift); + regval |= (sel & mux->mask) << mux->shift; + if (mux->lpl) { + regval &= ~(mux->mask << (mux->shift + LPL_SHIFT)); + regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT); + } + krait_set_l2_indirect_reg(mux->offset, regval); + spin_unlock_irqrestore(&krait_clock_reg_lock, flags); + + /* Wait for switch to complete. */ + mb(); + udelay(1); +} + +static int krait_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct krait_mux_clk *mux = to_krait_mux_clk(hw); + u32 sel; + + sel = clk_mux_index_to_val(mux->parent_map, 0, index); + mux->en_mask = sel; + /* Don't touch mux if CPU is off as it won't work */ + if (__clk_is_enabled(hw->clk)) + __krait_mux_set_sel(mux, sel); + + mux->reparent = true; + + return 0; +} + +static u8 krait_mux_get_parent(struct clk_hw *hw) +{ + struct krait_mux_clk *mux = to_krait_mux_clk(hw); + u32 sel; + + sel = krait_get_l2_indirect_reg(mux->offset); + sel >>= mux->shift; + sel &= mux->mask; + mux->en_mask = sel; + + return clk_mux_val_to_index(hw, mux->parent_map, 0, sel); +} + +const struct clk_ops krait_mux_clk_ops = { + .set_parent = krait_mux_set_parent, + .get_parent = krait_mux_get_parent, + .determine_rate = __clk_mux_determine_rate_closest, +}; +EXPORT_SYMBOL_GPL(krait_mux_clk_ops); + +/* The divider can divide by 2, 4, 6 and 8. But we only really need div-2. */ +static long krait_div2_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), rate * 2); + return DIV_ROUND_UP(*parent_rate, 2); +} + +static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct krait_div2_clk *d = to_krait_div2_clk(hw); + unsigned long flags; + u32 val; + u32 mask = BIT(d->width) - 1; + + if (d->lpl) + mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift; + + spin_lock_irqsave(&krait_clock_reg_lock, flags); + val = krait_get_l2_indirect_reg(d->offset); + val &= ~mask; + krait_set_l2_indirect_reg(d->offset, val); + spin_unlock_irqrestore(&krait_clock_reg_lock, flags); + + return 0; +} + +static unsigned long +krait_div2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct krait_div2_clk *d = to_krait_div2_clk(hw); + u32 mask = BIT(d->width) - 1; + u32 div; + + div = krait_get_l2_indirect_reg(d->offset); + div >>= d->shift; + div &= mask; + div = (div + 1) * 2; + + return DIV_ROUND_UP(parent_rate, div); +} + +const struct clk_ops krait_div2_clk_ops = { + .round_rate = krait_div2_round_rate, + .set_rate = krait_div2_set_rate, + .recalc_rate = krait_div2_recalc_rate, +}; +EXPORT_SYMBOL_GPL(krait_div2_clk_ops); diff --git a/drivers/clk/qcom/clk-krait.h b/drivers/clk/qcom/clk-krait.h new file mode 100644 index 000000000000..9120bd2f5297 --- /dev/null +++ b/drivers/clk/qcom/clk-krait.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __QCOM_CLK_KRAIT_H +#define __QCOM_CLK_KRAIT_H + +#include <linux/clk-provider.h> + +struct krait_mux_clk { + unsigned int *parent_map; + u32 offset; + u32 mask; + u32 shift; + u32 en_mask; + bool lpl; + u8 safe_sel; + u8 old_index; + bool reparent; + + struct clk_hw hw; + struct notifier_block clk_nb; +}; + +#define to_krait_mux_clk(_hw) container_of(_hw, struct krait_mux_clk, hw) + +extern const struct clk_ops krait_mux_clk_ops; + +struct krait_div2_clk { + u32 offset; + u8 width; + u32 shift; + bool lpl; + + struct clk_hw hw; +}; + +#define to_krait_div2_clk(_hw) container_of(_hw, struct krait_div2_clk, hw) + +extern const struct clk_ops krait_div2_clk_ops; + +#endif diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index dbd5a9e83554..e5eca8a1abe4 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -163,4 +163,15 @@ extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_rcg2_shared_ops; +struct clk_rcg_dfs_data { + struct clk_rcg2 *rcg; + struct clk_init_data *init; +}; + +#define DEFINE_RCG_DFS(r) \ + { .rcg = &r##_src, .init = &r##_init } + +extern int qcom_cc_register_rcg_dfs(struct regmap *regmap, + const struct clk_rcg_dfs_data *rcgs, + size_t len); #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 52208d4165f4..6e3bd195d012 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -12,6 +12,7 @@ #include <linux/delay.h> #include <linux/regmap.h> #include <linux/math64.h> +#include <linux/slab.h> #include <asm/div64.h> @@ -40,6 +41,14 @@ #define N_REG 0xc #define D_REG 0x10 +/* Dynamic Frequency Scaling */ +#define MAX_PERF_LEVEL 8 +#define SE_CMD_DFSR_OFFSET 0x14 +#define SE_CMD_DFS_EN BIT(0) +#define SE_PERF_DFSR(level) (0x1c + 0x4 * (level)) +#define SE_PERF_M_DFSR(level) (0x5c + 0x4 * (level)) +#define SE_PERF_N_DFSR(level) (0x9c + 0x4 * (level)) + enum freq_policy { FLOOR, CEIL, @@ -929,3 +938,189 @@ const struct clk_ops clk_rcg2_shared_ops = { .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + +/* Common APIs to be used for DFS based RCGR */ +static void clk_rcg2_dfs_populate_freq(struct clk_hw *hw, unsigned int l, + struct freq_tbl *f) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + struct clk_hw *p; + unsigned long prate = 0; + u32 val, mask, cfg, mode; + int i, num_parents; + + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_DFSR(l), &cfg); + + mask = BIT(rcg->hid_width) - 1; + f->pre_div = 1; + if (cfg & mask) + f->pre_div = cfg & mask; + + cfg &= CFG_SRC_SEL_MASK; + cfg >>= CFG_SRC_SEL_SHIFT; + + num_parents = clk_hw_get_num_parents(hw); + for (i = 0; i < num_parents; i++) { + if (cfg == rcg->parent_map[i].cfg) { + f->src = rcg->parent_map[i].src; + p = clk_hw_get_parent_by_index(&rcg->clkr.hw, i); + prate = clk_hw_get_rate(p); + } + } + + mode = cfg & CFG_MODE_MASK; + mode >>= CFG_MODE_SHIFT; + if (mode) { + mask = BIT(rcg->mnd_width) - 1; + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_M_DFSR(l), + &val); + val &= mask; + f->m = val; + + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_N_DFSR(l), + &val); + val = ~val; + val &= mask; + val += f->m; + f->n = val; + } + + f->freq = calc_rate(prate, f->m, f->n, mode, f->pre_div); +} + +static int clk_rcg2_dfs_populate_freq_table(struct clk_rcg2 *rcg) +{ + struct freq_tbl *freq_tbl; + int i; + + /* Allocate space for 1 extra since table is NULL terminated */ + freq_tbl = kcalloc(MAX_PERF_LEVEL + 1, sizeof(*freq_tbl), GFP_KERNEL); + if (!freq_tbl) + return -ENOMEM; + rcg->freq_tbl = freq_tbl; + + for (i = 0; i < MAX_PERF_LEVEL; i++) + clk_rcg2_dfs_populate_freq(&rcg->clkr.hw, i, freq_tbl + i); + + return 0; +} + +static int clk_rcg2_dfs_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + int ret; + + if (!rcg->freq_tbl) { + ret = clk_rcg2_dfs_populate_freq_table(rcg); + if (ret) { + pr_err("Failed to update DFS tables for %s\n", + clk_hw_get_name(hw)); + return ret; + } + } + + return clk_rcg2_determine_rate(hw, req); +} + +static unsigned long +clk_rcg2_dfs_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + u32 level, mask, cfg, m = 0, n = 0, mode, pre_div; + + regmap_read(rcg->clkr.regmap, + rcg->cmd_rcgr + SE_CMD_DFSR_OFFSET, &level); + level &= GENMASK(4, 1); + level >>= 1; + + if (rcg->freq_tbl) + return rcg->freq_tbl[level].freq; + + /* + * Assume that parent_rate is actually the parent because + * we can't do any better at figuring it out when the table + * hasn't been populated yet. We only populate the table + * in determine_rate because we can't guarantee the parents + * will be registered with the framework until then. + */ + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_DFSR(level), + &cfg); + + mask = BIT(rcg->hid_width) - 1; + pre_div = 1; + if (cfg & mask) + pre_div = cfg & mask; + + mode = cfg & CFG_MODE_MASK; + mode >>= CFG_MODE_SHIFT; + if (mode) { + mask = BIT(rcg->mnd_width) - 1; + regmap_read(rcg->clkr.regmap, + rcg->cmd_rcgr + SE_PERF_M_DFSR(level), &m); + m &= mask; + + regmap_read(rcg->clkr.regmap, + rcg->cmd_rcgr + SE_PERF_N_DFSR(level), &n); + n = ~n; + n &= mask; + n += m; + } + + return calc_rate(parent_rate, m, n, mode, pre_div); +} + +static const struct clk_ops clk_rcg2_dfs_ops = { + .is_enabled = clk_rcg2_is_enabled, + .get_parent = clk_rcg2_get_parent, + .determine_rate = clk_rcg2_dfs_determine_rate, + .recalc_rate = clk_rcg2_dfs_recalc_rate, +}; + +static int clk_rcg2_enable_dfs(const struct clk_rcg_dfs_data *data, + struct regmap *regmap) +{ + struct clk_rcg2 *rcg = data->rcg; + struct clk_init_data *init = data->init; + u32 val; + int ret; + + ret = regmap_read(regmap, rcg->cmd_rcgr + SE_CMD_DFSR_OFFSET, &val); + if (ret) + return -EINVAL; + + if (!(val & SE_CMD_DFS_EN)) + return 0; + + /* + * Rate changes with consumer writing a register in + * their own I/O region + */ + init->flags |= CLK_GET_RATE_NOCACHE; + init->ops = &clk_rcg2_dfs_ops; + + rcg->freq_tbl = NULL; + + pr_debug("DFS registered for clk %s\n", init->name); + + return 0; +} + +int qcom_cc_register_rcg_dfs(struct regmap *regmap, + const struct clk_rcg_dfs_data *rcgs, size_t len) +{ + int i, ret; + + for (i = 0; i < len; i++) { + ret = clk_rcg2_enable_dfs(&rcgs[i], regmap); + if (ret) { + const char *name = rcgs[i].init->name; + + pr_err("DFS register failed for clk %s\n", name); + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(qcom_cc_register_rcg_dfs); diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c index 5f61225657ab..33d1bc5c6a46 100644 --- a/drivers/clk/qcom/gcc-ipq806x.c +++ b/drivers/clk/qcom/gcc-ipq806x.c @@ -30,6 +30,7 @@ #include "clk-pll.h" #include "clk-rcg.h" #include "clk-branch.h" +#include "clk-hfpll.h" #include "reset.h" static struct clk_pll pll0 = { @@ -113,6 +114,84 @@ static struct clk_regmap pll8_vote = { }, }; +static struct hfpll_data hfpll0_data = { + .mode_reg = 0x3200, + .l_reg = 0x3208, + .m_reg = 0x320c, + .n_reg = 0x3210, + .config_reg = 0x3204, + .status_reg = 0x321c, + .config_val = 0x7845c665, + .droop_reg = 0x3214, + .droop_val = 0x0108c000, + .min_rate = 600000000UL, + .max_rate = 1800000000UL, +}; + +static struct clk_hfpll hfpll0 = { + .d = &hfpll0_data, + .clkr.hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .name = "hfpll0", + .ops = &clk_ops_hfpll, + .flags = CLK_IGNORE_UNUSED, + }, + .lock = __SPIN_LOCK_UNLOCKED(hfpll0.lock), +}; + +static struct hfpll_data hfpll1_data = { + .mode_reg = 0x3240, + .l_reg = 0x3248, + .m_reg = 0x324c, + .n_reg = 0x3250, + .config_reg = 0x3244, + .status_reg = 0x325c, + .config_val = 0x7845c665, + .droop_reg = 0x3314, + .droop_val = 0x0108c000, + .min_rate = 600000000UL, + .max_rate = 1800000000UL, +}; + +static struct clk_hfpll hfpll1 = { + .d = &hfpll1_data, + .clkr.hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .name = "hfpll1", + .ops = &clk_ops_hfpll, + .flags = CLK_IGNORE_UNUSED, + }, + .lock = __SPIN_LOCK_UNLOCKED(hfpll1.lock), +}; + +static struct hfpll_data hfpll_l2_data = { + .mode_reg = 0x3300, + .l_reg = 0x3308, + .m_reg = 0x330c, + .n_reg = 0x3310, + .config_reg = 0x3304, + .status_reg = 0x331c, + .config_val = 0x7845c665, + .droop_reg = 0x3314, + .droop_val = 0x0108c000, + .min_rate = 600000000UL, + .max_rate = 1800000000UL, +}; + +static struct clk_hfpll hfpll_l2 = { + .d = &hfpll_l2_data, + .clkr.hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .name = "hfpll_l2", + .ops = &clk_ops_hfpll, + .flags = CLK_IGNORE_UNUSED, + }, + .lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock), +}; + static struct clk_pll pll14 = { .l_reg = 0x31c4, .m_reg = 0x31c8, @@ -2797,6 +2876,9 @@ static struct clk_regmap *gcc_ipq806x_clks[] = { [UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr, [NSSTCM_CLK_SRC] = &nss_tcm_src.clkr, [NSSTCM_CLK] = &nss_tcm_clk.clkr, + [PLL9] = &hfpll0.clkr, + [PLL10] = &hfpll1.clkr, + [PLL12] = &hfpll_l2.clkr, }; static const struct qcom_reset_map gcc_ipq806x_resets[] = { diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index fd495e0471bb..399474755654 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -30,6 +30,7 @@ #include "clk-pll.h" #include "clk-rcg.h" #include "clk-branch.h" +#include "clk-hfpll.h" #include "reset.h" static struct clk_pll pll3 = { @@ -86,6 +87,164 @@ static struct clk_regmap pll8_vote = { }, }; +static struct hfpll_data hfpll0_data = { + .mode_reg = 0x3200, + .l_reg = 0x3208, + .m_reg = 0x320c, + .n_reg = 0x3210, + .config_reg = 0x3204, + .status_reg = 0x321c, + .config_val = 0x7845c665, + .droop_reg = 0x3214, + .droop_val = 0x0108c000, + .min_rate = 600000000UL, + .max_rate = 1800000000UL, +}; + +static struct clk_hfpll hfpll0 = { + .d = &hfpll0_data, + .clkr.hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .name = "hfpll0", + .ops = &clk_ops_hfpll, + .flags = CLK_IGNORE_UNUSED, + }, + .lock = __SPIN_LOCK_UNLOCKED(hfpll0.lock), +}; + +static struct hfpll_data hfpll1_8064_data = { + .mode_reg = 0x3240, + .l_reg = 0x3248, + .m_reg = 0x324c, + .n_reg = 0x3250, + .config_reg = 0x3244, + .status_reg = 0x325c, + .config_val = 0x7845c665, + .droop_reg = 0x3254, + .droop_val = 0x0108c000, + .min_rate = 600000000UL, + .max_rate = 1800000000UL, +}; + +static struct hfpll_data hfpll1_data = { + .mode_reg = 0x3300, + .l_reg = 0x3308, + .m_reg = 0x330c, + .n_reg = 0x3310, + .config_reg = 0x3304, + .status_reg = 0x331c, + .config_val = 0x7845c665, + .droop_reg = 0x3314, + .droop_val = 0x0108c000, + .min_rate = 600000000UL, + .max_rate = 1800000000UL, +}; + +static struct clk_hfpll hfpll1 = { + .d = &hfpll1_data, + .clkr.hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .name = "hfpll1", + .ops = &clk_ops_hfpll, + .flags = CLK_IGNORE_UNUSED, + }, + .lock = __SPIN_LOCK_UNLOCKED(hfpll1.lock), +}; + +static struct hfpll_data hfpll2_data = { + .mode_reg = 0x3280, + .l_reg = 0x3288, + .m_reg = 0x328c, + .n_reg = 0x3290, + .config_reg = 0x3284, + .status_reg = 0x329c, + .config_val = 0x7845c665, + .droop_reg = 0x3294, + .droop_val = 0x0108c000, + .min_rate = 600000000UL, + .max_rate = 1800000000UL, +}; + +static struct clk_hfpll hfpll2 = { + .d = &hfpll2_data, + .clkr.hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .name = "hfpll2", + .ops = &clk_ops_hfpll, + .flags = CLK_IGNORE_UNUSED, + }, + .lock = __SPIN_LOCK_UNLOCKED(hfpll2.lock), +}; + +static struct hfpll_data hfpll3_data = { + .mode_reg = 0x32c0, + .l_reg = 0x32c8, + .m_reg = 0x32cc, + .n_reg = 0x32d0, + .config_reg = 0x32c4, + .status_reg = 0x32dc, + .config_val = 0x7845c665, + .droop_reg = 0x32d4, + .droop_val = 0x0108c000, + .min_rate = 600000000UL, + .max_rate = 1800000000UL, +}; + +static struct clk_hfpll hfpll3 = { + .d = &hfpll3_data, + .clkr.hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .name = "hfpll3", + .ops = &clk_ops_hfpll, + .flags = CLK_IGNORE_UNUSED, + }, + .lock = __SPIN_LOCK_UNLOCKED(hfpll3.lock), +}; + +static struct hfpll_data hfpll_l2_8064_data = { + .mode_reg = 0x3300, + .l_reg = 0x3308, + .m_reg = 0x330c, + .n_reg = 0x3310, + .config_reg = 0x3304, + .status_reg = 0x331c, + .config_val = 0x7845c665, + .droop_reg = 0x3314, + .droop_val = 0x0108c000, + .min_rate = 600000000UL, + .max_rate = 1800000000UL, +}; + +static struct hfpll_data hfpll_l2_data = { + .mode_reg = 0x3400, + .l_reg = 0x3408, + .m_reg = 0x340c, + .n_reg = 0x3410, + .config_reg = 0x3404, + .status_reg = 0x341c, + .config_val = 0x7845c665, + .droop_reg = 0x3414, + .droop_val = 0x0108c000, + .min_rate = 600000000UL, + .max_rate = 1800000000UL, +}; + +static struct clk_hfpll hfpll_l2 = { + .d = &hfpll_l2_data, + .clkr.hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .name = "hfpll_l2", + .ops = &clk_ops_hfpll, + .flags = CLK_IGNORE_UNUSED, + }, + .lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock), +}; + static struct clk_pll pll14 = { .l_reg = 0x31c4, .m_reg = 0x31c8, @@ -3107,6 +3266,9 @@ static struct clk_regmap *gcc_msm8960_clks[] = { [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr, [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr, [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr, + [PLL9] = &hfpll0.clkr, + [PLL10] = &hfpll1.clkr, + [PLL12] = &hfpll_l2.clkr, }; static const struct qcom_reset_map gcc_msm8960_resets[] = { @@ -3318,6 +3480,11 @@ static struct clk_regmap *gcc_apq8064_clks[] = { [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr, [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr, [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr, + [PLL9] = &hfpll0.clkr, + [PLL10] = &hfpll1.clkr, + [PLL12] = &hfpll_l2.clkr, + [PLL16] = &hfpll2.clkr, + [PLL17] = &hfpll3.clkr, }; static const struct qcom_reset_map gcc_apq8064_resets[] = { @@ -3477,6 +3644,11 @@ static int gcc_msm8960_probe(struct platform_device *pdev) if (ret) return ret; + if (match->data == &gcc_apq8064_desc) { + hfpll1.d = &hfpll1_8064_data; + hfpll_l2.d = &hfpll_l2_8064_data; + } + tsens = platform_device_register_data(&pdev->dev, "qcom-tsens", -1, NULL, 0); if (IS_ERR(tsens)) diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index 9a3290fdd01b..9d136172c27c 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -260,6 +260,36 @@ static struct clk_alpha_pll_postdiv gpll0 = { }, }; +static struct clk_branch gcc_mmss_gpll0_div_clk = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_gpll0_div_clk", + .parent_names = (const char *[]){ "gpll0" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_gpll0_div_clk = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_gpll0_div_clk", + .parent_names = (const char *[]){ "gpll0" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops + }, + }, +}; + static struct clk_alpha_pll gpll4_early = { .offset = 0x77000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], @@ -2951,6 +2981,20 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = { }, }; +static struct clk_branch gcc_aggre1_pnoc_ahb_clk = { + .halt_reg = 0x82014, + .clkr = { + .enable_reg = 0x82014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre1_pnoc_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_aggre2_ufs_axi_clk = { .halt_reg = 0x83014, .clkr = { @@ -2981,6 +3025,34 @@ static struct clk_branch gcc_aggre2_usb3_axi_clk = { }, }; +static struct clk_branch gcc_dcc_ahb_clk = { + .halt_reg = 0x84004, + .clkr = { + .enable_reg = 0x84004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcc_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre0_noc_mpu_cfg_ahb_clk = { + .halt_reg = 0x85000, + .clkr = { + .enable_reg = 0x85000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre0_noc_mpu_cfg_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_qspi_ahb_clk = { .halt_reg = 0x8b004, .clkr = { @@ -3039,6 +3111,20 @@ static struct clk_branch gcc_hdmi_clkref_clk = { }, }; +static struct clk_branch gcc_edp_clkref_clk = { + .halt_reg = 0x88004, + .clkr = { + .enable_reg = 0x88004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_edp_clkref_clk", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_ufs_clkref_clk = { .halt_reg = 0x88008, .clkr = { @@ -3095,6 +3181,62 @@ static struct clk_branch gcc_rx1_usb2_clkref_clk = { }, }; +static struct clk_branch gcc_mss_cfg_ahb_clk = { + .halt_reg = 0x8a000, + .clkr = { + .enable_reg = 0x8a000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_cfg_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = { + .halt_reg = 0x8a004, + .clkr = { + .enable_reg = 0x8a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_mnoc_bimc_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_snoc_axi_clk = { + .halt_reg = 0x8a024, + .clkr = { + .enable_reg = 0x8a024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_snoc_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .halt_reg = 0x8a028, + .clkr = { + .enable_reg = 0x8a028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_bimc_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_hw *gcc_msm8996_hws[] = { &xo.hw, &gpll0_early_div.hw, @@ -3355,6 +3497,7 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GCC_AGGRE0_CNOC_AHB_CLK] = &gcc_aggre0_cnoc_ahb_clk.clkr, [GCC_SMMU_AGGRE0_AXI_CLK] = &gcc_smmu_aggre0_axi_clk.clkr, [GCC_SMMU_AGGRE0_AHB_CLK] = &gcc_smmu_aggre0_ahb_clk.clkr, + [GCC_AGGRE1_PNOC_AHB_CLK] = &gcc_aggre1_pnoc_ahb_clk.clkr, [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr, [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr, [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr, @@ -3365,6 +3508,15 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GCC_PCIE_CLKREF_CLK] = &gcc_pcie_clkref_clk.clkr, [GCC_RX2_USB2_CLKREF_CLK] = &gcc_rx2_usb2_clkref_clk.clkr, [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr, + [GCC_EDP_CLKREF_CLK] = &gcc_edp_clkref_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, + [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr, + [GCC_DCC_AHB_CLK] = &gcc_dcc_ahb_clk.clkr, + [GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK] = &gcc_aggre0_noc_mpu_cfg_ahb_clk.clkr, + [GCC_MMSS_GPLL0_DIV_CLK] = &gcc_mmss_gpll0_div_clk.clkr, + [GCC_MSS_GPLL0_DIV_CLK] = &gcc_mss_gpll0_div_clk.clkr, }; static struct gdsc *gcc_msm8996_gdscs[] = { diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c new file mode 100644 index 000000000000..e4ca6a45f313 --- /dev/null +++ b/drivers/clk/qcom/gcc-qcs404.c @@ -0,0 +1,2744 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> + +#include <dt-bindings/clock/qcom,gcc-qcs404.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "reset.h" + +enum { + P_CORE_BI_PLL_TEST_SE, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_GPLL0_OUT_AUX, + P_GPLL0_OUT_MAIN, + P_GPLL1_OUT_MAIN, + P_GPLL3_OUT_MAIN, + P_GPLL4_OUT_AUX, + P_GPLL4_OUT_MAIN, + P_GPLL6_OUT_AUX, + P_HDMI_PHY_PLL_CLK, + P_PCIE_0_PIPE_CLK, + P_SLEEP_CLK, + P_XO, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_0[] = { + "cxo", + "gpll0_out_main", + "core_bi_pll_test_se", +}; + +static const char * const gcc_parent_names_ao_0[] = { + "cxo", + "gpll0_ao_out_main", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_XO, 0 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_1[] = { + "cxo", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL6_OUT_AUX, 2 }, + { P_SLEEP_CLK, 6 }, +}; + +static const char * const gcc_parent_names_2[] = { + "cxo", + "gpll0_out_main", + "gpll6_out_aux", + "sleep_clk", +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL6_OUT_AUX, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_3[] = { + "cxo", + "gpll0_out_main", + "gpll6_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_XO, 0 }, + { P_GPLL1_OUT_MAIN, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_4[] = { + "cxo", + "gpll1_out_main", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_XO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, + { P_GPLL0_OUT_AUX, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_5[] = { + "cxo", + "dsi0pll_byteclk_src", + "gpll0_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_XO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_GPLL0_OUT_AUX, 3 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_6[] = { + "cxo", + "dsi0_phy_pll_out_byteclk", + "gpll0_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_7[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL3_OUT_MAIN, 2 }, + { P_GPLL6_OUT_AUX, 3 }, + { P_GPLL4_OUT_AUX, 4 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_7[] = { + "cxo", + "gpll0_out_main", + "gpll3_out_main", + "gpll6_out_aux", + "gpll4_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_8[] = { + { P_XO, 0 }, + { P_HDMI_PHY_PLL_CLK, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_8[] = { + "cxo", + "hdmi_phy_pll_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_9[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 2 }, + { P_GPLL6_OUT_AUX, 3 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_9[] = { + "cxo", + "gpll0_out_main", + "dsi0_phy_pll_out_dsiclk", + "gpll6_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_10[] = { + { P_XO, 0 }, + { P_SLEEP_CLK, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_10[] = { + "cxo", + "sleep_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_11[] = { + { P_XO, 0 }, + { P_PCIE_0_PIPE_CLK, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_11[] = { + "cxo", + "pcie_0_pipe_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_12[] = { + { P_XO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_GPLL0_OUT_AUX, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_12[] = { + "cxo", + "dsi0pll_pclk_src", + "gpll0_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_13[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL4_OUT_MAIN, 2 }, + { P_GPLL6_OUT_AUX, 3 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_13[] = { + "cxo", + "gpll0_out_main", + "gpll4_out_main", + "gpll6_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_14[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL4_OUT_AUX, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_14[] = { + "cxo", + "gpll0_out_main", + "gpll4_out_aux", + "core_bi_pll_test_se", +}; + +static const struct parent_map gcc_parent_map_15[] = { + { P_XO, 0 }, + { P_GPLL0_OUT_AUX, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const gcc_parent_names_15[] = { + "cxo", + "gpll0_out_aux", + "core_bi_pll_test_se", +}; + +static struct clk_fixed_factor cxo = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "cxo", + .parent_names = (const char *[]){ "xo_board" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll0_sleep_clk_src = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x45008, + .enable_mask = BIT(23), + .enable_is_inverted = true, + .hw.init = &(struct clk_init_data){ + .name = "gpll0_sleep_clk_src", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll0_out_main = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .flags = SUPPORTS_FSM_MODE, + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_out_main", + .parent_names = (const char *[]) + { "gpll0_sleep_clk_src" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll0_ao_out_main = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .flags = SUPPORTS_FSM_MODE, + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_ao_out_main", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll1_out_main = { + .offset = 0x20000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gpll1_out_main", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +/* 930MHz configuration */ +static const struct alpha_pll_config gpll3_config = { + .l = 48, + .alpha = 0x0, + .alpha_en_mask = BIT(24), + .post_div_mask = 0xf << 8, + .post_div_val = 0x1 << 8, + .vco_mask = 0x3 << 20, + .main_output_mask = 0x1, + .config_ctl_val = 0x4001055b, +}; + +static const struct pll_vco gpll3_vco[] = { + { 700000000, 1400000000, 0 }, +}; + +static struct clk_alpha_pll gpll3_out_main = { + .offset = 0x22000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .vco_table = gpll3_vco, + .num_vco = ARRAY_SIZE(gpll3_vco), + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpll3_out_main", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll4_out_main = { + .offset = 0x24000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gpll4_out_main", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_pll gpll6 = { + .l_reg = 0x37004, + .m_reg = 0x37008, + .n_reg = 0x3700C, + .config_reg = 0x37014, + .mode_reg = 0x37000, + .status_reg = 0x3701C, + .status_bit = 17, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll6", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap gpll6_out_aux = { + .enable_reg = 0x45000, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gpll6_out_aux", + .parent_names = (const char *[]){ "gpll6" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static const struct freq_tbl ftbl_apss_ahb_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 apss_ahb_clk_src = { + .cmd_rcgr = 0x46000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_apss_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "apss_ahb_clk_src", + .parent_names = gcc_parent_names_ao_0, + .num_parents = 3, + .flags = CLK_IS_CRITICAL, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup0_i2c_apps_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup0_i2c_apps_clk_src = { + .cmd_rcgr = 0x602c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup0_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup0_spi_apps_clk_src[] = { + F(960000, P_XO, 10, 1, 2), + F(4800000, P_XO, 4, 0, 0), + F(9600000, P_XO, 2, 0, 0), + F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup0_spi_apps_clk_src = { + .cmd_rcgr = 0x6034, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup0_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x200c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup1_spi_apps_clk_src[] = { + F(960000, P_XO, 10, 1, 2), + F(4800000, P_XO, 4, 0, 0), + F(9600000, P_XO, 2, 0, 0), + F(10480000, P_GPLL0_OUT_MAIN, 1, 3, 229), + F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(20961000, P_GPLL0_OUT_MAIN, 1, 6, 229), + { } +}; + +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x2024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x3000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup2_spi_apps_clk_src[] = { + F(960000, P_XO, 10, 1, 2), + F(4800000, P_XO, 4, 0, 0), + F(9600000, P_XO, 2, 0, 0), + F(15000000, P_GPLL0_OUT_MAIN, 1, 3, 160), + F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2), + F(30000000, P_GPLL0_OUT_MAIN, 1, 3, 80), + { } +}; + +static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x3014, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup2_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x4000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x4024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x5000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x5024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_uart0_apps_clk_src[] = { + F(3686400, P_GPLL0_OUT_MAIN, 1, 72, 15625), + F(7372800, P_GPLL0_OUT_MAIN, 1, 144, 15625), + F(14745600, P_GPLL0_OUT_MAIN, 1, 288, 15625), + F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0_OUT_MAIN, 1, 3, 100), + F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2), + F(32000000, P_GPLL0_OUT_MAIN, 1, 1, 25), + F(40000000, P_GPLL0_OUT_MAIN, 1, 1, 20), + F(46400000, P_GPLL0_OUT_MAIN, 1, 29, 500), + F(48000000, P_GPLL0_OUT_MAIN, 1, 3, 50), + F(51200000, P_GPLL0_OUT_MAIN, 1, 8, 125), + F(56000000, P_GPLL0_OUT_MAIN, 1, 7, 100), + F(58982400, P_GPLL0_OUT_MAIN, 1, 1152, 15625), + F(60000000, P_GPLL0_OUT_MAIN, 1, 3, 40), + F(64000000, P_GPLL0_OUT_MAIN, 1, 2, 25), + { } +}; + +static struct clk_rcg2 blsp1_uart0_apps_clk_src = { + .cmd_rcgr = 0x600c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart0_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x2044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart1_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .cmd_rcgr = 0x3034, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart2_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart3_apps_clk_src = { + .cmd_rcgr = 0x4014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart3_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup0_i2c_apps_clk_src = { + .cmd_rcgr = 0xc00c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup0_i2c_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup0_spi_apps_clk_src = { + .cmd_rcgr = 0xc024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup0_spi_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart0_apps_clk_src = { + .cmd_rcgr = 0xc044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart0_apps_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 byte0_clk_src = { + .cmd_rcgr = 0x4d044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte0_clk_src", + .parent_names = gcc_parent_names_5, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static const struct freq_tbl ftbl_emac_clk_src[] = { + F(5000000, P_GPLL1_OUT_MAIN, 2, 1, 50), + F(50000000, P_GPLL1_OUT_MAIN, 10, 0, 0), + F(125000000, P_GPLL1_OUT_MAIN, 4, 0, 0), + F(250000000, P_GPLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 emac_clk_src = { + .cmd_rcgr = 0x4e01c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_emac_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "emac_clk_src", + .parent_names = gcc_parent_names_4, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_emac_ptp_clk_src[] = { + F(50000000, P_GPLL1_OUT_MAIN, 10, 0, 0), + F(125000000, P_GPLL1_OUT_MAIN, 4, 0, 0), + F(250000000, P_GPLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 emac_ptp_clk_src = { + .cmd_rcgr = 0x4e014, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_emac_ptp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "emac_ptp_clk_src", + .parent_names = gcc_parent_names_4, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_esc0_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 esc0_clk_src = { + .cmd_rcgr = 0x4d05c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc0_clk_src", + .parent_names = gcc_parent_names_6, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gfx3d_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(228571429, P_GPLL0_OUT_MAIN, 3.5, 0, 0), + F(240000000, P_GPLL6_OUT_AUX, 4.5, 0, 0), + F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(270000000, P_GPLL6_OUT_AUX, 4, 0, 0), + F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + F(400000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + F(484800000, P_GPLL3_OUT_MAIN, 1, 0, 0), + F(523200000, P_GPLL3_OUT_MAIN, 1, 0, 0), + F(550000000, P_GPLL3_OUT_MAIN, 1, 0, 0), + F(598000000, P_GPLL3_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gfx3d_clk_src = { + .cmd_rcgr = 0x59000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gfx3d_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk_src", + .parent_names = gcc_parent_names_7, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gp1_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x8004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_names = gcc_parent_names_2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x9004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_names = gcc_parent_names_2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0xa004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_names = gcc_parent_names_2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 hdmi_app_clk_src = { + .cmd_rcgr = 0x4d0e4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hdmi_app_clk_src", + .parent_names = gcc_parent_names_1, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 hdmi_pclk_clk_src = { + .cmd_rcgr = 0x4d0dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hdmi_pclk_clk_src", + .parent_names = gcc_parent_names_8, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_mdp_clk_src[] = { + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(145454545, P_GPLL0_OUT_MAIN, 5.5, 0, 0), + F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0), + F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 mdp_clk_src = { + .cmd_rcgr = 0x4d014, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_mdp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mdp_clk_src", + .parent_names = gcc_parent_names_9, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_pcie_0_aux_clk_src[] = { + F(1200000, P_XO, 16, 0, 0), + { } +}; + +static struct clk_rcg2 pcie_0_aux_clk_src = { + .cmd_rcgr = 0x3e024, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_10, + .freq_tbl = ftbl_pcie_0_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pcie_0_aux_clk_src", + .parent_names = gcc_parent_names_10, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_pcie_0_pipe_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(125000000, P_PCIE_0_PIPE_CLK, 2, 0, 0), + F(250000000, P_PCIE_0_PIPE_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 pcie_0_pipe_clk_src = { + .cmd_rcgr = 0x3e01c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_11, + .freq_tbl = ftbl_pcie_0_pipe_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pcie_0_pipe_clk_src", + .parent_names = gcc_parent_names_11, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 pclk0_clk_src = { + .cmd_rcgr = 0x4d000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_12, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk0_clk_src", + .parent_names = gcc_parent_names_12, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static const struct freq_tbl ftbl_pdm2_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(64000000, P_GPLL0_OUT_MAIN, 12.5, 0, 0), + { } +}; + +static struct clk_rcg2 pdm2_clk_src = { + .cmd_rcgr = 0x44010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_pdm2_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pdm2_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc1_apps_clk_src[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0_OUT_MAIN, 10, 1, 4), + F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(192000000, P_GPLL4_OUT_MAIN, 6, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(384000000, P_GPLL4_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x42004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_13, + .freq_tbl = ftbl_sdcc1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_names = gcc_parent_names_13, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc1_ice_core_clk_src[] = { + F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0), + F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x5d000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_sdcc1_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_ice_core_clk_src", + .parent_names = gcc_parent_names_3, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc2_apps_clk_src[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0_OUT_MAIN, 10, 1, 4), + F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2), + F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc2_apps_clk_src = { + .cmd_rcgr = 0x43004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_14, + .freq_tbl = ftbl_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc2_apps_clk_src", + .parent_names = gcc_parent_names_14, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 usb20_mock_utmi_clk_src = { + .cmd_rcgr = 0x41048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb20_mock_utmi_clk_src", + .parent_names = gcc_parent_names_1, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb30_master_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 usb30_master_clk_src = { + .cmd_rcgr = 0x39028, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_usb30_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_master_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 usb30_mock_utmi_clk_src = { + .cmd_rcgr = 0x3901c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_mock_utmi_clk_src", + .parent_names = gcc_parent_names_1, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 usb3_phy_aux_clk_src = { + .cmd_rcgr = 0x3903c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_pcie_0_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb3_phy_aux_clk_src", + .parent_names = gcc_parent_names_1, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb_hs_system_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + { } +}; + +static struct clk_rcg2 usb_hs_system_clk_src = { + .cmd_rcgr = 0x41010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_usb_hs_system_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hs_system_clk_src", + .parent_names = gcc_parent_names_3, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 vsync_clk_src = { + .cmd_rcgr = 0x4d02c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_15, + .freq_tbl = ftbl_esc0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vsync_clk_src", + .parent_names = gcc_parent_names_15, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_apss_ahb_clk = { + .halt_reg = 0x4601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_ahb_clk", + .parent_names = (const char *[]){ + "apss_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_apss_tcu_clk = { + .halt_reg = 0x5b004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_tcu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_gfx_clk = { + .halt_reg = 0x59034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x59034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_gfx_clk", + .ops = &clk_branch2_ops, + .parent_names = (const char *[]){ + "gcc_apss_tcu_clk", + }, + + }, + }, +}; + +static struct clk_branch gcc_bimc_gpu_clk = { + .halt_reg = 0x59030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x59030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_gpu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_mdss_clk = { + .halt_reg = 0x31038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x31038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_mdss_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x1008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_dcc_clk = { + .halt_reg = 0x77004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x77004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_dcc_xo_clk = { + .halt_reg = 0x77008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x77008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcc_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup0_i2c_apps_clk = { + .halt_reg = 0x6028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup0_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup0_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup0_spi_apps_clk = { + .halt_reg = 0x6024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup0_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup0_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x2008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { + .halt_reg = 0x2004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { + .halt_reg = 0x3010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { + .halt_reg = 0x300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = { + .halt_reg = 0x4020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup3_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = { + .halt_reg = 0x401c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x401c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup3_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = { + .halt_reg = 0x5020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup4_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = { + .halt_reg = 0x501c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x501c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup4_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart0_apps_clk = { + .halt_reg = 0x6004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart0_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart0_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart1_apps_clk = { + .halt_reg = 0x203c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x203c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart1_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart1_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart2_apps_clk = { + .halt_reg = 0x302c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x302c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart2_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart2_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart3_apps_clk = { + .halt_reg = 0x400c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x400c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart3_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart3_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_ahb_clk = { + .halt_reg = 0xb008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(20), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup0_i2c_apps_clk = { + .halt_reg = 0xc008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup0_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup0_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup0_spi_apps_clk = { + .halt_reg = 0xc004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup0_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup0_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart0_apps_clk = { + .halt_reg = 0xc03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart0_apps_clk", + .parent_names = (const char *[]){ + "blsp2_uart0_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x1300c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_ahb_clk = { + .halt_reg = 0x16024, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_axi_clk = { + .halt_reg = 0x16020, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_clk = { + .halt_reg = 0x1601c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eth_axi_clk = { + .halt_reg = 0x4e010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4e010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_eth_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eth_ptp_clk = { + .halt_reg = 0x4e004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4e004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_eth_ptp_clk", + .parent_names = (const char *[]){ + "emac_ptp_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eth_rgmii_clk = { + .halt_reg = 0x4e008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4e008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_eth_rgmii_clk", + .parent_names = (const char *[]){ + "emac_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eth_slave_ahb_clk = { + .halt_reg = 0x4e00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4e00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_eth_slave_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_geni_ir_s_clk = { + .halt_reg = 0xf008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_geni_ir_s_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_geni_ir_h_clk = { + .halt_reg = 0xf004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_geni_ir_h_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gfx_tcu_clk = { + .halt_reg = 0x12020, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4500C, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gfx_tcu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gfx_tbu_clk = { + .halt_reg = 0x12010, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4500C, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gfx_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x8000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_names = (const char *[]){ + "gp1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x9000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_names = (const char *[]){ + "gp2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0xa000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_names = (const char *[]){ + "gp3_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gtcu_ahb_clk = { + .halt_reg = 0x12044, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gtcu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdp_tbu_clk = { + .halt_reg = 0x1201c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdp_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_ahb_clk = { + .halt_reg = 0x4d07c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d07c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_axi_clk = { + .halt_reg = 0x4d080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_byte0_clk = { + .halt_reg = 0x4d094, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d094, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_byte0_clk", + .parent_names = (const char *[]){ + "byte0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_esc0_clk = { + .halt_reg = 0x4d098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_esc0_clk", + .parent_names = (const char *[]){ + "esc0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_hdmi_app_clk = { + .halt_reg = 0x4d0d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d0d8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_hdmi_app_clk", + .parent_names = (const char *[]){ + "hdmi_app_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_hdmi_pclk_clk = { + .halt_reg = 0x4d0d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d0d4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_hdmi_pclk_clk", + .parent_names = (const char *[]){ + "hdmi_pclk_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_mdp_clk = { + .halt_reg = 0x4d088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d088, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_mdp_clk", + .parent_names = (const char *[]){ + "mdp_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_pclk0_clk = { + .halt_reg = 0x4d084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_pclk0_clk", + .parent_names = (const char *[]){ + "pclk0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdss_vsync_clk = { + .halt_reg = 0x4d090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d090, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_vsync_clk", + .parent_names = (const char *[]){ + "vsync_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_oxili_ahb_clk = { + .halt_reg = 0x59028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x59028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_oxili_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_oxili_gfx3d_clk = { + .halt_reg = 0x59020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x59020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_oxili_gfx3d_clk", + .parent_names = (const char *[]){ + "gfx3d_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_aux_clk = { + .halt_reg = 0x3e014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(27), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_aux_clk", + .parent_names = (const char *[]){ + "pcie_0_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { + .halt_reg = 0x3e008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_mstr_axi_clk = { + .halt_reg = 0x3e018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_pipe_clk = { + .halt_reg = 0x3e00c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(28), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_pipe_clk", + .parent_names = (const char *[]){ + "pcie_0_pipe_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_axi_clk = { + .halt_reg = 0x3e010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcnoc_usb2_clk = { + .halt_reg = 0x27008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x27008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcnoc_usb2_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcnoc_usb3_clk = { + .halt_reg = 0x2700c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2700c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcnoc_usb3_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x4400c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4400c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_names = (const char *[]){ + "pdm2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x44004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x44004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x13004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* PWM clks do not have XO as parent as src clk is a balance root */ +static struct clk_branch gcc_pwm0_xo512_clk = { + .halt_reg = 0x44018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x44018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pwm0_xo512_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pwm1_xo512_clk = { + .halt_reg = 0x49004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x49004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pwm1_xo512_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pwm2_xo512_clk = { + .halt_reg = 0x4a004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pwm2_xo512_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qdss_dap_clk = { + .halt_reg = 0x29084, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qdss_dap_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x4201c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4201c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x42018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x42018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_names = (const char *[]){ + "sdcc1_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x5d014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5d014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk", + .parent_names = (const char *[]){ + "sdcc1_ice_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x4301c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4301c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x43018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x43018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_names = (const char *[]){ + "sdcc2_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_smmu_cfg_clk = { + .halt_reg = 0x12038, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x3600C, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "gcc_smmu_cfg_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_usb3_clk = { + .halt_reg = 0x26014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x26014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_usb3_clk", + .parent_names = (const char *[]){ + "usb30_master_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_inactivity_timers_clk = { + .halt_reg = 0x4100C, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4100C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_inactivity_timers_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_mock_utmi_clk = { + .halt_reg = 0x41044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x41044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb20_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb20_mock_utmi_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2a_phy_sleep_clk = { + .halt_reg = 0x4102c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4102c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2a_phy_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_master_clk = { + .halt_reg = 0x3900c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3900c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_master_clk", + .parent_names = (const char *[]){ + "usb30_master_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_mock_utmi_clk = { + .halt_reg = 0x39014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb30_mock_utmi_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sleep_clk = { + .halt_reg = 0x39010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_phy_aux_clk = { + .halt_reg = 0x39044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_phy_aux_clk", + .parent_names = (const char *[]){ + "usb3_phy_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_phy_pipe_clk = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x39018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_phy_cfg_ahb_clk = { + .halt_reg = 0x41030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x41030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_phy_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_system_clk = { + .halt_reg = 0x41004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x41004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_system_clk", + .parent_names = (const char *[]){ + "usb_hs_system_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_hw *gcc_qcs404_hws[] = { + &cxo.hw, +}; + +static struct clk_regmap *gcc_qcs404_clocks[] = { + [GCC_APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr, + [GCC_BLSP1_QUP0_I2C_APPS_CLK_SRC] = &blsp1_qup0_i2c_apps_clk_src.clkr, + [GCC_BLSP1_QUP0_SPI_APPS_CLK_SRC] = &blsp1_qup0_spi_apps_clk_src.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [GCC_BLSP1_UART0_APPS_CLK_SRC] = &blsp1_uart0_apps_clk_src.clkr, + [GCC_BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [GCC_BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [GCC_BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr, + [GCC_BLSP2_QUP0_I2C_APPS_CLK_SRC] = &blsp2_qup0_i2c_apps_clk_src.clkr, + [GCC_BLSP2_QUP0_SPI_APPS_CLK_SRC] = &blsp2_qup0_spi_apps_clk_src.clkr, + [GCC_BLSP2_UART0_APPS_CLK_SRC] = &blsp2_uart0_apps_clk_src.clkr, + [GCC_BYTE0_CLK_SRC] = &byte0_clk_src.clkr, + [GCC_EMAC_CLK_SRC] = &emac_clk_src.clkr, + [GCC_EMAC_PTP_CLK_SRC] = &emac_ptp_clk_src.clkr, + [GCC_ESC0_CLK_SRC] = &esc0_clk_src.clkr, + [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr, + [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, + [GCC_BIMC_MDSS_CLK] = &gcc_bimc_mdss_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_QUP0_I2C_APPS_CLK] = &gcc_blsp1_qup0_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP0_SPI_APPS_CLK] = &gcc_blsp1_qup0_spi_apps_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_UART0_APPS_CLK] = &gcc_blsp1_uart0_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr, + [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr, + [GCC_BLSP2_QUP0_I2C_APPS_CLK] = &gcc_blsp2_qup0_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP0_SPI_APPS_CLK] = &gcc_blsp2_qup0_spi_apps_clk.clkr, + [GCC_BLSP2_UART0_APPS_CLK] = &gcc_blsp2_uart0_apps_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_ETH_AXI_CLK] = &gcc_eth_axi_clk.clkr, + [GCC_ETH_PTP_CLK] = &gcc_eth_ptp_clk.clkr, + [GCC_ETH_RGMII_CLK] = &gcc_eth_rgmii_clk.clkr, + [GCC_ETH_SLAVE_AHB_CLK] = &gcc_eth_slave_ahb_clk.clkr, + [GCC_GENI_IR_S_CLK] = &gcc_geni_ir_s_clk.clkr, + [GCC_GENI_IR_H_CLK] = &gcc_geni_ir_h_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_MDSS_AHB_CLK] = &gcc_mdss_ahb_clk.clkr, + [GCC_MDSS_AXI_CLK] = &gcc_mdss_axi_clk.clkr, + [GCC_MDSS_BYTE0_CLK] = &gcc_mdss_byte0_clk.clkr, + [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr, + [GCC_MDSS_HDMI_APP_CLK] = &gcc_mdss_hdmi_app_clk.clkr, + [GCC_MDSS_HDMI_PCLK_CLK] = &gcc_mdss_hdmi_pclk_clk.clkr, + [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr, + [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr, + [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr, + [GCC_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr, + [GCC_OXILI_GFX3D_CLK] = &gcc_oxili_gfx3d_clk.clkr, + [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr, + [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr, + [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr, + [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr, + [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr, + [GCC_PCNOC_USB2_CLK] = &gcc_pcnoc_usb2_clk.clkr, + [GCC_PCNOC_USB3_CLK] = &gcc_pcnoc_usb3_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_PWM0_XO512_CLK] = &gcc_pwm0_xo512_clk.clkr, + [GCC_PWM1_XO512_CLK] = &gcc_pwm1_xo512_clk.clkr, + [GCC_PWM2_XO512_CLK] = &gcc_pwm2_xo512_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SYS_NOC_USB3_CLK] = &gcc_sys_noc_usb3_clk.clkr, + [GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr, + [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr, + [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr, + [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr, + [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr, + [GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr, + [GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr, + [GCC_USB_HS_PHY_CFG_AHB_CLK] = &gcc_usb_hs_phy_cfg_ahb_clk.clkr, + [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr, + [GCC_GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr, + [GCC_GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GCC_GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GCC_GP3_CLK_SRC] = &gp3_clk_src.clkr, + [GCC_GPLL0_OUT_MAIN] = &gpll0_out_main.clkr, + [GCC_GPLL0_AO_OUT_MAIN] = &gpll0_ao_out_main.clkr, + [GCC_GPLL0_SLEEP_CLK_SRC] = &gpll0_sleep_clk_src.clkr, + [GCC_GPLL1_OUT_MAIN] = &gpll1_out_main.clkr, + [GCC_GPLL3_OUT_MAIN] = &gpll3_out_main.clkr, + [GCC_GPLL4_OUT_MAIN] = &gpll4_out_main.clkr, + [GCC_GPLL6] = &gpll6.clkr, + [GCC_GPLL6_OUT_AUX] = &gpll6_out_aux, + [GCC_HDMI_APP_CLK_SRC] = &hdmi_app_clk_src.clkr, + [GCC_HDMI_PCLK_CLK_SRC] = &hdmi_pclk_clk_src.clkr, + [GCC_MDP_CLK_SRC] = &mdp_clk_src.clkr, + [GCC_PCIE_0_AUX_CLK_SRC] = &pcie_0_aux_clk_src.clkr, + [GCC_PCIE_0_PIPE_CLK_SRC] = &pcie_0_pipe_clk_src.clkr, + [GCC_PCLK0_CLK_SRC] = &pclk0_clk_src.clkr, + [GCC_PDM2_CLK_SRC] = &pdm2_clk_src.clkr, + [GCC_SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [GCC_SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr, + [GCC_USB20_MOCK_UTMI_CLK_SRC] = &usb20_mock_utmi_clk_src.clkr, + [GCC_USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr, + [GCC_USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, + [GCC_USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr, + [GCC_USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr, + [GCC_VSYNC_CLK_SRC] = &vsync_clk_src.clkr, + [GCC_USB_HS_INACTIVITY_TIMERS_CLK] = + &gcc_usb_hs_inactivity_timers_clk.clkr, + [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr, + [GCC_GTCU_AHB_CLK] = &gcc_gtcu_ahb_clk.clkr, + [GCC_GFX_TCU_CLK] = &gcc_gfx_tcu_clk.clkr, + [GCC_GFX_TBU_CLK] = &gcc_gfx_tbu_clk.clkr, + [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr, + [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr, + [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr, + [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr, + [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr, + [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_clk.clkr, + [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, + [GCC_DCC_CLK] = &gcc_dcc_clk.clkr, + [GCC_DCC_XO_CLK] = &gcc_dcc_xo_clk.clkr, +}; + +static const struct qcom_reset_map gcc_qcs404_resets[] = { + [GCC_GENI_IR_BCR] = { 0x0F000 }, + [GCC_USB_HS_BCR] = { 0x41000 }, + [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, + [GCC_QUSB2_PHY_BCR] = { 0x4103c }, + [GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 }, + [GCC_USB2A_PHY_BCR] = { 0x0000c, 0 }, + [GCC_USB3_PHY_BCR] = { 0x39004 }, + [GCC_USB_30_BCR] = { 0x39000 }, + [GCC_USB3PHY_PHY_BCR] = { 0x39008 }, + [GCC_PCIE_0_BCR] = { 0x3e000 }, + [GCC_PCIE_0_PHY_BCR] = { 0x3e004 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 }, + [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c }, + [GCC_EMAC_BCR] = { 0x4e000 }, +}; + +static const struct regmap_config gcc_qcs404_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x7f000, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_qcs404_desc = { + .config = &gcc_qcs404_regmap_config, + .clks = gcc_qcs404_clocks, + .num_clks = ARRAY_SIZE(gcc_qcs404_clocks), + .resets = gcc_qcs404_resets, + .num_resets = ARRAY_SIZE(gcc_qcs404_resets), +}; + +static const struct of_device_id gcc_qcs404_match_table[] = { + { .compatible = "qcom,gcc-qcs404" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_qcs404_match_table); + +static int gcc_qcs404_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret, i; + + regmap = qcom_cc_map(pdev, &gcc_qcs404_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + clk_alpha_pll_configure(&gpll3_out_main, regmap, &gpll3_config); + + for (i = 0; i < ARRAY_SIZE(gcc_qcs404_hws); i++) { + ret = devm_clk_hw_register(&pdev->dev, gcc_qcs404_hws[i]); + if (ret) + return ret; + } + + return qcom_cc_really_probe(pdev, &gcc_qcs404_desc, regmap); +} + +static struct platform_driver gcc_qcs404_driver = { + .probe = gcc_qcs404_probe, + .driver = { + .name = "gcc-qcs404", + .of_match_table = gcc_qcs404_match_table, + }, +}; + +static int __init gcc_qcs404_init(void) +{ + return platform_driver_register(&gcc_qcs404_driver); +} +subsys_initcall(gcc_qcs404_init); + +static void __exit gcc_qcs404_exit(void) +{ + platform_driver_unregister(&gcc_qcs404_driver); +} +module_exit(gcc_qcs404_exit); + +MODULE_DESCRIPTION("Qualcomm GCC QCS404 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c new file mode 100644 index 000000000000..ba239ea4c842 --- /dev/null +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -0,0 +1,2480 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2018, Craig Tatlor. + */ + +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> + +#include <dt-bindings/clock/qcom,gcc-sdm660.h> + +#include "common.h" +#include "clk-regmap.h" +#include "clk-alpha-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" +#include "gdsc.h" + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +enum { + P_XO, + P_SLEEP_CLK, + P_GPLL0, + P_GPLL1, + P_GPLL4, + P_GPLL0_EARLY_DIV, + P_GPLL1_EARLY_DIV, +}; + +static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL0_EARLY_DIV, 6 }, +}; + +static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div[] = { + "xo", + "gpll0", + "gpll0_early_div", +}; + +static const struct parent_map gcc_parent_map_xo_gpll0[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, +}; + +static const char * const gcc_parent_names_xo_gpll0[] = { + "xo", + "gpll0", +}; + +static const struct parent_map gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GPLL0_EARLY_DIV, 6 }, +}; + +static const char * const gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div[] = { + "xo", + "gpll0", + "sleep_clk", + "gpll0_early_div", +}; + +static const struct parent_map gcc_parent_map_xo_sleep_clk[] = { + { P_XO, 0 }, + { P_SLEEP_CLK, 5 }, +}; + +static const char * const gcc_parent_names_xo_sleep_clk[] = { + "xo", + "sleep_clk", +}; + +static const struct parent_map gcc_parent_map_xo_gpll4[] = { + { P_XO, 0 }, + { P_GPLL4, 5 }, +}; + +static const char * const gcc_parent_names_xo_gpll4[] = { + "xo", + "gpll4", +}; + +static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL0_EARLY_DIV, 3 }, + { P_GPLL1, 4 }, + { P_GPLL4, 5 }, + { P_GPLL1_EARLY_DIV, 6 }, +}; + +static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div[] = { + "xo", + "gpll0", + "gpll0_early_div", + "gpll1", + "gpll4", + "gpll1_early_div", +}; + +static const struct parent_map gcc_parent_map_xo_gpll0_gpll4_gpll0_early_div[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL4, 5 }, + { P_GPLL0_EARLY_DIV, 6 }, +}; + +static const char * const gcc_parent_names_xo_gpll0_gpll4_gpll0_early_div[] = { + "xo", + "gpll0", + "gpll4", + "gpll0_early_div", +}; + +static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div_gpll4[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL0_EARLY_DIV, 2 }, + { P_GPLL4, 5 }, +}; + +static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div_gpll4[] = { + "xo", + "gpll0", + "gpll0_early_div", + "gpll4", +}; + +static struct clk_fixed_factor xo = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "xo", + .parent_names = (const char *[]){ "xo_board" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll0_early = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll0_early_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll0_early_div", + .parent_names = (const char *[]){ "gpll0_early" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll0 = { + .offset = 0x00000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_names = (const char *[]){ "gpll0_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static struct clk_alpha_pll gpll1_early = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gpll1_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll1_early_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll1_early_div", + .parent_names = (const char *[]){ "gpll1_early" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll1", + .parent_names = (const char *[]){ "gpll1_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static struct clk_alpha_pll gpll4_early = { + .offset = 0x77000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gpll4_early", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv gpll4 = { + .offset = 0x77000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data) + { + .name = "gpll4", + .parent_names = (const char *[]) { "gpll4_early" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup1_i2c_apps_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x19020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup1_spi_apps_clk_src[] = { + F(960000, P_XO, 10, 1, 2), + F(4800000, P_XO, 4, 0, 0), + F(9600000, P_XO, 2, 0, 0), + F(15000000, P_GPLL0, 10, 1, 4), + F(19200000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0, 12, 1, 2), + F(50000000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x1900c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x1b020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x1b00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x1d020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x1d00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x1f020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x1f00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_uart1_apps_clk_src[] = { + F(3686400, P_GPLL0, 1, 96, 15625), + F(7372800, P_GPLL0, 1, 192, 15625), + F(14745600, P_GPLL0, 1, 384, 15625), + F(16000000, P_GPLL0, 5, 2, 15), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0, 5, 1, 5), + F(32000000, P_GPLL0, 1, 4, 75), + F(40000000, P_GPLL0, 15, 0, 0), + F(46400000, P_GPLL0, 1, 29, 375), + F(48000000, P_GPLL0, 12.5, 0, 0), + F(51200000, P_GPLL0, 1, 32, 375), + F(56000000, P_GPLL0, 1, 7, 75), + F(58982400, P_GPLL0, 1, 1536, 15625), + F(60000000, P_GPLL0, 10, 0, 0), + F(63157895, P_GPLL0, 9.5, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x1a00c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart1_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .cmd_rcgr = 0x1c00c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart2_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x26020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup1_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x2600c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup1_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x28020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup2_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x2800c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup2_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x2a020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup3_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x2a00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup3_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x2c020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup4_i2c_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x2c00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup4_spi_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart1_apps_clk_src = { + .cmd_rcgr = 0x2700c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart1_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp2_uart2_apps_clk_src = { + .cmd_rcgr = 0x2900c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_uart2_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gp1_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x65004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0x66004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div, + .freq_tbl = ftbl_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_hmss_gpll0_clk_src[] = { + F(300000000, P_GPLL0, 2, 0, 0), + F(600000000, P_GPLL0, 1, 0, 0), + { } +}; + +static struct clk_rcg2 hmss_gpll0_clk_src = { + .cmd_rcgr = 0x4805c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_hmss_gpll0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hmss_gpll0_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_hmss_gpll4_clk_src[] = { + F(384000000, P_GPLL4, 4, 0, 0), + F(768000000, P_GPLL4, 2, 0, 0), + F(1536000000, P_GPLL4, 1, 0, 0), + { } +}; + +static struct clk_rcg2 hmss_gpll4_clk_src = { + .cmd_rcgr = 0x48074, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll4, + .freq_tbl = ftbl_hmss_gpll4_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hmss_gpll4_clk_src", + .parent_names = gcc_parent_names_xo_gpll4, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_hmss_rbcpr_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 hmss_rbcpr_clk_src = { + .cmd_rcgr = 0x48044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_hmss_rbcpr_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hmss_rbcpr_clk_src", + .parent_names = gcc_parent_names_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_pdm2_clk_src[] = { + F(60000000, P_GPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 pdm2_clk_src = { + .cmd_rcgr = 0x33010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_pdm2_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pdm2_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_qspi_ser_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(80200000, P_GPLL1_EARLY_DIV, 5, 0, 0), + F(160400000, P_GPLL1, 5, 0, 0), + F(267333333, P_GPLL1, 3, 0, 0), + { } +}; + +static struct clk_rcg2 qspi_ser_clk_src = { + .cmd_rcgr = 0x4d00c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div, + .freq_tbl = ftbl_qspi_ser_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "qspi_ser_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc1_apps_clk_src[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0_EARLY_DIV, 5, 1, 3), + F(25000000, P_GPLL0_EARLY_DIV, 6, 1, 2), + F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(192000000, P_GPLL4, 8, 0, 0), + F(384000000, P_GPLL4, 4, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x1602c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll4_gpll0_early_div, + .freq_tbl = ftbl_sdcc1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll4_gpll0_early_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc1_ice_core_clk_src[] = { + F(75000000, P_GPLL0_EARLY_DIV, 4, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x16010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_sdcc1_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_ice_core_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_sdcc2_apps_clk_src[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0_EARLY_DIV, 5, 1, 3), + F(25000000, P_GPLL0_EARLY_DIV, 6, 1, 2), + F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(192000000, P_GPLL4, 8, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc2_apps_clk_src = { + .cmd_rcgr = 0x14010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div_gpll4, + .freq_tbl = ftbl_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc2_apps_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div_gpll4, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_ufs_axi_clk_src[] = { + F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(240000000, P_GPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 ufs_axi_clk_src = { + .cmd_rcgr = 0x75018, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_ufs_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ufs_axi_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_ufs_ice_core_clk_src[] = { + F(75000000, P_GPLL0_EARLY_DIV, 4, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + { } +}; + +static struct clk_rcg2 ufs_ice_core_clk_src = { + .cmd_rcgr = 0x76010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_ufs_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ufs_ice_core_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 ufs_phy_aux_clk_src = { + .cmd_rcgr = 0x76044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_sleep_clk, + .freq_tbl = ftbl_hmss_rbcpr_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ufs_phy_aux_clk_src", + .parent_names = gcc_parent_names_xo_sleep_clk, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_ufs_unipro_core_clk_src[] = { + F(37500000, P_GPLL0_EARLY_DIV, 8, 0, 0), + F(75000000, P_GPLL0, 8, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 ufs_unipro_core_clk_src = { + .cmd_rcgr = 0x76028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_ufs_unipro_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ufs_unipro_core_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb20_master_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(60000000, P_GPLL0, 10, 0, 0), + F(120000000, P_GPLL0, 5, 0, 0), + { } +}; + +static struct clk_rcg2 usb20_master_clk_src = { + .cmd_rcgr = 0x2f010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_usb20_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb20_master_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb20_mock_utmi_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(60000000, P_GPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 usb20_mock_utmi_clk_src = { + .cmd_rcgr = 0x2f024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_usb20_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb20_mock_utmi_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb30_master_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(66666667, P_GPLL0_EARLY_DIV, 4.5, 0, 0), + F(120000000, P_GPLL0, 5, 0, 0), + F(133333333, P_GPLL0, 4.5, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(240000000, P_GPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 usb30_master_clk_src = { + .cmd_rcgr = 0xf014, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_usb30_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_master_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb30_mock_utmi_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(40000000, P_GPLL0_EARLY_DIV, 7.5, 0, 0), + F(60000000, P_GPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 usb30_mock_utmi_clk_src = { + .cmd_rcgr = 0xf028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .freq_tbl = ftbl_usb30_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_mock_utmi_clk_src", + .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb3_phy_aux_clk_src[] = { + F(1200000, P_XO, 16, 0, 0), + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 usb3_phy_aux_clk_src = { + .cmd_rcgr = 0x5000c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_xo_sleep_clk, + .freq_tbl = ftbl_usb3_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb3_phy_aux_clk_src", + .parent_names = gcc_parent_names_xo_sleep_clk, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_aggre2_ufs_axi_clk = { + .halt_reg = 0x75034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x75034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre2_ufs_axi_clk", + .parent_names = (const char *[]){ + "ufs_axi_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre2_usb3_axi_clk = { + .halt_reg = 0xf03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre2_usb3_axi_clk", + .parent_names = (const char *[]){ + "usb30_master_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_gfx_clk = { + .halt_reg = 0x7106c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x7106c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_hmss_axi_clk = { + .halt_reg = 0x48004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_hmss_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_mss_q6_axi_clk = { + .halt_reg = 0x4401c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4401c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_mss_q6_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(17), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x19008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x19008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { + .halt_reg = 0x19004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x19004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { + .halt_reg = 0x1b008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1b008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { + .halt_reg = 0x1b004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = { + .halt_reg = 0x1d008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup3_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = { + .halt_reg = 0x1d004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup3_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = { + .halt_reg = 0x1f008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1f008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup4_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = { + .halt_reg = 0x1f004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1f004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup4_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart1_apps_clk = { + .halt_reg = 0x1a004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart1_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart1_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart2_apps_clk = { + .halt_reg = 0x1c004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart2_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart2_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_ahb_clk = { + .halt_reg = 0x25004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = { + .halt_reg = 0x26008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x26008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup1_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup1_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = { + .halt_reg = 0x26004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x26004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup1_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup1_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = { + .halt_reg = 0x28008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup2_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup2_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = { + .halt_reg = 0x28004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup2_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup2_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = { + .halt_reg = 0x2a008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2a008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup3_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup3_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = { + .halt_reg = 0x2a004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup3_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup3_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = { + .halt_reg = 0x2c008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2c008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup4_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup4_i2c_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = { + .halt_reg = 0x2c004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup4_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp2_qup4_spi_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart1_apps_clk = { + .halt_reg = 0x27004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x27004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart1_apps_clk", + .parent_names = (const char *[]){ + "blsp2_uart1_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp2_uart2_apps_clk = { + .halt_reg = 0x29004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x29004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_uart2_apps_clk", + .parent_names = (const char *[]){ + "blsp2_uart2_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb2_axi_clk = { + .halt_reg = 0x5058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cfg_noc_usb2_axi_clk", + .parent_names = (const char *[]){ + "usb20_master_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_axi_clk = { + .halt_reg = 0x5018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cfg_noc_usb3_axi_clk", + .parent_names = (const char *[]){ + "usb30_master_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_dcc_ahb_clk = { + .halt_reg = 0x84004, + .clkr = { + .enable_reg = 0x84004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x64000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x64000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_names = (const char *[]){ + "gp1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x65000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x65000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_names = (const char *[]){ + "gp2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x66000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x66000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_names = (const char *[]){ + "gp3_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_bimc_gfx_clk = { + .halt_reg = 0x71010, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x71010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_bimc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_cfg_ahb_clk = { + .halt_reg = 0x71004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x71004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk = { + .halt_reg = 0x5200c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_clk", + .parent_names = (const char *[]){ + "gpll0", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk = { + .halt_reg = 0x5200c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_div_clk", + .parent_names = (const char *[]){ + "gpll0_early_div", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_hmss_dvm_bus_clk = { + .halt_reg = 0x4808c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4808c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_hmss_dvm_bus_clk", + .ops = &clk_branch2_ops, + .flags = CLK_IGNORE_UNUSED, + }, + }, +}; + +static struct clk_branch gcc_hmss_rbcpr_clk = { + .halt_reg = 0x48008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x48008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_hmss_rbcpr_clk", + .parent_names = (const char *[]){ + "hmss_rbcpr_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmss_gpll0_clk = { + .halt_reg = 0x5200c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_gpll0_clk", + .parent_names = (const char *[]){ + "gpll0", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmss_gpll0_div_clk = { + .halt_reg = 0x5200c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_gpll0_div_clk", + .parent_names = (const char *[]){ + "gpll0_early_div", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = { + .halt_reg = 0x9004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_noc_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmss_sys_noc_axi_clk = { + .halt_reg = 0x9000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_sys_noc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_cfg_ahb_clk = { + .halt_reg = 0x8a000, + .clkr = { + .enable_reg = 0x8a000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = { + .halt_reg = 0x8a004, + .clkr = { + .enable_reg = 0x8a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_mnoc_bimc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .halt_reg = 0x8a040, + .clkr = { + .enable_reg = 0x8a040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_bimc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_snoc_axi_clk = { + .halt_reg = 0x8a03c, + .clkr = { + .enable_reg = 0x8a03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_snoc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_names = (const char *[]){ + "pdm2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x33004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x34004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_ahb_clk = { + .halt_reg = 0x4d004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_ser_clk = { + .halt_reg = 0x4d008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_ser_clk", + .parent_names = (const char *[]){ + "qspi_ser_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_rx0_usb2_clkref_clk = { + .halt_reg = 0x88018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x88018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_rx0_usb2_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_rx1_usb2_clkref_clk = { + .halt_reg = 0x88014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x88014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_rx1_usb2_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x16008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x16004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_names = (const char *[]){ + "sdcc1_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x1600c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk", + .parent_names = (const char *[]){ + "sdcc1_ice_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x14008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x14004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_names = (const char *[]){ + "sdcc2_apps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_ahb_clk = { + .halt_reg = 0x7500c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7500c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_axi_clk = { + .halt_reg = 0x75008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x75008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_axi_clk", + .parent_names = (const char *[]){ + "ufs_axi_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_clkref_clk = { + .halt_reg = 0x88008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x88008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_ice_core_clk = { + .halt_reg = 0x7600c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_ice_core_clk", + .parent_names = (const char *[]){ + "ufs_ice_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_aux_clk = { + .halt_reg = 0x76040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x76040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_aux_clk", + .parent_names = (const char *[]){ + "ufs_phy_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_rx_symbol_0_clk = { + .halt_reg = 0x75014, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x75014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_rx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_rx_symbol_1_clk = { + .halt_reg = 0x7605c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x7605c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_rx_symbol_1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_tx_symbol_0_clk = { + .halt_reg = 0x75010, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x75010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_tx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_unipro_core_clk = { + .halt_reg = 0x76008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x76008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_unipro_core_clk", + .parent_names = (const char *[]){ + "ufs_unipro_core_clk_src", + }, + .flags = CLK_SET_RATE_PARENT, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_master_clk = { + .halt_reg = 0x2f004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2f004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb20_master_clk", + .parent_names = (const char *[]){ + "usb20_master_clk_src" + }, + .flags = CLK_SET_RATE_PARENT, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_mock_utmi_clk = { + .halt_reg = 0x2f00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2f00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb20_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb20_mock_utmi_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_sleep_clk = { + .halt_reg = 0x2f008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2f008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb20_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_master_clk = { + .halt_reg = 0xf008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_master_clk", + .parent_names = (const char *[]){ + "usb30_master_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_mock_utmi_clk = { + .halt_reg = 0xf010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb30_mock_utmi_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sleep_clk = { + .halt_reg = 0xf00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_clkref_clk = { + .halt_reg = 0x8800c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8800c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_phy_aux_clk = { + .halt_reg = 0x50000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x50000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_phy_aux_clk", + .parent_names = (const char *[]){ + "usb3_phy_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_phy_pipe_clk = { + .halt_reg = 0x50004, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x50004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { + .halt_reg = 0x6a004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_phy_cfg_ahb2phy_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc ufs_gdsc = { + .gdscr = 0x75004, + .gds_hw_ctrl = 0x0, + .pd = { + .name = "ufs_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc usb_30_gdsc = { + .gdscr = 0xf004, + .gds_hw_ctrl = 0x0, + .pd = { + .name = "usb_30_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc pcie_0_gdsc = { + .gdscr = 0x6b004, + .gds_hw_ctrl = 0x0, + .pd = { + .name = "pcie_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct clk_hw *gcc_sdm660_hws[] = { + &xo.hw, + &gpll0_early_div.hw, + &gpll1_early_div.hw, +}; + +static struct clk_regmap *gcc_sdm660_clocks[] = { + [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr, + [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr, + [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr, + [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr, + [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr, + [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr, + [BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr, + [BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr, + [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr, + [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr, + [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr, + [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr, + [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, + [GCC_BIMC_HMSS_AXI_CLK] = &gcc_bimc_hmss_axi_clk.clkr, + [GCC_BIMC_MSS_Q6_AXI_CLK] = &gcc_bimc_mss_q6_axi_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr, + [GCC_BLSP2_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr, + [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr, + [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr, + [GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr, + [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr, + [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CFG_NOC_USB2_AXI_CLK] = &gcc_cfg_noc_usb2_axi_clk.clkr, + [GCC_CFG_NOC_USB3_AXI_CLK] = &gcc_cfg_noc_usb3_axi_clk.clkr, + [GCC_DCC_AHB_CLK] = &gcc_dcc_ahb_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GPU_BIMC_GFX_CLK] = &gcc_gpu_bimc_gfx_clk.clkr, + [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr, + [GCC_GPU_GPLL0_CLK] = &gcc_gpu_gpll0_clk.clkr, + [GCC_GPU_GPLL0_DIV_CLK] = &gcc_gpu_gpll0_div_clk.clkr, + [GCC_HMSS_DVM_BUS_CLK] = &gcc_hmss_dvm_bus_clk.clkr, + [GCC_HMSS_RBCPR_CLK] = &gcc_hmss_rbcpr_clk.clkr, + [GCC_MMSS_GPLL0_CLK] = &gcc_mmss_gpll0_clk.clkr, + [GCC_MMSS_GPLL0_DIV_CLK] = &gcc_mmss_gpll0_div_clk.clkr, + [GCC_MMSS_NOC_CFG_AHB_CLK] = &gcc_mmss_noc_cfg_ahb_clk.clkr, + [GCC_MMSS_SYS_NOC_AXI_CLK] = &gcc_mmss_sys_noc_axi_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr, + [GCC_QSPI_SER_CLK] = &gcc_qspi_ser_clk.clkr, + [GCC_RX0_USB2_CLKREF_CLK] = &gcc_rx0_usb2_clkref_clk.clkr, + [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr, + [GCC_UFS_AXI_CLK] = &gcc_ufs_axi_clk.clkr, + [GCC_UFS_CLKREF_CLK] = &gcc_ufs_clkref_clk.clkr, + [GCC_UFS_ICE_CORE_CLK] = &gcc_ufs_ice_core_clk.clkr, + [GCC_UFS_PHY_AUX_CLK] = &gcc_ufs_phy_aux_clk.clkr, + [GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr, + [GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr, + [GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr, + [GCC_UFS_UNIPRO_CORE_CLK] = &gcc_ufs_unipro_core_clk.clkr, + [GCC_USB20_MASTER_CLK] = &gcc_usb20_master_clk.clkr, + [GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr, + [GCC_USB20_SLEEP_CLK] = &gcc_usb20_sleep_clk.clkr, + [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr, + [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr, + [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr, + [GCC_USB3_CLKREF_CLK] = &gcc_usb3_clkref_clk.clkr, + [GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr, + [GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr, + [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [GPLL0] = &gpll0.clkr, + [GPLL0_EARLY] = &gpll0_early.clkr, + [GPLL1] = &gpll1.clkr, + [GPLL1_EARLY] = &gpll1_early.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL4_EARLY] = &gpll4_early.clkr, + [HMSS_GPLL0_CLK_SRC] = &hmss_gpll0_clk_src.clkr, + [HMSS_GPLL4_CLK_SRC] = &hmss_gpll4_clk_src.clkr, + [HMSS_RBCPR_CLK_SRC] = &hmss_rbcpr_clk_src.clkr, + [PDM2_CLK_SRC] = &pdm2_clk_src.clkr, + [QSPI_SER_CLK_SRC] = &qspi_ser_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr, + [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr, + [UFS_AXI_CLK_SRC] = &ufs_axi_clk_src.clkr, + [UFS_ICE_CORE_CLK_SRC] = &ufs_ice_core_clk_src.clkr, + [UFS_PHY_AUX_CLK_SRC] = &ufs_phy_aux_clk_src.clkr, + [UFS_UNIPRO_CORE_CLK_SRC] = &ufs_unipro_core_clk_src.clkr, + [USB20_MASTER_CLK_SRC] = &usb20_master_clk_src.clkr, + [USB20_MOCK_UTMI_CLK_SRC] = &usb20_mock_utmi_clk_src.clkr, + [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr, + [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, + [USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr, +}; + +static struct gdsc *gcc_sdm660_gdscs[] = { + [UFS_GDSC] = &ufs_gdsc, + [USB_30_GDSC] = &usb_30_gdsc, + [PCIE_0_GDSC] = &pcie_0_gdsc, +}; + +static const struct qcom_reset_map gcc_sdm660_resets[] = { + [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 }, + [GCC_UFS_BCR] = { 0x75000 }, + [GCC_USB3_DP_PHY_BCR] = { 0x50028 }, + [GCC_USB3_PHY_BCR] = { 0x50020 }, + [GCC_USB3PHY_PHY_BCR] = { 0x50024 }, + [GCC_USB_20_BCR] = { 0x2f000 }, + [GCC_USB_30_BCR] = { 0xf000 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, +}; + +static const struct regmap_config gcc_sdm660_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x94000, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_sdm660_desc = { + .config = &gcc_sdm660_regmap_config, + .clks = gcc_sdm660_clocks, + .num_clks = ARRAY_SIZE(gcc_sdm660_clocks), + .resets = gcc_sdm660_resets, + .num_resets = ARRAY_SIZE(gcc_sdm660_resets), + .gdscs = gcc_sdm660_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_sdm660_gdscs), +}; + +static const struct of_device_id gcc_sdm660_match_table[] = { + { .compatible = "qcom,gcc-sdm630" }, + { .compatible = "qcom,gcc-sdm660" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_sdm660_match_table); + +static int gcc_sdm660_probe(struct platform_device *pdev) +{ + int i, ret; + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &gcc_sdm660_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* + * Set the HMSS_AHB_CLK_SLEEP_ENA bit to allow the hmss_ahb_clk to be + * turned off by hardware during certain apps low power modes. + */ + ret = regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21)); + if (ret) + return ret; + + /* Register the hws */ + for (i = 0; i < ARRAY_SIZE(gcc_sdm660_hws); i++) { + ret = devm_clk_hw_register(&pdev->dev, gcc_sdm660_hws[i]); + if (ret) + return ret; + } + + return qcom_cc_really_probe(pdev, &gcc_sdm660_desc, regmap); +} + +static struct platform_driver gcc_sdm660_driver = { + .probe = gcc_sdm660_probe, + .driver = { + .name = "gcc-sdm660", + .of_match_table = gcc_sdm660_match_table, + }, +}; + +static int __init gcc_sdm660_init(void) +{ + return platform_driver_register(&gcc_sdm660_driver); +} +core_initcall_sync(gcc_sdm660_init); + +static void __exit gcc_sdm660_exit(void) +{ + platform_driver_unregister(&gcc_sdm660_driver); +} +module_exit(gcc_sdm660_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("QCOM GCC sdm660 Driver"); diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index a7e72ebb79ba..f133b7f5652f 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -340,6 +340,28 @@ static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = { }, }; +static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_qspi_core_clk_src = { + .cmd_rcgr = 0x4b008, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qspi_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_core_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_floor_ops, + }, +}; + static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { F(9600000, P_BI_TCXO, 2, 0, 0), F(19200000, P_BI_TCXO, 1, 0, 0), @@ -380,18 +402,27 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { { } }; +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_init = { + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, +}; + static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { .cmd_rcgr = 0x17034, .mnd_width = 16, .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s0_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_init = { + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { @@ -400,12 +431,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s1_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_init = { + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { @@ -414,12 +447,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s2_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_init = { + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { @@ -428,12 +463,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s3_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_init = { + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { @@ -442,12 +479,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s4_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_init = { + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { @@ -456,12 +495,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s5_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s6_clk_init = { + .name = "gcc_qupv3_wrap0_s6_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { @@ -470,12 +511,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s6_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s7_clk_init = { + .name = "gcc_qupv3_wrap0_s7_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { @@ -484,12 +527,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s7_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { @@ -498,12 +543,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s0_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_init = { + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { @@ -512,12 +559,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s1_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s2_clk_init = { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { @@ -526,12 +575,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s2_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_init = { + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { @@ -540,12 +591,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s3_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { @@ -554,12 +607,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s4_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_init = { + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { @@ -568,12 +623,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s5_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s6_clk_init = { + .name = "gcc_qupv3_wrap1_s6_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { @@ -582,12 +639,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s6_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s7_clk_init = { + .name = "gcc_qupv3_wrap1_s7_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { @@ -596,12 +655,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s7_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_init, }; static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { @@ -1917,6 +1971,37 @@ static struct clk_branch gcc_qmip_video_ahb_clk = { }, }; +static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = { + .halt_reg = 0x4b000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4b000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_cnoc_periph_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_core_clk = { + .halt_reg = 0x4b004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_core_clk", + .parent_names = (const char *[]){ + "gcc_qspi_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_qupv3_wrap0_s0_clk = { .halt_reg = 0x17030, .halt_check = BRANCH_HALT_VOTED, @@ -3365,6 +3450,9 @@ static struct clk_regmap *gcc_sdm845_clocks[] = { [GPLL4] = &gpll4.clkr, [GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr, [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr, + [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr, + [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr, + [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr, }; static const struct qcom_reset_map gcc_sdm845_resets[] = { @@ -3442,9 +3530,29 @@ static const struct of_device_id gcc_sdm845_match_table[] = { }; MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table); +static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk), +}; + static int gcc_sdm845_probe(struct platform_device *pdev) { struct regmap *regmap; + int ret; regmap = qcom_cc_map(pdev, &gcc_sdm845_desc); if (IS_ERR(regmap)) @@ -3454,6 +3562,11 @@ static int gcc_sdm845_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); regmap_update_bits(regmap, 0x71028, 0x3, 0x3); + 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_sdm845_desc, regmap); } diff --git a/drivers/clk/qcom/hfpll.c b/drivers/clk/qcom/hfpll.c new file mode 100644 index 000000000000..a6de7101430c --- /dev/null +++ b/drivers/clk/qcom/hfpll.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018, The Linux Foundation. All rights reserved. + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/of.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> + +#include "clk-regmap.h" +#include "clk-hfpll.h" + +static const struct hfpll_data hdata = { + .mode_reg = 0x00, + .l_reg = 0x04, + .m_reg = 0x08, + .n_reg = 0x0c, + .user_reg = 0x10, + .config_reg = 0x14, + .config_val = 0x430405d, + .status_reg = 0x1c, + .lock_bit = 16, + + .user_val = 0x8, + .user_vco_mask = 0x100000, + .low_vco_max_rate = 1248000000, + .min_rate = 537600000UL, + .max_rate = 2900000000UL, +}; + +static const struct of_device_id qcom_hfpll_match_table[] = { + { .compatible = "qcom,hfpll" }, + { } +}; +MODULE_DEVICE_TABLE(of, qcom_hfpll_match_table); + +static const struct regmap_config hfpll_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x30, + .fast_io = true, +}; + +static int qcom_hfpll_probe(struct platform_device *pdev) +{ + struct resource *res; + struct device *dev = &pdev->dev; + void __iomem *base; + struct regmap *regmap; + struct clk_hfpll *h; + struct clk_init_data init = { + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_ops_hfpll, + }; + + h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL); + if (!h) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(&pdev->dev, base, &hfpll_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + if (of_property_read_string_index(dev->of_node, "clock-output-names", + 0, &init.name)) + return -ENODEV; + + h->d = &hdata; + h->clkr.hw.init = &init; + spin_lock_init(&h->lock); + + return devm_clk_register_regmap(&pdev->dev, &h->clkr); +} + +static struct platform_driver qcom_hfpll_driver = { + .probe = qcom_hfpll_probe, + .driver = { + .name = "qcom-hfpll", + .of_match_table = qcom_hfpll_match_table, + }, +}; +module_platform_driver(qcom_hfpll_driver); + +MODULE_DESCRIPTION("QCOM HFPLL Clock Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:qcom-hfpll"); diff --git a/drivers/clk/qcom/kpss-xcc.c b/drivers/clk/qcom/kpss-xcc.c new file mode 100644 index 000000000000..8590b5edd19d --- /dev/null +++ b/drivers/clk/qcom/kpss-xcc.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018, The Linux Foundation. All rights reserved. + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> + +static const char *aux_parents[] = { + "pll8_vote", + "pxo", +}; + +static unsigned int aux_parent_map[] = { + 3, + 0, +}; + +static const struct of_device_id kpss_xcc_match_table[] = { + { .compatible = "qcom,kpss-acc-v1", .data = (void *)1UL }, + { .compatible = "qcom,kpss-gcc" }, + {} +}; +MODULE_DEVICE_TABLE(of, kpss_xcc_match_table); + +static int kpss_xcc_driver_probe(struct platform_device *pdev) +{ + const struct of_device_id *id; + struct clk *clk; + struct resource *res; + void __iomem *base; + const char *name; + + id = of_match_device(kpss_xcc_match_table, &pdev->dev); + if (!id) + return -ENODEV; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + if (id->data) { + if (of_property_read_string_index(pdev->dev.of_node, + "clock-output-names", + 0, &name)) + return -ENODEV; + base += 0x14; + } else { + name = "acpu_l2_aux"; + base += 0x28; + } + + clk = clk_register_mux_table(&pdev->dev, name, aux_parents, + ARRAY_SIZE(aux_parents), 0, base, 0, 0x3, + 0, aux_parent_map, NULL); + + platform_set_drvdata(pdev, clk); + + return PTR_ERR_OR_ZERO(clk); +} + +static int kpss_xcc_driver_remove(struct platform_device *pdev) +{ + clk_unregister_mux(platform_get_drvdata(pdev)); + return 0; +} + +static struct platform_driver kpss_xcc_driver = { + .probe = kpss_xcc_driver_probe, + .remove = kpss_xcc_driver_remove, + .driver = { + .name = "kpss-xcc", + .of_match_table = kpss_xcc_match_table, + }, +}; +module_platform_driver(kpss_xcc_driver); + +MODULE_DESCRIPTION("Krait Processor Sub System (KPSS) Clock Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:kpss-xcc"); diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c new file mode 100644 index 000000000000..4d4b657d33c3 --- /dev/null +++ b/drivers/clk/qcom/krait-cc.c @@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018, The Linux Foundation. All rights reserved. + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/slab.h> + +#include "clk-krait.h" + +static unsigned int sec_mux_map[] = { + 2, + 0, +}; + +static unsigned int pri_mux_map[] = { + 1, + 2, + 0, +}; + +/* + * Notifier function for switching the muxes to safe parent + * while the hfpll is getting reprogrammed. + */ +static int krait_notifier_cb(struct notifier_block *nb, + unsigned long event, + void *data) +{ + int ret = 0; + struct krait_mux_clk *mux = container_of(nb, struct krait_mux_clk, + clk_nb); + /* Switch to safe parent */ + if (event == PRE_RATE_CHANGE) { + mux->old_index = krait_mux_clk_ops.get_parent(&mux->hw); + ret = krait_mux_clk_ops.set_parent(&mux->hw, mux->safe_sel); + mux->reparent = false; + /* + * By the time POST_RATE_CHANGE notifier is called, + * clk framework itself would have changed the parent for the new rate. + * Only otherwise, put back to the old parent. + */ + } else if (event == POST_RATE_CHANGE) { + if (!mux->reparent) + ret = krait_mux_clk_ops.set_parent(&mux->hw, + mux->old_index); + } + + return notifier_from_errno(ret); +} + +static int krait_notifier_register(struct device *dev, struct clk *clk, + struct krait_mux_clk *mux) +{ + int ret = 0; + + mux->clk_nb.notifier_call = krait_notifier_cb; + ret = clk_notifier_register(clk, &mux->clk_nb); + if (ret) + dev_err(dev, "failed to register clock notifier: %d\n", ret); + + return ret; +} + +static int +krait_add_div(struct device *dev, int id, const char *s, unsigned int offset) +{ + struct krait_div2_clk *div; + struct clk_init_data init = { + .num_parents = 1, + .ops = &krait_div2_clk_ops, + .flags = CLK_SET_RATE_PARENT, + }; + const char *p_names[1]; + struct clk *clk; + + div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); + if (!div) + return -ENOMEM; + + div->width = 2; + div->shift = 6; + div->lpl = id >= 0; + div->offset = offset; + div->hw.init = &init; + + init.name = kasprintf(GFP_KERNEL, "hfpll%s_div", s); + if (!init.name) + return -ENOMEM; + + init.parent_names = p_names; + p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s); + if (!p_names[0]) { + kfree(init.name); + return -ENOMEM; + } + + clk = devm_clk_register(dev, &div->hw); + kfree(p_names[0]); + kfree(init.name); + + return PTR_ERR_OR_ZERO(clk); +} + +static int +krait_add_sec_mux(struct device *dev, int id, const char *s, + unsigned int offset, bool unique_aux) +{ + int ret; + struct krait_mux_clk *mux; + static const char *sec_mux_list[] = { + "acpu_aux", + "qsb", + }; + struct clk_init_data init = { + .parent_names = sec_mux_list, + .num_parents = ARRAY_SIZE(sec_mux_list), + .ops = &krait_mux_clk_ops, + .flags = CLK_SET_RATE_PARENT, + }; + struct clk *clk; + + mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); + if (!mux) + return -ENOMEM; + + mux->offset = offset; + mux->lpl = id >= 0; + mux->mask = 0x3; + mux->shift = 2; + mux->parent_map = sec_mux_map; + mux->hw.init = &init; + mux->safe_sel = 0; + + init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s); + if (!init.name) + return -ENOMEM; + + if (unique_aux) { + sec_mux_list[0] = kasprintf(GFP_KERNEL, "acpu%s_aux", s); + if (!sec_mux_list[0]) { + clk = ERR_PTR(-ENOMEM); + goto err_aux; + } + } + + clk = devm_clk_register(dev, &mux->hw); + + ret = krait_notifier_register(dev, clk, mux); + if (ret) + goto unique_aux; + +unique_aux: + if (unique_aux) + kfree(sec_mux_list[0]); +err_aux: + kfree(init.name); + return PTR_ERR_OR_ZERO(clk); +} + +static struct clk * +krait_add_pri_mux(struct device *dev, int id, const char *s, + unsigned int offset) +{ + int ret; + struct krait_mux_clk *mux; + const char *p_names[3]; + struct clk_init_data init = { + .parent_names = p_names, + .num_parents = ARRAY_SIZE(p_names), + .ops = &krait_mux_clk_ops, + .flags = CLK_SET_RATE_PARENT, + }; + struct clk *clk; + + mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); + if (!mux) + return ERR_PTR(-ENOMEM); + + mux->mask = 0x3; + mux->shift = 0; + mux->offset = offset; + mux->lpl = id >= 0; + mux->parent_map = pri_mux_map; + mux->hw.init = &init; + mux->safe_sel = 2; + + init.name = kasprintf(GFP_KERNEL, "krait%s_pri_mux", s); + if (!init.name) + return ERR_PTR(-ENOMEM); + + p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s); + if (!p_names[0]) { + clk = ERR_PTR(-ENOMEM); + goto err_p0; + } + + p_names[1] = kasprintf(GFP_KERNEL, "hfpll%s_div", s); + if (!p_names[1]) { + clk = ERR_PTR(-ENOMEM); + goto err_p1; + } + + p_names[2] = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s); + if (!p_names[2]) { + clk = ERR_PTR(-ENOMEM); + goto err_p2; + } + + clk = devm_clk_register(dev, &mux->hw); + + ret = krait_notifier_register(dev, clk, mux); + if (ret) + goto err_p3; +err_p3: + kfree(p_names[2]); +err_p2: + kfree(p_names[1]); +err_p1: + kfree(p_names[0]); +err_p0: + kfree(init.name); + return clk; +} + +/* id < 0 for L2, otherwise id == physical CPU number */ +static struct clk *krait_add_clks(struct device *dev, int id, bool unique_aux) +{ + int ret; + unsigned int offset; + void *p = NULL; + const char *s; + struct clk *clk; + + if (id >= 0) { + offset = 0x4501 + (0x1000 * id); + s = p = kasprintf(GFP_KERNEL, "%d", id); + if (!s) + return ERR_PTR(-ENOMEM); + } else { + offset = 0x500; + s = "_l2"; + } + + ret = krait_add_div(dev, id, s, offset); + if (ret) { + clk = ERR_PTR(ret); + goto err; + } + + ret = krait_add_sec_mux(dev, id, s, offset, unique_aux); + if (ret) { + clk = ERR_PTR(ret); + goto err; + } + + clk = krait_add_pri_mux(dev, id, s, offset); +err: + kfree(p); + return clk; +} + +static struct clk *krait_of_get(struct of_phandle_args *clkspec, void *data) +{ + unsigned int idx = clkspec->args[0]; + struct clk **clks = data; + + if (idx >= 5) { + pr_err("%s: invalid clock index %d\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return clks[idx] ? : ERR_PTR(-ENODEV); +} + +static const struct of_device_id krait_cc_match_table[] = { + { .compatible = "qcom,krait-cc-v1", (void *)1UL }, + { .compatible = "qcom,krait-cc-v2" }, + {} +}; +MODULE_DEVICE_TABLE(of, krait_cc_match_table); + +static int krait_cc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct of_device_id *id; + unsigned long cur_rate, aux_rate; + int cpu; + struct clk *clk; + struct clk **clks; + struct clk *l2_pri_mux_clk; + + id = of_match_device(krait_cc_match_table, dev); + if (!id) + return -ENODEV; + + /* Rate is 1 because 0 causes problems for __clk_mux_determine_rate */ + clk = clk_register_fixed_rate(dev, "qsb", NULL, 0, 1); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + if (!id->data) { + clk = clk_register_fixed_factor(dev, "acpu_aux", + "gpll0_vote", 0, 1, 2); + if (IS_ERR(clk)) + return PTR_ERR(clk); + } + + /* Krait configurations have at most 4 CPUs and one L2 */ + clks = devm_kcalloc(dev, 5, sizeof(*clks), GFP_KERNEL); + if (!clks) + return -ENOMEM; + + for_each_possible_cpu(cpu) { + clk = krait_add_clks(dev, cpu, id->data); + if (IS_ERR(clk)) + return PTR_ERR(clk); + clks[cpu] = clk; + } + + l2_pri_mux_clk = krait_add_clks(dev, -1, id->data); + if (IS_ERR(l2_pri_mux_clk)) + return PTR_ERR(l2_pri_mux_clk); + clks[4] = l2_pri_mux_clk; + + /* + * We don't want the CPU or L2 clocks to be turned off at late init + * if CPUFREQ or HOTPLUG configs are disabled. So, bump up the + * refcount of these clocks. Any cpufreq/hotplug manager can assume + * that the clocks have already been prepared and enabled by the time + * they take over. + */ + for_each_online_cpu(cpu) { + clk_prepare_enable(l2_pri_mux_clk); + WARN(clk_prepare_enable(clks[cpu]), + "Unable to turn on CPU%d clock", cpu); + } + + /* + * Force reinit of HFPLLs and muxes to overwrite any potential + * incorrect configuration of HFPLLs and muxes by the bootloader. + * While at it, also make sure the cores are running at known rates + * and print the current rate. + * + * The clocks are set to aux clock rate first to make sure the + * secondary mux is not sourcing off of QSB. The rate is then set to + * two different rates to force a HFPLL reinit under all + * circumstances. + */ + cur_rate = clk_get_rate(l2_pri_mux_clk); + aux_rate = 384000000; + if (cur_rate == 1) { + pr_info("L2 @ QSB rate. Forcing new rate.\n"); + cur_rate = aux_rate; + } + clk_set_rate(l2_pri_mux_clk, aux_rate); + clk_set_rate(l2_pri_mux_clk, 2); + clk_set_rate(l2_pri_mux_clk, cur_rate); + pr_info("L2 @ %lu KHz\n", clk_get_rate(l2_pri_mux_clk) / 1000); + for_each_possible_cpu(cpu) { + clk = clks[cpu]; + cur_rate = clk_get_rate(clk); + if (cur_rate == 1) { + pr_info("CPU%d @ QSB rate. Forcing new rate.\n", cpu); + cur_rate = aux_rate; + } + + clk_set_rate(clk, aux_rate); + clk_set_rate(clk, 2); + clk_set_rate(clk, cur_rate); + pr_info("CPU%d @ %lu KHz\n", cpu, clk_get_rate(clk) / 1000); + } + + of_clk_add_provider(dev->of_node, krait_of_get, clks); + + return 0; +} + +static struct platform_driver krait_cc_driver = { + .probe = krait_cc_probe, + .driver = { + .name = "krait-cc", + .of_match_table = krait_cc_match_table, + }, +}; +module_platform_driver(krait_cc_driver); + +MODULE_DESCRIPTION("Krait CPU Clock Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:krait-cc"); |