diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index c8e48c070015..3908e101d113 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2016, 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, 2018-2019, The Linux Foundation. + * All rights reserved. */ #include @@ -1414,6 +1415,16 @@ static int lucid_pll_is_enabled(struct clk_alpha_pll *pll, (mode_regval & PLL_OUTCTRL)); } +static void clk_alpha_pll_custom_configure(struct clk_alpha_pll *pll, + struct regmap *regmap, const struct alpha_pll_config *config) +{ + int i; + + for (i = 0; i < config->num_custom_reg; i++) + regmap_write(regmap, pll->offset + config->custom_reg_offset[i], + config->custom_reg_val[i]); +} + void clk_lucid_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config) { @@ -1463,6 +1474,8 @@ void clk_lucid_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, regmap_write(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val); + clk_alpha_pll_custom_configure(pll, regmap, config); + regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS, PLL_UPDATE_BYPASS); @@ -1580,6 +1593,20 @@ static int alpha_pll_lucid_prepare(struct clk_hw *hw) if (regval & LUCID_PCAL_DONE) return 0; + if (pll->config) { + /* + * Reconfigure the PLL if CAL_L_VAL is 0 (which implies that all + * clock controller registers have been reset). + */ + regmap_read(pll->clkr.regmap, PLL_CAL_L_VAL(pll), ®val); + if (!regval) { + pr_debug("reconfiguring %s after it was reset\n", + clk_hw_get_name(hw)); + clk_lucid_pll_configure(pll, pll->clkr.regmap, + pll->config); + } + } + p = clk_hw_get_parent(hw); if (!p) return -EINVAL; diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 8c4aaca939b7..9184df33352d 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2015-2016, 2018, The Linux Foundation. All rights reserved. */ +/* + * Copyright (c) 2015-2016, 2018-2019, The Linux Foundation. + * All rights reserved. + */ #ifndef __QCOM_CLK_ALPHA_PLL_H__ #define __QCOM_CLK_ALPHA_PLL_H__ @@ -114,6 +117,9 @@ struct alpha_pll_config { u32 post_div_mask; u32 vco_val; u32 vco_mask; + const u32 *custom_reg_offset; + const u32 *custom_reg_val; + size_t num_custom_reg; }; extern const struct clk_ops clk_alpha_pll_ops;