diff options
author | Stephan Gerhold <stephan.gerhold@kernkonzept.com> | 2022-07-06 15:41:28 +0200 |
---|---|---|
committer | Bjorn Andersson <andersson@kernel.org> | 2022-09-13 22:07:25 -0500 |
commit | bf37a05744ebc6a488e3cfd3ec6d502d626740cc (patch) | |
tree | d248712ecff03e55d7fed67e2506c67e5e02a955 /drivers/clk/qcom/gcc-msm8909.c | |
parent | c40668048f236da6f7725998f93f0d6180003da3 (diff) | |
download | linux-bf37a05744ebc6a488e3cfd3ec6d502d626740cc.tar.gz linux-bf37a05744ebc6a488e3cfd3ec6d502d626740cc.tar.bz2 linux-bf37a05744ebc6a488e3cfd3ec6d502d626740cc.zip |
clk: qcom: Add driver for MSM8909 GCC
The Global Clock Controller (GCC) in the MSM8909 SoC provides clocks,
resets and power domains for the various hardware blocks in the SoC.
Add a driver for it to make it possible to enable additional
functionality for the SoC.
Work on this driver was originally started independently by Dominik,
I picked it up and added missing clocks/resets, as well as various
cleanup to bring it into shape for mainline.
Co-developed-by: Dominik Kobinski <dominikkobinski314@gmail.com>
Signed-off-by: Dominik Kobinski <dominikkobinski314@gmail.com>
Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Link: https://lore.kernel.org/r/20220706134132.3623415-3-stephan.gerhold@kernkonzept.com
Diffstat (limited to 'drivers/clk/qcom/gcc-msm8909.c')
-rw-r--r-- | drivers/clk/qcom/gcc-msm8909.c | 2731 |
1 files changed, 2731 insertions, 0 deletions
diff --git a/drivers/clk/qcom/gcc-msm8909.c b/drivers/clk/qcom/gcc-msm8909.c new file mode 100644 index 000000000000..c551953d3791 --- /dev/null +++ b/drivers/clk/qcom/gcc-msm8909.c @@ -0,0 +1,2731 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 Kernkonzept GmbH. + * + * Based on gcc-msm8916.c: + * Copyright 2015 Linaro Limited + * adapted with data from clock-gcc-8909.c in Qualcomm's msm-3.18 release: + * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. + */ + +#include <linux/bitops.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> + +#include <dt-bindings/clock/qcom,gcc-msm8909.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 "gdsc.h" +#include "reset.h" + +/* Need to match the order of clocks in DT binding */ +enum { + DT_XO, + DT_SLEEP_CLK, + DT_DSI0PLL, + DT_DSI0PLL_BYTE, +}; + +enum { + P_XO, + P_SLEEP_CLK, + P_GPLL0, + P_GPLL1, + P_GPLL2, + P_BIMC, + P_DSI0PLL, + P_DSI0PLL_BYTE, +}; + +static const struct parent_map gcc_xo_map[] = { + { P_XO, 0 }, +}; + +static const struct clk_parent_data gcc_xo_data[] = { + { .index = DT_XO }, +}; + +static const struct clk_parent_data gcc_sleep_clk_data[] = { + { .index = DT_SLEEP_CLK }, +}; + +static struct clk_alpha_pll gpll0_early = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) { + .name = "gpll0_early", + .parent_data = gcc_xo_data, + .num_parents = ARRAY_SIZE(gcc_xo_data), + /* Avoid rate changes for shared clock */ + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv gpll0 = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data) { + .name = "gpll0", + .parent_hws = (const struct clk_hw*[]) { + &gpll0_early.clkr.hw, + }, + .num_parents = 1, + /* Avoid rate changes for shared clock */ + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static struct clk_pll gpll1 = { + .l_reg = 0x20004, + .m_reg = 0x20008, + .n_reg = 0x2000c, + .config_reg = 0x20010, + .mode_reg = 0x20000, + .status_reg = 0x2001c, + .status_bit = 17, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gpll1", + .parent_data = gcc_xo_data, + .num_parents = ARRAY_SIZE(gcc_xo_data), + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap gpll1_vote = { + .enable_reg = 0x45000, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data) { + .name = "gpll1_vote", + .parent_hws = (const struct clk_hw*[]) { + &gpll1.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static struct clk_alpha_pll gpll2_early = { + .offset = 0x25000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data) { + .name = "gpll2_early", + .parent_data = gcc_xo_data, + .num_parents = ARRAY_SIZE(gcc_xo_data), + /* Avoid rate changes for shared clock */ + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv gpll2 = { + .offset = 0x25000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data) { + .name = "gpll2", + .parent_hws = (const struct clk_hw*[]) { + &gpll2_early.clkr.hw, + }, + .num_parents = 1, + /* Avoid rate changes for shared clock */ + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static struct clk_alpha_pll bimc_pll_early = { + .offset = 0x23000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data) { + .name = "bimc_pll_early", + .parent_data = gcc_xo_data, + .num_parents = ARRAY_SIZE(gcc_xo_data), + /* Avoid rate changes for shared clock */ + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv bimc_pll = { + .offset = 0x23000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data) { + .name = "bimc_pll", + .parent_hws = (const struct clk_hw*[]) { + &bimc_pll_early.clkr.hw, + }, + .num_parents = 1, + /* Avoid rate changes for shared clock */ + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static const struct parent_map gcc_xo_gpll0_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_data[] = { + { .index = DT_XO }, + { .hw = &gpll0.clkr.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_bimc_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_BIMC, 2 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_bimc_data[] = { + { .index = DT_XO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &bimc_pll.clkr.hw }, +}; + +static const struct freq_tbl ftbl_apss_ahb_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + { } +}; + +static struct clk_rcg2 apss_ahb_clk_src = { + .cmd_rcgr = 0x46000, + .hid_width = 5, + .freq_tbl = ftbl_apss_ahb_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "apss_ahb_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 bimc_ddr_clk_src = { + .cmd_rcgr = 0x32004, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_bimc_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "bimc_ddr_clk_src", + .parent_data = gcc_xo_gpll0_bimc_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc_data), + .ops = &clk_rcg2_ops, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_rcg2 bimc_gpu_clk_src = { + .cmd_rcgr = 0x31028, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_bimc_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "bimc_gpu_clk_src", + .parent_data = gcc_xo_gpll0_bimc_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc_data), + .ops = &clk_rcg2_ops, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static const struct freq_tbl ftbl_blsp_i2c_apps_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x0200c, + .hid_width = 5, + .freq_tbl = ftbl_blsp_i2c_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x03000, + .hid_width = 5, + .freq_tbl = ftbl_blsp_i2c_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x04000, + .hid_width = 5, + .freq_tbl = ftbl_blsp_i2c_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup3_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x05000, + .hid_width = 5, + .freq_tbl = ftbl_blsp_i2c_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup4_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = { + .cmd_rcgr = 0x06000, + .hid_width = 5, + .freq_tbl = ftbl_blsp_i2c_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup5_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = { + .cmd_rcgr = 0x07000, + .hid_width = 5, + .freq_tbl = ftbl_blsp_i2c_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup6_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct freq_tbl ftbl_blsp_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, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0, 16, 1, 2), + F(50000000, P_GPLL0, 16, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x02024, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_blsp_spi_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x03014, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_blsp_spi_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x04024, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_blsp_spi_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup3_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x05024, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_blsp_spi_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup4_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = { + .cmd_rcgr = 0x06024, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_blsp_spi_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup5_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = { + .cmd_rcgr = 0x07024, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_blsp_spi_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_qup6_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct freq_tbl ftbl_blsp_uart_apps_clk_src[] = { + F(3686400, P_GPLL0, 1, 72, 15625), + F(7372800, P_GPLL0, 1, 144, 15625), + F(14745600, P_GPLL0, 1, 288, 15625), + F(16000000, P_GPLL0, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0, 1, 3, 100), + F(25000000, P_GPLL0, 16, 1, 2), + F(32000000, P_GPLL0, 1, 1, 25), + F(40000000, P_GPLL0, 1, 1, 20), + F(46400000, P_GPLL0, 1, 29, 500), + F(48000000, P_GPLL0, 1, 3, 50), + F(51200000, P_GPLL0, 1, 8, 125), + F(56000000, P_GPLL0, 1, 7, 100), + F(58982400, P_GPLL0, 1, 1152, 15625), + F(60000000, P_GPLL0, 1, 3, 40), + { } +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x02044, + .hid_width = 5, + .mnd_width = 16, + .freq_tbl = ftbl_blsp_uart_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_uart1_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .cmd_rcgr = 0x03034, + .hid_width = 5, + .mnd_width = 16, + .freq_tbl = ftbl_blsp_uart_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "blsp1_uart2_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct parent_map gcc_byte0_map[] = { + { P_XO, 0 }, + { P_DSI0PLL_BYTE, 1 }, +}; + +static const struct clk_parent_data gcc_byte_data[] = { + { .index = DT_XO }, + { .index = DT_DSI0PLL_BYTE }, +}; + +static struct clk_rcg2 byte0_clk_src = { + .cmd_rcgr = 0x4d044, + .hid_width = 5, + .parent_map = gcc_byte0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "byte0_clk_src", + .parent_data = gcc_byte_data, + .num_parents = ARRAY_SIZE(gcc_byte_data), + .ops = &clk_byte2_ops, + .flags = CLK_SET_RATE_PARENT, + } +}; + +static const struct freq_tbl ftbl_camss_gp_clk_src[] = { + F(100000000, P_GPLL0, 8, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 camss_gp0_clk_src = { + .cmd_rcgr = 0x54000, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_camss_gp_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "camss_gp0_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 camss_gp1_clk_src = { + .cmd_rcgr = 0x55000, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_camss_gp_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "camss_gp1_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct freq_tbl ftbl_camss_top_ahb_clk_src[] = { + F(40000000, P_GPLL0, 10, 1, 2), + F(80000000, P_GPLL0, 10, 0, 0), + { } +}; + +static struct clk_rcg2 camss_top_ahb_clk_src = { + .cmd_rcgr = 0x5a000, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_camss_top_ahb_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "camss_top_ahb_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct freq_tbl ftbl_crypto_clk_src[] = { + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + { } +}; + +static struct clk_rcg2 crypto_clk_src = { + .cmd_rcgr = 0x16004, + .hid_width = 5, + .freq_tbl = ftbl_crypto_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "crypto_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct freq_tbl ftbl_csi_clk_src[] = { + F(100000000, P_GPLL0, 8, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 csi0_clk_src = { + .cmd_rcgr = 0x4e020, + .hid_width = 5, + .freq_tbl = ftbl_csi_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "csi0_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_map), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 csi1_clk_src = { + .cmd_rcgr = 0x4f020, + .hid_width = 5, + .freq_tbl = ftbl_csi_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "csi1_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct freq_tbl ftbl_csi_phytimer_clk_src[] = { + F(100000000, P_GPLL0, 8, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 csi0phytimer_clk_src = { + .cmd_rcgr = 0x4e000, + .hid_width = 5, + .freq_tbl = ftbl_csi_phytimer_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "csi0phytimer_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .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, + .hid_width = 5, + .freq_tbl = ftbl_esc0_clk_src, + .parent_map = gcc_xo_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "esc0_clk_src", + .parent_data = gcc_xo_data, + .num_parents = ARRAY_SIZE(gcc_xo_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct parent_map gcc_gfx3d_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL1, 2 }, +}; + +static const struct clk_parent_data gcc_gfx3d_data[] = { + { .index = DT_XO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll1_vote.hw }, +}; + +static const struct freq_tbl ftbl_gfx3d_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(177780000, P_GPLL0, 4.5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(307200000, P_GPLL1, 4, 0, 0), + F(409600000, P_GPLL1, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gfx3d_clk_src = { + .cmd_rcgr = 0x59000, + .hid_width = 5, + .freq_tbl = ftbl_gfx3d_clk_src, + .parent_map = gcc_gfx3d_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gfx3d_clk_src", + .parent_data = gcc_gfx3d_data, + .num_parents = ARRAY_SIZE(gcc_gfx3d_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct freq_tbl ftbl_gp_clk_src[] = { + F(150000, P_XO, 1, 1, 128), + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x08004, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_gp_clk_src, + .parent_map = gcc_xo_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gp1_clk_src", + .parent_data = gcc_xo_data, + .num_parents = ARRAY_SIZE(gcc_xo_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x09004, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_gp_clk_src, + .parent_map = gcc_xo_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gp2_clk_src", + .parent_data = gcc_xo_data, + .num_parents = ARRAY_SIZE(gcc_xo_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0x0a004, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_gp_clk_src, + .parent_map = gcc_xo_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gp3_clk_src", + .parent_data = gcc_xo_data, + .num_parents = ARRAY_SIZE(gcc_xo_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct parent_map gcc_mclk_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL2, 3 }, +}; + +static const struct clk_parent_data gcc_mclk_data[] = { + { .index = DT_XO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll2.clkr.hw }, +}; + +static const struct freq_tbl ftbl_mclk_clk_src[] = { + F(24000000, P_GPLL2, 1, 1, 33), + F(66667000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 mclk0_clk_src = { + .cmd_rcgr = 0x52000, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_mclk_clk_src, + .parent_map = gcc_mclk_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "mclk0_clk_src", + .parent_data = gcc_mclk_data, + .num_parents = ARRAY_SIZE(gcc_mclk_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_rcg2 mclk1_clk_src = { + .cmd_rcgr = 0x53000, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_mclk_clk_src, + .parent_map = gcc_mclk_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "mclk1_clk_src", + .parent_data = gcc_mclk_data, + .num_parents = ARRAY_SIZE(gcc_mclk_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct parent_map gcc_mdp_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL1, 3 }, +}; + +static const struct clk_parent_data gcc_mdp_data[] = { + { .index = DT_XO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll1_vote.hw }, +}; + +static const struct freq_tbl ftbl_mdp_clk_src[] = { + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(177780000, P_GPLL0, 4.5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(307200000, P_GPLL1, 4, 0, 0), + { } +}; + +static struct clk_rcg2 mdp_clk_src = { + .cmd_rcgr = 0x4d014, + .hid_width = 5, + .freq_tbl = ftbl_mdp_clk_src, + .parent_map = gcc_mdp_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "mdp_clk_src", + .parent_data = gcc_mdp_data, + .num_parents = ARRAY_SIZE(gcc_mdp_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct parent_map gcc_pclk0_map[] = { + { P_XO, 0 }, + { P_DSI0PLL, 1 }, +}; + +static const struct clk_parent_data gcc_pclk_data[] = { + { .index = DT_XO }, + { .index = DT_DSI0PLL }, +}; + +static struct clk_rcg2 pclk0_clk_src = { + .cmd_rcgr = 0x4d000, + .hid_width = 5, + .mnd_width = 8, + .parent_map = gcc_pclk0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pclk0_clk_src", + .parent_data = gcc_pclk_data, + .num_parents = ARRAY_SIZE(gcc_pclk_data), + .ops = &clk_pixel_ops, + .flags = CLK_SET_RATE_PARENT, + } +}; + +static struct clk_rcg2 pcnoc_bfdcd_clk_src = { + .cmd_rcgr = 0x27000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_bimc_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pcnoc_bfdcd_clk_src", + .parent_data = gcc_xo_gpll0_bimc_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_pdm2_clk_src[] = { + F(64000000, P_GPLL0, 12.5, 0, 0), + { } +}; + +static struct clk_rcg2 pdm2_clk_src = { + .cmd_rcgr = 0x44010, + .hid_width = 5, + .freq_tbl = ftbl_pdm2_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "pdm2_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_2_apps_clk[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0, 10, 1, 4), + F(25000000, P_GPLL0, 16, 1, 2), + F(50000000, P_GPLL0, 16, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(177770000, P_GPLL0, 4.5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x42004, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_gcc_sdcc1_2_apps_clk, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "sdcc1_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_floor_ops, + } +}; + +static struct clk_rcg2 sdcc2_apps_clk_src = { + .cmd_rcgr = 0x43004, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_gcc_sdcc1_2_apps_clk, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "sdcc2_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_floor_ops, + } +}; + +static struct clk_rcg2 system_noc_bfdcd_clk_src = { + .cmd_rcgr = 0x26004, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_bimc_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "system_noc_bfdcd_clk_src", + .parent_data = gcc_xo_gpll0_bimc_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc_data), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = { + F(57140000, P_GPLL0, 14, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + { } +}; + +static struct clk_rcg2 usb_hs_system_clk_src = { + .cmd_rcgr = 0x41010, + .hid_width = 5, + .freq_tbl = ftbl_gcc_usb_hs_system_clk, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "usb_hs_system_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct parent_map gcc_vcodec0_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL1, 3 }, +}; + +static const struct clk_parent_data gcc_vcodec0_data[] = { + { .index = DT_XO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll1_vote.hw }, +}; + +static const struct freq_tbl ftbl_vcodec0_clk_src[] = { + F(133330000, P_GPLL0, 6, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(307200000, P_GPLL1, 4, 0, 0), + { } +}; + +static struct clk_rcg2 vcodec0_clk_src = { + .cmd_rcgr = 0x4c000, + .hid_width = 5, + .mnd_width = 8, + .freq_tbl = ftbl_vcodec0_clk_src, + .parent_map = gcc_vcodec0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "vcodec0_clk_src", + .parent_data = gcc_vcodec0_data, + .num_parents = ARRAY_SIZE(gcc_vcodec0_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct freq_tbl ftbl_gcc_camss_vfe0_clk[] = { + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(133330000, P_GPLL0, 6, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(177780000, P_GPLL0, 4.5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 vfe0_clk_src = { + .cmd_rcgr = 0x58000, + .hid_width = 5, + .freq_tbl = ftbl_gcc_camss_vfe0_clk, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "vfe0_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + } +}; + +static const struct freq_tbl ftbl_vsync_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 vsync_clk_src = { + .cmd_rcgr = 0x4d02c, + .hid_width = 5, + .freq_tbl = ftbl_vsync_clk_src, + .parent_map = gcc_xo_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "vsync_clk_src", + .parent_data = gcc_xo_data, + .num_parents = ARRAY_SIZE(gcc_xo_data), + .ops = &clk_rcg2_ops, + } +}; + +static struct clk_branch gcc_apss_tcu_clk = { + .halt_reg = 0x12018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data) { + .name = "gcc_apss_tcu_clk", + .parent_hws = (const struct clk_hw*[]) { + &bimc_ddr_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + } + } +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x01008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data) { + .name = "gcc_blsp1_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &pcnoc_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + } + } +}; + +static struct clk_branch gcc_blsp1_sleep_clk = { + .halt_reg = 0x01004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data) { + .name = "gcc_blsp1_sleep_clk", + .parent_data = gcc_sleep_clk_data, + .num_parents = ARRAY_SIZE(gcc_sleep_clk_data), + .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", + .parent_hws = (const struct clk_hw*[]) { + &pcnoc_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + } + } +}; + +static struct clk_branch gcc_crypto_clk = { + .halt_reg = 0x1601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data) { + .name = "gcc_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &crypto_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + } + } +}; + +static struct clk_branch gcc_crypto_ahb_clk = { + .halt_reg = 0x16024, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) { + .name = "gcc_crypto_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &pcnoc_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + } + } +}; + +static struct clk_branch gcc_crypto_axi_clk = { + .halt_reg = 0x16020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data) { + .name = "gcc_crypto_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &pcnoc_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + } + } +}; + +static struct clk_branch gcc_gfx_tbu_clk = { + .halt_reg = 0x12010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data) { + .name = "gcc_gfx_tbu_clk", + .parent_hws = (const struct clk_hw*[]) { + &bimc_ddr_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + } + } +}; + +static struct clk_branch gcc_gfx_tcu_clk = { + .halt_reg = 0x12020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data) { + .name = "gcc_gfx_tcu_clk", + .parent_hws = (const struct clk_hw*[]) { + &bimc_ddr_clk_src.clkr.hw, + }, |