// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <dt-bindings/clock/qcom,shikra-audiocorecc.h>
#include "clk-alpha-pll.h"
#include "clk-branch.h"
#include "clk-pll.h"
#include "clk-rcg.h"
#include "clk-regmap.h"
#include "clk-regmap-divider.h"
#include "clk-regmap-mux.h"
#include "common.h"
#include "reset.h"
enum {
DT_BI_TCXO,
DT_SLEEP_CLK,
DT_AUD_REF_CLK_SRC,
};
enum {
P_AUD_REF_CLK_SRC,
P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX,
P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2,
P_BI_TCXO,
P_SLEEP_CLK,
};
static const struct pll_vco spark_vco[] = {
{ 500000000, 1000000000, 2 },
};
/* 614.4 MHz Configuration */
static const struct alpha_pll_config audio_core_cc_dig_pll_config = {
.l = 0x20,
.alpha = 0x0,
.vco_val = BIT(21),
.post_div_val = 0x28100,
.post_div_mask = GENMASK(17, 8),
.vco_mask = GENMASK(21, 20),
.main_output_mask = BIT(0),
.aux_output_mask = BIT(1),
.aux2_output_mask = BIT(2),
.config_ctl_val = 0x4001055b,
.test_ctl_hi_val = 0x1,
.test_ctl_hi_mask = 0x1,
};
static struct clk_alpha_pll audio_core_cc_dig_pll = {
.offset = 0x0,
.config = &audio_core_cc_dig_pll_config,
.vco_table = spark_vco,
.num_vco = ARRAY_SIZE(spark_vco),
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
.clkr = {
.hw.init = &(const struct clk_init_data) {
.name = "audio_core_cc_dig_pll",
.parent_data = &(const struct clk_parent_data) {
.index = DT_BI_TCXO,
},
.num_parents = 1,
.ops = &clk_alpha_pll_fixed_ops,
},
},
};
static struct clk_fixed_factor audio_core_cc_dig_pll_out_aux = {
.mult = 1,
.div = 5,
.hw.init = &(struct clk_init_data) {
.name = "audio_core_cc_dig_pll_out_aux",
.parent_data = &(const struct clk_parent_data) {
.hw = &audio_core_cc_dig_pll.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_fixed_factor_ops,
},
};
static struct clk_fixed_factor audio_core_cc_dig_pll_out_aux2 = {
.mult = 1,
.div = 2,
.hw.init = &(struct clk_init_data) {
.name = "audio_core_cc_dig_pll_out_aux2",
.parent_data = &(const struct clk_parent_data) {
.hw = &audio_core_cc_dig_pll.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_fixed_factor_ops,
},
};
static const struct parent_map audio_core_cc_parent_map_0[] = {
{ P_BI_TCXO, 0 },
{ P_AUD_REF_CLK_SRC, 1 },
{ P_SLEEP_CLK, 2 },
{ P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 4 },
{ P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 6 },
};
static const struct clk_parent_data audio_core_cc_parent_data_0[] = {
{ .index = DT_BI_TCXO },
{ .index = DT_AUD_REF_CLK_SRC },
{ .index = DT_SLEEP_CLK },
{ .hw = &audio_core_cc_dig_pll_out_aux.hw },
{ .hw = &audio_core_cc_dig_pll_out_aux2.hw },
};
static const struct freq_tbl ftbl_audio_core_cc_aif_if0_clk_src[] = {
F(240000, P_BI_TCXO, 10, 1, 8),
F(256000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 32),
F(512000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 16),
F(768000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 16),
F(1024000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 8),
F(1536000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 8),
F(2048000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 4),
F(3072000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 4),
F(4096000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 2),
F(6144000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 2),
F(8192000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 0, 0),
F(9600000, P_BI_TCXO, 2, 0, 0),
F(12288000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 0, 0),
F(19200000, P_BI_TCXO, 1, 0, 0),
F(24576000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 5, 0, 0),
{ }
};
static struct clk_rcg2 audio_core_cc_aif_if0_clk_src = {
.cmd_rcgr = 0x104c,
.mnd_width = 16,
.hid_width = 5,
.parent_map = audio_core_cc_parent_map_0,
.freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src,
.hw_clk_ctrl = true,
.clk