#include <linux/kernel.h>
#include <linux/err.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 <linux/math64.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <dt-bindings/clock/qcom,gcc-ipq4019.h>
#include "common.h"
#include "clk-regmap.h"
#include "clk-rcg.h"
#include "clk-branch.h"
#include "reset.h"
#include "clk-regmap-divider.h"
#define to_clk_regmap_div(_hw) …
#define to_clk_fepll(_hw) …
enum { … };
struct clk_fepll_vco { … };
struct clk_fepll { … };
static const int gcc_ipq4019_cpu_safe_parent = …;
static u64 clk_fepll_vco_calc_rate(struct clk_fepll *pll_div,
unsigned long parent_rate)
{ … }
static const struct clk_fepll_vco gcc_apss_ddrpll_vco = …;
static const struct clk_fepll_vco gcc_fepll_vco = …;
static long clk_cpu_div_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *p_rate)
{
struct clk_fepll *pll = to_clk_fepll(hw);
struct clk_hw *p_hw;
const struct freq_tbl *f;
f = qcom_find_freq(pll->freq_tbl, rate);
if (!f)
return -EINVAL;
p_hw = clk_hw_get_parent_by_index(hw, f->src);
*p_rate = clk_hw_get_rate(p_hw);
return f->freq;
};
static int clk_cpu_div_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_fepll *pll = to_clk_fepll(hw);
const struct freq_tbl *f;
u32 mask;
f = qcom_find_freq(pll->freq_tbl, rate);
if (!f)
return -EINVAL;
mask = (BIT(pll->cdiv.width) - 1) << pll->cdiv.shift;
regmap_update_bits(pll->cdiv.clkr.regmap,
pll->cdiv.reg, mask,
f->pre_div << pll->cdiv.shift);
udelay(1);
return 0;
};
static unsigned long
clk_cpu_div_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_fepll *pll = to_clk_fepll(hw);
u32 cdiv, pre_div;
u64 rate;
regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv);
cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1);
if (cdiv > 10)
pre_div = (cdiv + 1) * 2;
else
pre_div = cdiv + 12;
rate = clk_fepll_vco_calc_rate(pll, parent_rate) * 2;
do_div(rate, pre_div);
return rate;
};
static const struct clk_ops clk_regmap_cpu_div_ops = …;
static const struct freq_tbl ftbl_apss_ddr_pll[] = …;
static struct clk_fepll gcc_apss_cpu_plldiv_clk = …;
static unsigned long
clk_regmap_clk_div_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_fepll *pll = to_clk_fepll(hw);
u32 cdiv, pre_div = 1;
u64 rate;
const struct clk_div_table *clkt;
if (pll->fixed_div) {
pre_div = pll->fixed_div;
} else {
regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv);
cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1);
for (clkt = pll->div_table; clkt->div; clkt++) {
if (clkt->val == cdiv)
pre_div = clkt->div;
}
}
rate = clk_fepll_vco_calc_rate(pll, parent_rate);
do_div(rate, pre_div);
return rate;
};
static const struct clk_ops clk_fepll_div_ops = …;
static struct clk_fepll gcc_apss_sdcc_clk = …;
static struct clk_fepll gcc_fepll125_clk = …;
static struct clk_fepll gcc_fepll125dly_clk = …;
static struct clk_fepll gcc_fepll200_clk = …;
static struct clk_fepll gcc_fepll500_clk = …;
static const struct clk_div_table fepllwcss_clk_div_table[] = …;
static struct clk_fepll gcc_fepllwcss2g_clk = …;
static struct clk_fepll gcc_fepllwcss5g_clk = …;
static struct parent_map gcc_xo_200_500_map[] = …;
static const struct clk_parent_data gcc_xo_200_500[] = …;
static const struct freq_tbl ftbl_gcc_pcnoc_ahb_clk[] = …;
static struct clk_rcg2 gcc_pcnoc_ahb_clk_src = …;
static struct clk_branch pcnoc_clk_src = …;
static struct parent_map gcc_xo_200_map[] = …;
static const struct clk_parent_data gcc_xo_200[] = …;
static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = …;
static struct clk_rcg2 audio_clk_src = …;
static struct clk_branch gcc_audio_ahb_clk = …;
static struct clk_branch gcc_audio_pwm_clk = …;
static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_i2c_apps_clk[] = …;
static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = …;
static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = …;
static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = …;
static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = …;
static struct parent_map gcc_xo_200_spi_map[] = …;
static const struct clk_parent_data gcc_xo_200_spi[] = …;
static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_spi_apps_clk[] = …;
static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = …;
static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = …;
static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = …;
static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = …;
static const struct freq_tbl ftbl_gcc_blsp1_uart1_2_apps_clk[] = …;
static struct clk_rcg2 blsp1_uart1_apps_clk_src = …;
static struct clk_branch gcc_blsp1_uart1_apps_clk = …;
static struct clk_rcg2 blsp1_uart2_apps_clk_src = …;
static struct clk_branch gcc_blsp1_uart2_apps_clk = …;
static const struct freq_tbl ftbl_gcc_gp_clk[] = …;
static struct clk_rcg2 gp1_clk_src = …;
static struct clk_branch gcc_gp1_clk = …;
static struct clk_rcg2 gp2_clk_src = …;
static struct clk_branch gcc_gp2_clk = …;
static struct clk_rcg2 gp3_clk_src = …;
static struct clk_branch gcc_gp3_clk = …;
static struct parent_map gcc_xo_sdcc1_500_map[] = …;
static const struct clk_parent_data gcc_xo_sdcc1_500[] = …;
static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = …;
static struct clk_rcg2 sdcc1_apps_clk_src = …;
static const struct freq_tbl ftbl_gcc_apps_clk[] = …;
static struct parent_map gcc_xo_ddr_500_200_map[] = …;
static const struct clk_parent_data gcc_xo_ddr_500_200[] = …;
static struct clk_rcg2 apps_clk_src = …;
static const struct freq_tbl ftbl_gcc_apps_ahb_clk[] = …;
static struct clk_rcg2 apps_ahb_clk_src = …;
static struct clk_branch gcc_apss_ahb_clk = …;
static struct clk_branch gcc_blsp1_ahb_clk = …;
static struct clk_branch gcc_dcd_xo_clk = …;
static struct clk_branch gcc_boot_rom_ahb_clk = …;
static struct clk_branch gcc_crypto_ahb_clk = …;
static struct clk_branch gcc_crypto_axi_clk = …;
static struct clk_branch gcc_crypto_clk = …;
static struct parent_map gcc_xo_125_dly_map[] = …;
static const struct clk_parent_data gcc_xo_125_dly[] = …;
static const struct freq_tbl ftbl_gcc_fephy_dly_clk[] = …;
static struct clk_rcg2 fephy_125m_dly_clk_src = …;
static struct clk_branch gcc_ess_clk = …;
static struct clk_branch gcc_imem_axi_clk = …;
static struct clk_branch gcc_imem_cfg_ahb_clk = …;
static struct clk_branch gcc_pcie_ahb_clk = …;
static struct clk_branch gcc_pcie_axi_m_clk = …;
static struct clk_branch gcc_pcie_axi_s_clk = …;
static struct clk_branch gcc_prng_ahb_clk = …;
static struct clk_branch gcc_qpic_ahb_clk = …;
static struct clk_branch gcc_qpic_clk = …;
static struct clk_branch gcc_sdcc1_ahb_clk = …;
static struct clk_branch gcc_sdcc1_apps_clk = …;
static struct clk_branch gcc_tlmm_ahb_clk = …;
static struct clk_branch gcc_usb2_master_clk = …;
static struct clk_branch gcc_usb2_sleep_clk = …;
static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = …;
static struct clk_rcg2 usb30_mock_utmi_clk_src = …;
static struct clk_branch gcc_usb2_mock_utmi_clk = …;
static struct clk_branch gcc_usb3_master_clk = …;
static struct clk_branch gcc_usb3_sleep_clk = …;
static struct clk_branch gcc_usb3_mock_utmi_clk = …;
static struct parent_map gcc_xo_wcss2g_map[] = …;
static const struct clk_parent_data gcc_xo_wcss2g[] = …;
static const struct freq_tbl ftbl_gcc_wcss2g_clk[] = …;
static struct clk_rcg2 wcss2g_clk_src = …;
static struct clk_branch gcc_wcss2g_clk = …;
static struct clk_branch gcc_wcss2g_ref_clk = …;
static struct clk_branch gcc_wcss2g_rtc_clk = …;
static struct parent_map gcc_xo_wcss5g_map[] = …;
static const struct clk_parent_data gcc_xo_wcss5g[] = …;
static const struct freq_tbl ftbl_gcc_wcss5g_clk[] = …;
static struct clk_rcg2 wcss5g_clk_src = …;
static struct clk_branch gcc_wcss5g_clk = …;
static struct clk_branch gcc_wcss5g_ref_clk = …;
static struct clk_branch gcc_wcss5g_rtc_clk = …;
static struct clk_regmap *gcc_ipq4019_clocks[] = …;
static const struct qcom_reset_map gcc_ipq4019_resets[] = …;
static const struct regmap_config gcc_ipq4019_regmap_config = …;
static const struct qcom_cc_desc gcc_ipq4019_desc = …;
static const struct of_device_id gcc_ipq4019_match_table[] = …;
MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table);
static int
gcc_ipq4019_cpu_clk_notifier_fn(struct notifier_block *nb,
unsigned long action, void *data)
{ … }
static struct notifier_block gcc_ipq4019_cpu_clk_notifier = …;
static int gcc_ipq4019_probe(struct platform_device *pdev)
{ … }
static struct platform_driver gcc_ipq4019_driver = …;
static int __init gcc_ipq4019_init(void)
{ … }
core_initcall(gcc_ipq4019_init);
static void __exit gcc_ipq4019_exit(void)
{ … }
module_exit(gcc_ipq4019_exit);
MODULE_ALIAS(…) …;
MODULE_LICENSE(…) …;
MODULE_DESCRIPTION(…) …;