Some RCG frequency can be reached by multiple configuration. Add clk_rcg2_fm_ops ops to support these special RCG configurations. These alternative ops will select the frequency using a CEIL policy. When the correct frequency is found, the correct config is selected by calculating the final rate (by checking the defined parent and values in the config that is being checked) and deciding based on the one that is less different than the requested one. These check are skipped if there is just one config for the requested freq. qcom_find_freq_multi is added to search the freq with the new struct freq_multi_tbl. __clk_rcg2_select_conf is used to select the correct conf by simulating the final clock. If a conf can't be found due to parent not reachable, a WARN is printed and -EINVAL is returned. Tested-by: Wei Lei <quic_leiwei@quicinc.com> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> Acked-by: Stephen Boyd <sboyd@kernel.org> Link: https://lore.kernel.org/r/20231220221724.3822-3-ansuelsmth@gmail.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
71 lines
2.1 KiB
C
71 lines
2.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Copyright (c) 2014, The Linux Foundation. All rights reserved. */
|
|
|
|
#ifndef __QCOM_CLK_COMMON_H__
|
|
#define __QCOM_CLK_COMMON_H__
|
|
|
|
struct platform_device;
|
|
struct regmap_config;
|
|
struct clk_regmap;
|
|
struct qcom_reset_map;
|
|
struct regmap;
|
|
struct freq_tbl;
|
|
struct clk_hw;
|
|
|
|
#define PLL_LOCK_COUNT_SHIFT 8
|
|
#define PLL_LOCK_COUNT_MASK 0x3f
|
|
#define PLL_BIAS_COUNT_SHIFT 14
|
|
#define PLL_BIAS_COUNT_MASK 0x3f
|
|
#define PLL_VOTE_FSM_ENA BIT(20)
|
|
#define PLL_VOTE_FSM_RESET BIT(21)
|
|
|
|
struct qcom_cc_desc {
|
|
const struct regmap_config *config;
|
|
struct clk_regmap **clks;
|
|
size_t num_clks;
|
|
const struct qcom_reset_map *resets;
|
|
size_t num_resets;
|
|
struct gdsc **gdscs;
|
|
size_t num_gdscs;
|
|
struct clk_hw **clk_hws;
|
|
size_t num_clk_hws;
|
|
};
|
|
|
|
/**
|
|
* struct parent_map - map table for source select configuration values
|
|
* @src: source
|
|
* @cfg: configuration value
|
|
*/
|
|
struct parent_map {
|
|
u8 src;
|
|
u8 cfg;
|
|
};
|
|
|
|
extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
|
|
unsigned long rate);
|
|
extern const struct freq_tbl *qcom_find_freq_floor(const struct freq_tbl *f,
|
|
unsigned long rate);
|
|
extern const struct freq_multi_tbl *qcom_find_freq_multi(const struct freq_multi_tbl *f,
|
|
unsigned long rate);
|
|
extern void
|
|
qcom_pll_set_fsm_mode(struct regmap *m, u32 reg, u8 bias_count, u8 lock_count);
|
|
extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map,
|
|
u8 src);
|
|
extern int qcom_find_cfg_index(struct clk_hw *hw, const struct parent_map *map,
|
|
u8 cfg);
|
|
|
|
extern int qcom_cc_register_board_clk(struct device *dev, const char *path,
|
|
const char *name, unsigned long rate);
|
|
extern int qcom_cc_register_sleep_clk(struct device *dev);
|
|
|
|
extern struct regmap *qcom_cc_map(struct platform_device *pdev,
|
|
const struct qcom_cc_desc *desc);
|
|
extern int qcom_cc_really_probe(struct platform_device *pdev,
|
|
const struct qcom_cc_desc *desc,
|
|
struct regmap *regmap);
|
|
extern int qcom_cc_probe(struct platform_device *pdev,
|
|
const struct qcom_cc_desc *desc);
|
|
extern int qcom_cc_probe_by_index(struct platform_device *pdev, int index,
|
|
const struct qcom_cc_desc *desc);
|
|
|
|
#endif
|