From e2766aa6625508130207553fa1ab552c2e8f6082 Mon Sep 17 00:00:00 2001 From: David Collins Date: Mon, 11 Feb 2019 17:25:36 -0800 Subject: [PATCH 1/2] clk: qcom: clk-alpha-pll: add support for custom register initialization Add support for configuring custom target-specific registers during PLL initialization. Change-Id: Id296ae904d1b74e7c2f90027bd557bdc62b1d362 Signed-off-by: David Collins --- drivers/clk/qcom/clk-alpha-pll.c | 15 ++++++++++++++- drivers/clk/qcom/clk-alpha-pll.h | 8 +++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index c8e48c070015..640a2663a975 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); 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; From bd0b75950bd06471f8f0713844fbf754c226ee10 Mon Sep 17 00:00:00 2001 From: David Collins Date: Mon, 11 Feb 2019 17:06:53 -0800 Subject: [PATCH 2/2] clk: qcom: clk-alpha-pll: add support to reconfigure PLLs during prepare Under some circumstances, such as during subsystem restart, the registers for a clock controller may be reset to hardware default values. Add support to reconfigure a Lucid PLL during clk_prepare in the case that the CAL_L_VAL is found to be 0 before performing calibration. Change-Id: Idef3c42dfb32748ec40f89a9dab9f6ab86e293f6 Signed-off-by: David Collins --- drivers/clk/qcom/clk-alpha-pll.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 640a2663a975..3908e101d113 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -1593,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;