diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:17:46 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:17:46 +0000 |
commit | 7f3a4257159dea8e7ef66d1a539dc6df708b8ed3 (patch) | |
tree | bcc69b5f4609f348fac49e2f59e210b29eaea783 /drivers/clk/qcom | |
parent | Adding upstream version 6.9.12. (diff) | |
download | linux-7f3a4257159dea8e7ef66d1a539dc6df708b8ed3.tar.xz linux-7f3a4257159dea8e7ef66d1a539dc6df708b8ed3.zip |
Adding upstream version 6.10.3.upstream/6.10.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/clk/qcom')
-rw-r--r-- | drivers/clk/qcom/apss-ipq-pll.c | 56 | ||||
-rw-r--r-- | drivers/clk/qcom/camcc-sc7280.c | 5 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-alpha-pll.c | 21 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-alpha-pll.h | 5 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-cbf-8996.c | 13 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-rcg.h | 24 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-rcg2.c | 198 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-rpm.c | 1 | ||||
-rw-r--r-- | drivers/clk/qcom/common.c | 18 | ||||
-rw-r--r-- | drivers/clk/qcom/common.h | 2 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-ipq8074.c | 120 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-msm8917.c | 1 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-msm8953.c | 1 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-sa8775p.c | 40 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-sc7280.c | 3 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-sm8150.c | 61 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-x1e80100.c | 46 | ||||
-rw-r--r-- | drivers/clk/qcom/gpucc-sa8775p.c | 41 | ||||
-rw-r--r-- | drivers/clk/qcom/gpucc-sm8350.c | 5 | ||||
-rw-r--r-- | drivers/clk/qcom/hfpll.c | 6 | ||||
-rw-r--r-- | drivers/clk/qcom/kpss-xcc.c | 4 |
21 files changed, 458 insertions, 213 deletions
diff --git a/drivers/clk/qcom/apss-ipq-pll.c b/drivers/clk/qcom/apss-ipq-pll.c index e12bb9abf6..e8632db2c5 100644 --- a/drivers/clk/qcom/apss-ipq-pll.c +++ b/drivers/clk/qcom/apss-ipq-pll.c @@ -8,43 +8,14 @@ #include "clk-alpha-pll.h" -/* - * Even though APSS PLL type is of existing one (like Huayra), its offsets - * are different from the one mentioned in the clk-alpha-pll.c, since the - * PLL is specific to APSS, so lets the define the same. - */ -static const u8 ipq_pll_offsets[][PLL_OFF_MAX_REGS] = { - [CLK_ALPHA_PLL_TYPE_HUAYRA] = { - [PLL_OFF_L_VAL] = 0x08, - [PLL_OFF_ALPHA_VAL] = 0x10, - [PLL_OFF_USER_CTL] = 0x18, - [PLL_OFF_CONFIG_CTL] = 0x20, - [PLL_OFF_CONFIG_CTL_U] = 0x24, - [PLL_OFF_STATUS] = 0x28, - [PLL_OFF_TEST_CTL] = 0x30, - [PLL_OFF_TEST_CTL_U] = 0x34, - }, - [CLK_ALPHA_PLL_TYPE_STROMER_PLUS] = { - [PLL_OFF_L_VAL] = 0x08, - [PLL_OFF_ALPHA_VAL] = 0x10, - [PLL_OFF_ALPHA_VAL_U] = 0x14, - [PLL_OFF_USER_CTL] = 0x18, - [PLL_OFF_USER_CTL_U] = 0x1c, - [PLL_OFF_CONFIG_CTL] = 0x20, - [PLL_OFF_STATUS] = 0x28, - [PLL_OFF_TEST_CTL] = 0x30, - [PLL_OFF_TEST_CTL_U] = 0x34, - }, -}; - static struct clk_alpha_pll ipq_pll_huayra = { .offset = 0x0, - .regs = ipq_pll_offsets[CLK_ALPHA_PLL_TYPE_HUAYRA], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_APSS], .flags = SUPPORTS_DYNAMIC_UPDATE, .clkr = { .enable_reg = 0x0, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "a53pll", .parent_data = &(const struct clk_parent_data) { .fw_name = "xo", @@ -57,12 +28,7 @@ static struct clk_alpha_pll ipq_pll_huayra = { static struct clk_alpha_pll ipq_pll_stromer = { .offset = 0x0, - /* - * Reuse CLK_ALPHA_PLL_TYPE_STROMER_PLUS register offsets. - * Although this is a bit confusing, but the offset values - * are correct nevertheless. - */ - .regs = ipq_pll_offsets[CLK_ALPHA_PLL_TYPE_STROMER_PLUS], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_STROMER], .flags = SUPPORTS_DYNAMIC_UPDATE, .clkr = { .enable_reg = 0x0, @@ -80,12 +46,16 @@ static struct clk_alpha_pll ipq_pll_stromer = { static struct clk_alpha_pll ipq_pll_stromer_plus = { .offset = 0x0, - .regs = ipq_pll_offsets[CLK_ALPHA_PLL_TYPE_STROMER_PLUS], + /* + * The register offsets of the Stromer Plus PLL used in IPQ5332 + * are the same as the Stromer PLL's offsets. + */ + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_STROMER], .flags = SUPPORTS_DYNAMIC_UPDATE, .clkr = { .enable_reg = 0x0, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(const struct clk_init_data) { .name = "a53pll", .parent_data = &(const struct clk_parent_data) { .fw_name = "xo", @@ -171,25 +141,25 @@ static const struct apss_pll_data ipq5018_pll_data = { .pll_config = &ipq5018_pll_config, }; -static struct apss_pll_data ipq5332_pll_data = { +static const struct apss_pll_data ipq5332_pll_data = { .pll_type = CLK_ALPHA_PLL_TYPE_STROMER_PLUS, .pll = &ipq_pll_stromer_plus, .pll_config = &ipq5332_pll_config, }; -static struct apss_pll_data ipq8074_pll_data = { +static const struct apss_pll_data ipq8074_pll_data = { .pll_type = CLK_ALPHA_PLL_TYPE_HUAYRA, .pll = &ipq_pll_huayra, .pll_config = &ipq8074_pll_config, }; -static struct apss_pll_data ipq6018_pll_data = { +static const struct apss_pll_data ipq6018_pll_data = { .pll_type = CLK_ALPHA_PLL_TYPE_HUAYRA, .pll = &ipq_pll_huayra, .pll_config = &ipq6018_pll_config, }; -static struct apss_pll_data ipq9574_pll_data = { +static const struct apss_pll_data ipq9574_pll_data = { .pll_type = CLK_ALPHA_PLL_TYPE_HUAYRA, .pll = &ipq_pll_huayra, .pll_config = &ipq9574_pll_config, diff --git a/drivers/clk/qcom/camcc-sc7280.c b/drivers/clk/qcom/camcc-sc7280.c index d89ddb2298..582fb3ba9c 100644 --- a/drivers/clk/qcom/camcc-sc7280.c +++ b/drivers/clk/qcom/camcc-sc7280.c @@ -2260,6 +2260,7 @@ static struct gdsc cam_cc_bps_gdsc = { .name = "cam_cc_bps_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = HW_CTRL | RETAIN_FF_ENABLE, }; @@ -2269,6 +2270,7 @@ static struct gdsc cam_cc_ife_0_gdsc = { .name = "cam_cc_ife_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = RETAIN_FF_ENABLE, }; @@ -2278,6 +2280,7 @@ static struct gdsc cam_cc_ife_1_gdsc = { .name = "cam_cc_ife_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = RETAIN_FF_ENABLE, }; @@ -2287,6 +2290,7 @@ static struct gdsc cam_cc_ife_2_gdsc = { .name = "cam_cc_ife_2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = RETAIN_FF_ENABLE, }; @@ -2296,6 +2300,7 @@ static struct gdsc cam_cc_ipe_0_gdsc = { .name = "cam_cc_ipe_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, .flags = HW_CTRL | RETAIN_FF_ENABLE, }; diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 003308a288..c51647e37d 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -83,6 +83,16 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL_U] = 0x20, [PLL_OFF_STATUS] = 0x24, }, + [CLK_ALPHA_PLL_TYPE_HUAYRA_APSS] = { + [PLL_OFF_L_VAL] = 0x08, + [PLL_OFF_ALPHA_VAL] = 0x10, + [PLL_OFF_USER_CTL] = 0x18, + [PLL_OFF_CONFIG_CTL] = 0x20, + [PLL_OFF_CONFIG_CTL_U] = 0x24, + [PLL_OFF_STATUS] = 0x28, + [PLL_OFF_TEST_CTL] = 0x30, + [PLL_OFF_TEST_CTL_U] = 0x34, + }, [CLK_ALPHA_PLL_TYPE_BRAMMO] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, @@ -213,9 +223,9 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_USER_CTL] = 0x18, [PLL_OFF_USER_CTL_U] = 0x1c, [PLL_OFF_CONFIG_CTL] = 0x20, + [PLL_OFF_STATUS] = 0x28, [PLL_OFF_TEST_CTL] = 0x30, [PLL_OFF_TEST_CTL_U] = 0x34, - [PLL_OFF_STATUS] = 0x28, }, [CLK_ALPHA_PLL_TYPE_STROMER_PLUS] = { [PLL_OFF_L_VAL] = 0x04, @@ -2113,6 +2123,15 @@ void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regma { u32 lval = config->l; + /* + * If the bootloader left the PLL enabled it's likely that there are + * RCGs that will lock up if we disable the PLL below. + */ + if (trion_pll_is_enabled(pll, regmap)) { + pr_debug("Lucid Evo PLL is already enabled, skipping configuration\n"); + return; + } + lval |= TRION_PLL_CAL_VAL << LUCID_EVO_PLL_CAL_L_VAL_SHIFT; clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), lval); clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index fb6d50263b..c7055b6c42 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -15,6 +15,7 @@ enum { CLK_ALPHA_PLL_TYPE_DEFAULT, CLK_ALPHA_PLL_TYPE_HUAYRA, + CLK_ALPHA_PLL_TYPE_HUAYRA_APSS, CLK_ALPHA_PLL_TYPE_BRAMMO, CLK_ALPHA_PLL_TYPE_FABIA, CLK_ALPHA_PLL_TYPE_TRION, @@ -73,8 +74,10 @@ struct pll_vco { /** * struct clk_alpha_pll - phase locked loop (PLL) * @offset: base address of registers - * @vco_table: array of VCO settings * @regs: alpha pll register map (see @clk_alpha_pll_regs) + * @vco_table: array of VCO settings + * @num_vco: number of VCO settings in @vco_table + * @flags: bitmask to indicate features supported by the hardware * @clkr: regmap clock handle */ struct clk_alpha_pll { diff --git a/drivers/clk/qcom/clk-cbf-8996.c b/drivers/clk/qcom/clk-cbf-8996.c index fe24b4abea..76bf523431 100644 --- a/drivers/clk/qcom/clk-cbf-8996.c +++ b/drivers/clk/qcom/clk-cbf-8996.c @@ -41,17 +41,6 @@ enum { #define CBF_PLL_OFFSET 0xf000 -static const u8 cbf_pll_regs[PLL_OFF_MAX_REGS] = { - [PLL_OFF_L_VAL] = 0x08, - [PLL_OFF_ALPHA_VAL] = 0x10, - [PLL_OFF_USER_CTL] = 0x18, - [PLL_OFF_CONFIG_CTL] = 0x20, - [PLL_OFF_CONFIG_CTL_U] = 0x24, - [PLL_OFF_TEST_CTL] = 0x30, - [PLL_OFF_TEST_CTL_U] = 0x34, - [PLL_OFF_STATUS] = 0x28, -}; - static struct alpha_pll_config cbfpll_config = { .l = 72, .config_ctl_val = 0x200d4828, @@ -67,7 +56,7 @@ static struct alpha_pll_config cbfpll_config = { static struct clk_alpha_pll cbf_pll = { .offset = CBF_PLL_OFFSET, - .regs = cbf_pll_regs, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_APSS], .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE, .clkr.hw.init = &(struct clk_init_data){ .name = "cbf_pll", diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index e6d84c8c79..d7414361e4 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -17,6 +17,23 @@ struct freq_tbl { u16 n; }; +#define C(s, h, m, n) { (s), (2 * (h) - 1), (m), (n) } +#define FM(f, confs) { (f), ARRAY_SIZE(confs), (confs) } +#define FMS(f, s, h, m, n) { (f), 1, (const struct freq_conf []){ C(s, h, m, n) } } + +struct freq_conf { + u8 src; + u8 pre_div; + u16 m; + u16 n; +}; + +struct freq_multi_tbl { + unsigned long freq; + size_t num_confs; + const struct freq_conf *confs; +}; + /** * struct mn - M/N:D counter * @mnctr_en_bit: bit to enable mn counter @@ -138,6 +155,7 @@ extern const struct clk_ops clk_dyn_rcg_ops; * @safe_src_index: safe src index value * @parent_map: map from software's parent index to hardware's src_sel field * @freq_tbl: frequency table + * @freq_multi_tbl: frequency table for clocks reachable with multiple RCGs conf * @clkr: regmap clock handle * @cfg_off: defines the cfg register offset from the CMD_RCGR + CFG_REG * @parked_cfg: cached value of the CFG register for parked RCGs @@ -149,7 +167,10 @@ struct clk_rcg2 { u8 hid_width; u8 safe_src_index; const struct parent_map *parent_map; - const struct freq_tbl *freq_tbl; + union { + const struct freq_tbl *freq_tbl; + const struct freq_multi_tbl *freq_multi_tbl; + }; struct clk_regmap clkr; u8 cfg_off; u32 parked_cfg; @@ -169,6 +190,7 @@ struct clk_rcg2_gfx3d { extern const struct clk_ops clk_rcg2_ops; extern const struct clk_ops clk_rcg2_floor_ops; +extern const struct clk_ops clk_rcg2_fm_ops; extern const struct clk_ops clk_rcg2_mux_closest_ops; extern const struct clk_ops clk_edp_pixel_ops; extern const struct clk_ops clk_byte_ops; diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 5183c74b07..30b19bd39d 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -260,6 +260,115 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, return 0; } +static const struct freq_conf * +__clk_rcg2_select_conf(struct clk_hw *hw, const struct freq_multi_tbl *f, + unsigned long req_rate) +{ + unsigned long rate_diff, best_rate_diff = ULONG_MAX; + const struct freq_conf *conf, *best_conf = NULL; + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + const char *name = clk_hw_get_name(hw); + unsigned long parent_rate, rate; + struct clk_hw *p; + int index, i; + + /* Exit early if only one config is defined */ + if (f->num_confs == 1) { + best_conf = f->confs; + goto exit; + } + + /* Search in each provided config the one that is near the wanted rate */ + for (i = 0, conf = f->confs; i < f->num_confs; i++, conf++) { + index = qcom_find_src_index(hw, rcg->parent_map, conf->src); + if (index < 0) + continue; + + p = clk_hw_get_parent_by_index(hw, index); + if (!p) + continue; + + parent_rate = clk_hw_get_rate(p); + rate = calc_rate(parent_rate, conf->n, conf->m, conf->n, conf->pre_div); + + if (rate == req_rate) { + best_conf = conf; + goto exit; + } + + rate_diff = abs_diff(req_rate, rate); + if (rate_diff < best_rate_diff) { + best_rate_diff = rate_diff; + best_conf = conf; + } + } + + /* + * Very unlikely. Warn if we couldn't find a correct config + * due to parent not found in every config. + */ + if (unlikely(!best_conf)) { + WARN(1, "%s: can't find a configuration for rate %lu\n", + name, req_rate); + return ERR_PTR(-EINVAL); + } + +exit: + return best_conf; +} + +static int _freq_tbl_fm_determine_rate(struct clk_hw *hw, const struct freq_multi_tbl *f, + struct clk_rate_request *req) +{ + unsigned long clk_flags, rate = req->rate; + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + const struct freq_conf *conf; + struct clk_hw *p; + int index; + + f = qcom_find_freq_multi(f, rate); + if (!f || !f->confs) + return -EINVAL; + + conf = __clk_rcg2_select_conf(hw, f, rate); + if (IS_ERR(conf)) + return PTR_ERR(conf); + index = qcom_find_src_index(hw, rcg->parent_map, conf->src); + if (index < 0) + return index; + + clk_flags = clk_hw_get_flags(hw); + p = clk_hw_get_parent_by_index(hw, index); + if (!p) + return -EINVAL; + + if (clk_flags & CLK_SET_RATE_PARENT) { + rate = f->freq; + if (conf->pre_div) { + if (!rate) + rate = req->rate; + rate /= 2; + rate *= conf->pre_div + 1; + } + + if (conf->n) { + u64 tmp = rate; + + tmp = tmp * conf->n; + do_div(tmp, conf->m); + rate = tmp; + } + } else { + rate = clk_hw_get_rate(p); + } + + req->best_parent_hw = p; + req->best_parent_rate = rate; + req->rate = f->freq; + + return 0; +} + static int clk_rcg2_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { @@ -276,6 +385,14 @@ static int clk_rcg2_determine_floor_rate(struct clk_hw *hw, return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, FLOOR); } +static int clk_rcg2_fm_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + + return _freq_tbl_fm_determine_rate(hw, rcg->freq_multi_tbl, req); +} + static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f, u32 *_cfg) { @@ -371,6 +488,30 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate, return clk_rcg2_configure(rcg, f); } +static int __clk_rcg2_fm_set_rate(struct clk_hw *hw, unsigned long rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + const struct freq_multi_tbl *f; + const struct freq_conf *conf; + struct freq_tbl f_tbl = {}; + + f = qcom_find_freq_multi(rcg->freq_multi_tbl, rate); + if (!f || !f->confs) + return -EINVAL; + + conf = __clk_rcg2_select_conf(hw, f, rate); + if (IS_ERR(conf)) + return PTR_ERR(conf); + + f_tbl.freq = f->freq; + f_tbl.src = conf->src; + f_tbl.pre_div = conf->pre_div; + f_tbl.m = conf->m; + f_tbl.n = conf->n; + + return clk_rcg2_configure(rcg, &f_tbl); +} + static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -383,6 +524,12 @@ static int clk_rcg2_set_floor_rate(struct clk_hw *hw, unsigned long rate, return __clk_rcg2_set_rate(hw, rate, FLOOR); } +static int clk_rcg2_fm_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return __clk_rcg2_fm_set_rate(hw, rate); +} + static int clk_rcg2_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate, u8 index) { @@ -395,6 +542,12 @@ static int clk_rcg2_set_floor_rate_and_parent(struct clk_hw *hw, return __clk_rcg2_set_rate(hw, rate, FLOOR); } +static int clk_rcg2_fm_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate, u8 index) +{ + return __clk_rcg2_fm_set_rate(hw, rate); +} + static int clk_rcg2_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); @@ -505,6 +658,19 @@ const struct clk_ops clk_rcg2_floor_ops = { }; EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops); +const struct clk_ops clk_rcg2_fm_ops = { + .is_enabled = clk_rcg2_is_enabled, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .determine_rate = clk_rcg2_fm_determine_rate, + .set_rate = clk_rcg2_fm_set_rate, + .set_rate_and_parent = clk_rcg2_fm_set_rate_and_parent, + .get_duty_cycle = clk_rcg2_get_duty_cycle, + .set_duty_cycle = clk_rcg2_set_duty_cycle, +}; +EXPORT_SYMBOL_GPL(clk_rcg2_fm_ops); + const struct clk_ops clk_rcg2_mux_closest_ops = { .determine_rate = __clk_mux_determine_rate_closest, .get_parent = clk_rcg2_get_parent, @@ -1138,7 +1304,39 @@ clk_rcg2_shared_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) return clk_rcg2_recalc_rate(hw, parent_rate); } +static int clk_rcg2_shared_init(struct clk_hw *hw) +{ + /* + * This does a few things: + * + * 1. Sets rcg->parked_cfg to reflect the value at probe so that the + * proper parent is reported from clk_rcg2_shared_get_parent(). + * + * 2. Clears the force enable bit of the RCG because we rely on child + * clks (branches) to turn the RCG on/off with a hardware feedback + * mechanism and only set the force enable bit in the RCG when we + * want to make sure the clk stays on for parent switches or + * parking. + * + * 3. Parks shared RCGs on the safe source at registration because we + * can't be certain that the parent clk will stay on during boot, + * especially if the parent is shared. If this RCG is enabled at + * boot, and the parent is turned off, the RCG will get stuck on. A + * GDSC can wedge if is turned on and the RCG is stuck on because + * the GDSC's controller will hang waiting for the clk status to + * toggle on when it never does. + * + * The safest option here is to "park" the RCG at init so that the clk + * can never get stuck on or off. This ensures the GDSC can't get + * wedged. + */ + clk_rcg2_shared_disable(hw); + + return 0; +} + const struct clk_ops clk_rcg2_shared_ops = { + .init = clk_rcg2_shared_init, .enable = clk_rcg2_shared_enable, .disable = clk_rcg2_shared_disable, .get_parent = clk_rcg2_shared_get_parent, diff --git a/drivers/clk/qcom/clk-rpm.c b/drivers/clk/qcom/clk-rpm.c index 745026ef4d..9da034f8f2 100644 --- a/drivers/clk/qcom/clk-rpm.c +++ b/drivers/clk/qcom/clk-rpm.c @@ -98,7 +98,6 @@ struct clk_rpm { }; struct rpm_cc { - struct qcom_rpm *rpm; struct clk_rpm **clks; size_t num_clks; u32 xo_buffer_value; diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 75f09e6e05..48f81e3a5e 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -41,6 +41,24 @@ struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate) } EXPORT_SYMBOL_GPL(qcom_find_freq); +const struct freq_multi_tbl *qcom_find_freq_multi(const struct freq_multi_tbl *f, + unsigned long rate) +{ + if (!f) + return NULL; + + if (!f->freq) + return f; + + for (; f->freq; f++) + if (rate <= f->freq) + return f; + + /* Default to our fastest rate */ + return f - 1; +} +EXPORT_SYMBOL_GPL(qcom_find_freq_multi); + const struct freq_tbl *qcom_find_freq_floor(const struct freq_tbl *f, unsigned long rate) { diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h index 9c8f7b798d..2d4a8a837e 100644 --- a/drivers/clk/qcom/common.h +++ b/drivers/clk/qcom/common.h @@ -45,6 +45,8 @@ 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, diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c index 7bc679871f..d2be56c589 100644 --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c @@ -1677,15 +1677,23 @@ static struct clk_regmap_div nss_port4_tx_div_clk_src = { }, }; -static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = { - F(19200000, P_XO, 1, 0, 0), - F(25000000, P_UNIPHY1_RX, 12.5, 0, 0), - F(25000000, P_UNIPHY0_RX, 5, 0, 0), - F(78125000, P_UNIPHY1_RX, 4, 0, 0), - F(125000000, P_UNIPHY1_RX, 2.5, 0, 0), - F(125000000, P_UNIPHY0_RX, 1, 0, 0), - F(156250000, P_UNIPHY1_RX, 2, 0, 0), - F(312500000, P_UNIPHY1_RX, 1, 0, 0), +static const struct freq_conf ftbl_nss_port5_rx_clk_src_25[] = { + C(P_UNIPHY1_RX, 12.5, 0, 0), + C(P_UNIPHY0_RX, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_port5_rx_clk_src_125[] = { + C(P_UNIPHY1_RX, 2.5, 0, 0), + C(P_UNIPHY0_RX, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_port5_rx_clk_src[] = { + FMS(19200000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_port5_rx_clk_src_25), + FMS(78125000, P_UNIPHY1_RX, 4, 0, 0), + FM(125000000, ftbl_nss_port5_rx_clk_src_125), + FMS(156250000, P_UNIPHY1_RX, 2, 0, 0), + FMS(312500000, P_UNIPHY1_RX, 1, 0, 0), { } }; @@ -1712,14 +1720,14 @@ gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map[] = { static struct clk_rcg2 nss_port5_rx_clk_src = { .cmd_rcgr = 0x68060, - .freq_tbl = ftbl_nss_port5_rx_clk_src, + .freq_multi_tbl = ftbl_nss_port5_rx_clk_src, .hid_width = 5, .parent_map = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port5_rx_clk_src", .parent_data = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias, .num_parents = ARRAY_SIZE(gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, }; @@ -1739,15 +1747,23 @@ static struct clk_regmap_div nss_port5_rx_div_clk_src = { }, }; -static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = { - F(19200000, P_XO, 1, 0, 0), - F(25000000, P_UNIPHY1_TX, 12.5, 0, 0), - F(25000000, P_UNIPHY0_TX, 5, 0, 0), - F(78125000, P_UNIPHY1_TX, 4, 0, 0), - F(125000000, P_UNIPHY1_TX, 2.5, 0, 0), - F(125000000, P_UNIPHY0_TX, 1, 0, 0), - F(156250000, P_UNIPHY1_TX, 2, 0, 0), - F(312500000, P_UNIPHY1_TX, 1, 0, 0), +static const struct freq_conf ftbl_nss_port5_tx_clk_src_25[] = { + C(P_UNIPHY1_TX, 12.5, 0, 0), + C(P_UNIPHY0_TX, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_port5_tx_clk_src_125[] = { + C(P_UNIPHY1_TX, 2.5, 0, 0), + C(P_UNIPHY0_TX, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_port5_tx_clk_src[] = { + FMS(19200000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_port5_tx_clk_src_25), + FMS(78125000, P_UNIPHY1_TX, 4, 0, 0), + FM(125000000, ftbl_nss_port5_tx_clk_src_125), + FMS(156250000, P_UNIPHY1_TX, 2, 0, 0), + FMS(312500000, P_UNIPHY1_TX, 1, 0, 0), { } }; @@ -1774,14 +1790,14 @@ gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map[] = { static struct clk_rcg2 nss_port5_tx_clk_src = { .cmd_rcgr = 0x68068, - .freq_tbl = ftbl_nss_port5_tx_clk_src, + .freq_multi_tbl = ftbl_nss_port5_tx_clk_src, .hid_width = 5, .parent_map = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port5_tx_clk_src", .parent_data = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias, .num_parents = ARRAY_SIZE(gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, }; @@ -1801,15 +1817,23 @@ static struct clk_regmap_div nss_port5_tx_div_clk_src = { }, }; -static const struct freq_tbl ftbl_nss_port6_rx_clk_src[] = { - F(19200000, P_XO, 1, 0, 0), - F(25000000, P_UNIPHY2_RX, 5, 0, 0), - F(25000000, P_UNIPHY2_RX, 12.5, 0, 0), - F(78125000, P_UNIPHY2_RX, 4, 0, 0), - F(125000000, P_UNIPHY2_RX, 1, 0, 0), - F(125000000, P_UNIPHY2_RX, 2.5, 0, 0), - F(156250000, P_UNIPHY2_RX, 2, 0, 0), - F(312500000, P_UNIPHY2_RX, 1, 0, 0), +static const struct freq_conf ftbl_nss_port6_rx_clk_src_25[] = { + C(P_UNIPHY2_RX, 5, 0, 0), + C(P_UNIPHY2_RX, 12.5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_port6_rx_clk_src_125[] = { + C(P_UNIPHY2_RX, 1, 0, 0), + C(P_UNIPHY2_RX, 2.5, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_port6_rx_clk_src[] = { + FMS(19200000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_port6_rx_clk_src_25), + FMS(78125000, P_UNIPHY2_RX, 4, 0, 0), + FM(125000000, ftbl_nss_port6_rx_clk_src_125), + FMS(156250000, P_UNIPHY2_RX, 2, 0, 0), + FMS(312500000, P_UNIPHY2_RX, 1, 0, 0), { } }; @@ -1831,14 +1855,14 @@ static const struct parent_map gcc_xo_uniphy2_rx_tx_ubi32_bias_map[] = { static struct clk_rcg2 nss_port6_rx_clk_src = { .cmd_rcgr = 0x68070, - .freq_tbl = ftbl_nss_port6_rx_clk_src, + .freq_multi_tbl = ftbl_nss_port6_rx_clk_src, .hid_width = 5, .parent_map = gcc_xo_uniphy2_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port6_rx_clk_src", .parent_data = gcc_xo_uniphy2_rx_tx_ubi32_bias, .num_parents = ARRAY_SIZE(gcc_xo_uniphy2_rx_tx_ubi32_bias), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, }; @@ -1858,15 +1882,23 @@ static struct clk_regmap_div nss_port6_rx_div_clk_src = { }, }; -static const struct freq_tbl ftbl_nss_port6_tx_clk_src[] = { - F(19200000, P_XO, 1, 0, 0), - F(25000000, P_UNIPHY2_TX, 5, 0, 0), - F(25000000, P_UNIPHY2_TX, 12.5, 0, 0), - F(78125000, P_UNIPHY2_TX, 4, 0, 0), - F(125000000, P_UNIPHY2_TX, 1, 0, 0), - F(125000000, P_UNIPHY2_TX, 2.5, 0, 0), - F(156250000, P_UNIPHY2_TX, 2, 0, 0), - F(312500000, P_UNIPHY2_TX, 1, 0, 0), +static const struct freq_conf ftbl_nss_port6_tx_clk_src_25[] = { + C(P_UNIPHY2_TX, 5, 0, 0), + C(P_UNIPHY2_TX, 12.5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_port6_tx_clk_src_125[] = { + C(P_UNIPHY2_TX, 1, 0, 0), + C(P_UNIPHY2_TX, 2.5, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_port6_tx_clk_src[] = { + FMS(19200000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_port6_tx_clk_src_25), + FMS(78125000, P_UNIPHY1_RX, 4, 0, 0), + FM(125000000, ftbl_nss_port6_tx_clk_src_125), + FMS(156250000, P_UNIPHY1_RX, 2, 0, 0), + FMS(312500000, P_UNIPHY1_RX, 1, 0, 0), { } }; @@ -1888,14 +1920,14 @@ static const struct parent_map gcc_xo_uniphy2_tx_rx_ubi32_bias_map[] = { static struct clk_rcg2 nss_port6_tx_clk_src = { .cmd_rcgr = 0x68078, - .freq_tbl = ftbl_nss_port6_tx_clk_src, + .freq_multi_tbl = ftbl_nss_port6_tx_clk_src, .hid_width = 5, .parent_map = gcc_xo_uniphy2_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port6_tx_clk_src", .parent_data = gcc_xo_uniphy2_tx_rx_ubi32_bias, .num_parents = ARRAY_SIZE(gcc_xo_uniphy2_tx_rx_ubi32_bias), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, }; diff --git a/drivers/clk/qcom/gcc-msm8917.c b/drivers/clk/qcom/gcc-msm8917.c index f2dd132e2f..f2b8729e41 100644 --- a/drivers/clk/qcom/gcc-msm8917.c +++ b/drivers/clk/qcom/gcc-msm8917.c @@ -3278,6 +3278,7 @@ static const struct of_device_id gcc_msm8917_match_table[] = { { .compatible = "qcom,gcc-qm215", .data = &gcc_qm215_desc }, {}, }; +MODULE_DEVICE_TABLE(of, gcc_msm8917_match_table); static struct platform_driver gcc_msm8917_driver = { .probe = gcc_msm8917_probe, diff --git a/drivers/clk/qcom/gcc-msm8953.c b/drivers/clk/qcom/gcc-msm8953.c index 68359534ff..7563bff581 100644 --- a/drivers/clk/qcom/gcc-msm8953.c +++ b/drivers/clk/qcom/gcc-msm8953.c @@ -4227,6 +4227,7 @@ static const struct of_device_id gcc_msm8953_match_table[] = { { .compatible = "qcom,gcc-msm8953" }, {}, }; +MODULE_DEVICE_TABLE(of, gcc_msm8953_match_table); static struct platform_driver gcc_msm8953_driver = { .probe = gcc_msm8953_probe, diff --git a/drivers/clk/qcom/gcc-sa8775p.c b/drivers/clk/qcom/gcc-sa8775p.c index 5bcbfbf52c..9bbc0836fa 100644 --- a/drivers/clk/qcom/gcc-sa8775p.c +++ b/drivers/clk/qcom/gcc-sa8775p.c @@ -4305,74 +4305,114 @@ static struct clk_branch gcc_video_axi1_clk = { static struct gdsc pcie_0_gdsc = { .gdscr = 0xa9004, + .collapse_ctrl = 0x4b104, + .collapse_mask = BIT(0), + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "pcie_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc pcie_1_gdsc = { .gdscr = 0x77004, + .collapse_ctrl = 0x4b104, + .collapse_mask = BIT(1), + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "pcie_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc ufs_card_gdsc = { .gdscr = 0x81004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "ufs_card_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc ufs_phy_gdsc = { .gdscr = 0x83004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "ufs_phy_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc usb20_prim_gdsc = { .gdscr = 0x1c004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "usb20_prim_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc usb30_prim_gdsc = { .gdscr = 0x1b004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "usb30_prim_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc usb30_sec_gdsc = { .gdscr = 0x2f004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "usb30_sec_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc emac0_gdsc = { .gdscr = 0xb6004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "emac0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct gdsc emac1_gdsc = { .gdscr = 0xb4004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "emac1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, }; static struct clk_regmap *gcc_sa8775p_clocks[] = { diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c index f45a831890..67ea9cf530 100644 --- a/drivers/clk/qcom/gcc-sc7280.c +++ b/drivers/clk/qcom/gcc-sc7280.c @@ -3463,6 +3463,9 @@ static int gcc_sc7280_probe(struct platform_device *pdev) qcom_branch_set_clk_en(regmap, 0x71004);/* GCC_GPU_CFG_AHB_CLK */ regmap_update_bits(regmap, 0x7100C, BIT(13), BIT(13)); + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, ARRAY_SIZE(gcc_dfs_clocks)); if (ret) diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c index a47ef9dfa8..1f748141d1 100644 --- a/drivers/clk/qcom/gcc-sm8150.c +++ b/drivers/clk/qcom/gcc-sm8150.c @@ -207,28 +207,6 @@ static const struct clk_parent_data gcc_parents_7[] = { { .hw = &gpll0_out_even.clkr.hw }, }; -static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { - F(19200000, P_BI_TCXO, 1, 0, 0), - F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0), - F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), - { } -}; - -static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { - .cmd_rcgr = 0x48014, - .mnd_width = 0, - .hid_width = 5, - .parent_map = gcc_parent_map_0, - .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_cpuss_ahb_clk_src", - .parent_data = gcc_parents_0, - .num_parents = ARRAY_SIZE(gcc_parents_0), - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, - }, -}; - static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src[] = { F(19200000, P_BI_TCXO, 1, 0, 0), F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), @@ -1361,24 +1339,6 @@ static struct clk_branch gcc_cfg_noc_usb3_sec_axi_clk = { }, }; -static struct clk_branch gcc_cpuss_ahb_clk = { - .halt_reg = 0x48000, - .halt_check = BRANCH_HALT_VOTED, - .clkr = { - .enable_reg = 0x52004, - .enable_mask = BIT(21), - .hw.init = &(struct clk_init_data){ - .name = "gcc_cpuss_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ - &gcc_cpuss_ahb_clk_src.clkr.hw }, - .num_parents = 1, - /* required for cpuss */ - .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_cpuss_dvm_bus_clk = { .halt_reg = 0x48190, .halt_check = BRANCH_HALT, @@ -2685,24 +2645,6 @@ static struct clk_branch gcc_sdcc4_apps_clk = { }, }; -static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = { - .halt_reg = 0x4819c, - .halt_check = BRANCH_HALT_VOTED, - .clkr = { - .enable_reg = 0x52004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_sys_noc_cpuss_ahb_clk", - .parent_hws = (const struct clk_hw *[]){ - &gcc_cpuss_ahb_clk_src.clkr.hw }, - .num_parents = 1, - /* required for cpuss */ - .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_tsif_ahb_clk = { .halt_reg = 0x36004, .halt_check = BRANCH_HALT, @@ -3550,8 +3492,6 @@ static struct clk_regmap *gcc_sm8150_clocks[] = { [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, [GCC_CFG_NOC_USB3_SEC_AXI_CLK] = &gcc_cfg_noc_usb3_sec_axi_clk.clkr, - [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr, - [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr, [GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr, [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr, [GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr, @@ -3669,7 +3609,6 @@ static struct clk_regmap *gcc_sm8150_clocks[] = { [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr, - [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr, [GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr, [GCC_TSIF_INACTIVITY_TIMERS_CLK] = &gcc_tsif_inactivity_timers_clk.clkr, [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr, diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index 1404017be9..a263f0c412 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -2812,7 +2812,7 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = { static struct clk_branch gcc_pcie_0_pipe_clk = { .halt_reg = 0xa0044, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52010, .enable_mask = BIT(25), @@ -2901,7 +2901,7 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = { static struct clk_branch gcc_pcie_1_pipe_clk = { .halt_reg = 0x2c044, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52020, .enable_mask = BIT(30), @@ -2990,7 +2990,7 @@ static struct clk_branch gcc_pcie_2_mstr_axi_clk = { static struct clk_branch gcc_pcie_2_pipe_clk = { .halt_reg = 0x13044, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52020, .enable_mask = BIT(23), @@ -3110,7 +3110,7 @@ static struct clk_branch gcc_pcie_3_phy_rchng_clk = { static struct clk_branch gcc_pcie_3_pipe_clk = { .halt_reg = 0x58050, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52020, .enable_mask = BIT(3), @@ -3235,7 +3235,7 @@ static struct clk_branch gcc_pcie_4_phy_rchng_clk = { static struct clk_branch gcc_pcie_4_pipe_clk = { .halt_reg = 0x6b044, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52008, .enable_mask = BIT(4), @@ -3360,7 +3360,7 @@ static struct clk_branch gcc_pcie_5_phy_rchng_clk = { static struct clk_branch gcc_pcie_5_pipe_clk = { .halt_reg = 0x2f044, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52018, .enable_mask = BIT(17), @@ -3498,7 +3498,7 @@ static struct clk_branch gcc_pcie_6a_phy_rchng_clk = { static struct clk_branch gcc_pcie_6a_pipe_clk = { .halt_reg = 0x31050, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52018, .enable_mask = BIT(26), @@ -3636,7 +3636,7 @@ static struct clk_branch gcc_pcie_6b_phy_rchng_clk = { static struct clk_branch gcc_pcie_6b_pipe_clk = { .halt_reg = 0x8d050, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52000, .enable_mask = BIT(30), @@ -5109,7 +5109,7 @@ static struct clk_branch gcc_usb3_mp_phy_com_aux_clk = { static struct clk_branch gcc_usb3_mp_phy_pipe_0_clk = { .halt_reg = 0x17290, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x17290, .enable_mask = BIT(0), @@ -5122,7 +5122,7 @@ static struct clk_branch gcc_usb3_mp_phy_pipe_0_clk = { static struct clk_branch gcc_usb3_mp_phy_pipe_1_clk = { .halt_reg = 0x17298, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x17298, .enable_mask = BIT(0), @@ -5186,7 +5186,7 @@ static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = { static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { .halt_reg = 0x39068, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x39068, .hwcg_bit = 1, .clkr = { @@ -5257,7 +5257,7 @@ static struct clk_regmap_mux gcc_usb3_sec_phy_pipe_clk_src = { static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { .halt_reg = 0xa1068, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0xa1068, .hwcg_bit = 1, .clkr = { @@ -5269,6 +5269,7 @@ static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5327,7 +5328,7 @@ static struct clk_regmap_mux gcc_usb3_tert_phy_pipe_clk_src = { static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { .halt_reg = 0xa2068, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0xa2068, .hwcg_bit = 1, .clkr = { @@ -5339,6 +5340,7 @@ static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5405,7 +5407,7 @@ static struct clk_branch gcc_usb4_0_master_clk = { static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { .halt_reg = 0x9f0d8, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x9f0d8, .enable_mask = BIT(0), @@ -5418,7 +5420,7 @@ static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { .halt_reg = 0x9f048, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52010, .enable_mask = BIT(19), @@ -5457,7 +5459,7 @@ static struct clk_branch gcc_usb4_0_phy_rx1_clk = { static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = { .halt_reg = 0x9f0a4, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x9f0a4, .hwcg_bit = 1, .clkr = { @@ -5582,7 +5584,7 @@ static struct clk_branch gcc_usb4_1_master_clk = { static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { .halt_reg = 0x2b0d8, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x2b0d8, .enable_mask = BIT(0), @@ -5595,7 +5597,7 @@ static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { .halt_reg = 0x2b048, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52028, .enable_mask = BIT(0), @@ -5634,7 +5636,7 @@ static struct clk_branch gcc_usb4_1_phy_rx1_clk = { static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = { .halt_reg = 0x2b0a4, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x2b0a4, .hwcg_bit = 1, .clkr = { @@ -5759,7 +5761,7 @@ static struct clk_branch gcc_usb4_2_master_clk = { static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { .halt_reg = 0x110d8, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x110d8, .enable_mask = BIT(0), @@ -5772,7 +5774,7 @@ static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { .halt_reg = 0x11048, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52028, .enable_mask = BIT(1), @@ -5811,7 +5813,7 @@ static struct clk_branch gcc_usb4_2_phy_rx1_clk = { static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = { .halt_reg = 0x110a4, - .halt_check = BRANCH_HALT_VOTED, + .halt_check = BRANCH_HALT_SKIP, .hwcg_reg = 0x110a4, .hwcg_bit = 1, .clkr = { diff --git a/drivers/clk/qcom/gpucc-sa8775p.c b/drivers/clk/qcom/gpucc-sa8775p.c index 1167c42da3..3deabf8333 100644 --- a/drivers/clk/qcom/gpucc-sa8775p.c +++ b/drivers/clk/qcom/gpucc-sa8775p.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, 2024, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2023, Linaro Limited */ @@ -161,7 +161,7 @@ static struct clk_rcg2 gpu_cc_ff_clk_src = { .name = "gpu_cc_ff_clk_src", .parent_data = gpu_cc_parent_data_0, .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -181,7 +181,7 @@ static struct clk_rcg2 gpu_cc_gmu_clk_src = { .parent_data = gpu_cc_parent_data_1, .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -200,7 +200,7 @@ static struct clk_rcg2 gpu_cc_hub_clk_src = { .name = "gpu_cc_hub_clk_src", .parent_data = gpu_cc_parent_data_2, .num_parents = ARRAY_SIZE(gpu_cc_parent_data_2), - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -280,7 +280,7 @@ static struct clk_branch gpu_cc_ahb_clk = { &gpu_cc_hub_ahb_div_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -294,8 +294,7 @@ static struct clk_branch gpu_cc_cb_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data){ .name = "gpu_cc_cb_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, + .ops = &clk_branch2_aon_ops, }, }, }; @@ -312,7 +311,7 @@ static struct clk_branch gpu_cc_crc_ahb_clk = { &gpu_cc_hub_ahb_div_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -330,7 +329,7 @@ static struct clk_branch gpu_cc_cx_ff_clk = { &gpu_cc_ff_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -348,7 +347,7 @@ static struct clk_branch gpu_cc_cx_gmu_clk = { &gpu_cc_gmu_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_aon_ops, }, }, @@ -362,7 +361,6 @@ static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data){ .name = "gpu_cc_cx_snoc_dvm_clk", - .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, @@ -380,7 +378,7 @@ static struct clk_branch gpu_cc_cxo_aon_clk = { &gpu_cc_xo_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -398,7 +396,7 @@ static struct clk_branch gpu_cc_cxo_clk = { &gpu_cc_xo_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -416,7 +414,7 @@ static struct clk_branch gpu_cc_demet_clk = { &gpu_cc_demet_div_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_aon_ops, }, }, @@ -430,7 +428,6 @@ static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data){ .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", - .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, @@ -448,7 +445,7 @@ static struct clk_branch gpu_cc_hub_aon_clk = { &gpu_cc_hub_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_aon_ops, }, }, @@ -466,7 +463,7 @@ static struct clk_branch gpu_cc_hub_cx_int_clk = { &gpu_cc_hub_cx_int_div_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_aon_ops, }, }, @@ -480,7 +477,6 @@ static struct clk_branch gpu_cc_memnoc_gfx_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data){ .name = "gpu_cc_memnoc_gfx_clk", - .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, @@ -494,7 +490,6 @@ static struct clk_branch gpu_cc_sleep_clk = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data){ .name = "gpu_cc_sleep_clk", - .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, @@ -528,16 +523,22 @@ static struct clk_regmap *gpu_cc_sa8775p_clocks[] = { static struct gdsc cx_gdsc = { .gdscr = 0x9108, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .gds_hw_ctrl = 0x953c, .pd = { .name = "cx_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE, }; static struct gdsc gx_gdsc = { .gdscr = 0x905c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, .pd = { .name = "gx_gdsc", .power_on = gdsc_gx_do_nothing_enable, diff --git a/drivers/clk/qcom/gpucc-sm8350.c b/drivers/clk/qcom/gpucc-sm8350.c index 38505d1388..8d9dcff40d 100644 --- a/drivers/clk/qcom/gpucc-sm8350.c +++ b/drivers/clk/qcom/gpucc-sm8350.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2022, Linaro Limited + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/clk.h> @@ -147,7 +148,7 @@ static struct clk_rcg2 gpu_cc_gmu_clk_src = { .parent_data = gpu_cc_parent_data_0, .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -169,7 +170,7 @@ static struct clk_rcg2 gpu_cc_hub_clk_src = { .parent_data = gpu_cc_parent_data_1, .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; diff --git a/drivers/clk/qcom/hfpll.c b/drivers/clk/qcom/hfpll.c index dac27e31ef..b0b0cb074b 100644 --- a/drivers/clk/qcom/hfpll.c +++ b/drivers/clk/qcom/hfpll.c @@ -14,7 +14,7 @@ #include "clk-regmap.h" #include "clk-hfpll.h" -static const struct hfpll_data hdata = { +static const struct hfpll_data qcs404 = { .mode_reg = 0x00, .l_reg = 0x04, .m_reg = 0x08, @@ -84,10 +84,12 @@ static const struct hfpll_data msm8976_cci = { }; static const struct of_device_id qcom_hfpll_match_table[] = { - { .compatible = "qcom,hfpll", .data = &hdata }, { .compatible = "qcom,msm8976-hfpll-a53", .data = &msm8976_a53 }, { .compatible = "qcom,msm8976-hfpll-a72", .data = &msm8976_a72 }, { .compatible = "qcom,msm8976-hfpll-cci", .data = &msm8976_cci }, + { .compatible = "qcom,qcs404-hfpll", .data = &qcs404 }, + /* Deprecated in bindings */ + { .compatible = "qcom,hfpll", .data = &qcs404 }, { } }; MODULE_DEVICE_TABLE(of, qcom_hfpll_match_table); diff --git a/drivers/clk/qcom/kpss-xcc.c b/drivers/clk/qcom/kpss-xcc.c index 23b0b11f00..e7cfa8d220 100644 --- a/drivers/clk/qcom/kpss-xcc.c +++ b/drivers/clk/qcom/kpss-xcc.c @@ -58,9 +58,7 @@ static int kpss_xcc_driver_probe(struct platform_device *pdev) if (IS_ERR(hw)) return PTR_ERR(hw); - of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, hw); - - return 0; + return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, hw); } static struct platform_driver kpss_xcc_driver = { |