Loading drivers/clk/qcom/clk-alpha-pll.c +106 −0 Original line number Original line Diff line number Diff line Loading @@ -699,6 +699,67 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate, return clamp(rate, min_freq, max_freq); return clamp(rate, min_freq, max_freq); } } void clk_huayra_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config) { if (config->config_ctl_val) regmap_write(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val); if (config->config_ctl_hi_val) regmap_write(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val); if (config->config_ctl_hi1_val) regmap_write(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val); if (config->test_ctl_val) regmap_write(regmap, PLL_TEST_CTL(pll), config->test_ctl_val); if (config->test_ctl_hi_val) regmap_write(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val); if (config->test_ctl_hi1_val) regmap_write(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val); if (config->l) regmap_write(regmap, PLL_L_VAL(pll), config->l); if (config->alpha) regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha); if (config->user_ctl_val) regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val); /* Set PLL_BYPASSNL */ regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL); /* * H/W requires a 1us delay between disabling the bypass and * de-asserting the reset. */ mb(); udelay(5); /* Take PLL out from reset state */ regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); /* Wait 50us for pll_lock_det bit to go high */ mb(); udelay(50); /* Enables PLL output */ regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL); } static unsigned long static unsigned long alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a) alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a) { { Loading Loading @@ -851,6 +912,50 @@ static long alpha_pll_huayra_round_rate(struct clk_hw *hw, unsigned long rate, return alpha_huayra_pll_round_rate(rate, *prate, &l, &a); return alpha_huayra_pll_round_rate(rate, *prate, &l, &a); } } static void clk_huayra_pll_list_registers(struct seq_file *f, struct clk_hw *hw) { struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); int size, i, val; static struct clk_register_data data[] = { {"PLL_MODE", PLL_OFF_MODE}, {"PLL_L_VAL", PLL_OFF_L_VAL}, {"PLL_ALPHA_VAL", PLL_OFF_ALPHA_VAL}, {"PLL_USER_CTL", PLL_OFF_USER_CTL}, {"PLL_CONFIG_CTL", PLL_OFF_CONFIG_CTL}, {"PLL_CONFIG_CTL_U", PLL_OFF_CONFIG_CTL_U}, {"PLL_CONFIG_CTL_U1", PLL_OFF_CONFIG_CTL_U1}, {"PLL_TEST_CTL", PLL_OFF_TEST_CTL}, {"PLL_TEST_CTL_U", PLL_OFF_TEST_CTL_U}, {"PLL_TEST_CTL_U1", PLL_OFF_TEST_CTL_U1}, {"PLL_OPMODE", PLL_OFF_OPMODE}, {"PLL_STATUS", PLL_OFF_STATUS}, }; static struct clk_register_data data1[] = { {"APSS_PLL_VOTE", 0x0}, }; size = ARRAY_SIZE(data); for (i = 0; i < size; i++) { regmap_read(pll->clkr.regmap, pll->offset + pll->regs[data[i].offset], &val); clock_debug_output(f, false, "%20s: 0x%.8x\n", data[i].name, val); } regmap_read(pll->clkr.regmap, pll->offset + pll->regs[data[0].offset], &val); if (val & PLL_FSM_ENA) { regmap_read(pll->clkr.regmap, pll->clkr.enable_reg + data1[0].offset, &val); clock_debug_output(f, false, "%20s: 0x%.8x\n", data1[0].name, val); } } static void clk_alpha_pll_list_registers(struct seq_file *f, struct clk_hw *hw) static void clk_alpha_pll_list_registers(struct seq_file *f, struct clk_hw *hw) { { struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); Loading Loading @@ -1200,6 +1305,7 @@ const struct clk_ops clk_alpha_pll_huayra_ops = { .recalc_rate = alpha_pll_huayra_recalc_rate, .recalc_rate = alpha_pll_huayra_recalc_rate, .round_rate = alpha_pll_huayra_round_rate, .round_rate = alpha_pll_huayra_round_rate, .set_rate = alpha_pll_huayra_set_rate, .set_rate = alpha_pll_huayra_set_rate, .list_registers = clk_huayra_pll_list_registers, .bus_vote = clk_debug_bus_vote, .bus_vote = clk_debug_bus_vote, }; }; EXPORT_SYMBOL_GPL(clk_alpha_pll_huayra_ops); EXPORT_SYMBOL_GPL(clk_alpha_pll_huayra_ops); Loading drivers/clk/qcom/clk-alpha-pll.h +3 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2015, 2018-2019, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2015, 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef __QCOM_CLK_ALPHA_PLL_H__ #ifndef __QCOM_CLK_ALPHA_PLL_H__ #define __QCOM_CLK_ALPHA_PLL_H__ #define __QCOM_CLK_ALPHA_PLL_H__ Loading Loading @@ -152,4 +152,6 @@ void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); const struct alpha_pll_config *config); int clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, int clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); const struct alpha_pll_config *config); void clk_huayra_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); #endif #endif Loading
drivers/clk/qcom/clk-alpha-pll.c +106 −0 Original line number Original line Diff line number Diff line Loading @@ -699,6 +699,67 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate, return clamp(rate, min_freq, max_freq); return clamp(rate, min_freq, max_freq); } } void clk_huayra_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config) { if (config->config_ctl_val) regmap_write(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val); if (config->config_ctl_hi_val) regmap_write(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val); if (config->config_ctl_hi1_val) regmap_write(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val); if (config->test_ctl_val) regmap_write(regmap, PLL_TEST_CTL(pll), config->test_ctl_val); if (config->test_ctl_hi_val) regmap_write(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val); if (config->test_ctl_hi1_val) regmap_write(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val); if (config->l) regmap_write(regmap, PLL_L_VAL(pll), config->l); if (config->alpha) regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha); if (config->user_ctl_val) regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val); /* Set PLL_BYPASSNL */ regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL); /* * H/W requires a 1us delay between disabling the bypass and * de-asserting the reset. */ mb(); udelay(5); /* Take PLL out from reset state */ regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); /* Wait 50us for pll_lock_det bit to go high */ mb(); udelay(50); /* Enables PLL output */ regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL); } static unsigned long static unsigned long alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a) alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a) { { Loading Loading @@ -851,6 +912,50 @@ static long alpha_pll_huayra_round_rate(struct clk_hw *hw, unsigned long rate, return alpha_huayra_pll_round_rate(rate, *prate, &l, &a); return alpha_huayra_pll_round_rate(rate, *prate, &l, &a); } } static void clk_huayra_pll_list_registers(struct seq_file *f, struct clk_hw *hw) { struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); int size, i, val; static struct clk_register_data data[] = { {"PLL_MODE", PLL_OFF_MODE}, {"PLL_L_VAL", PLL_OFF_L_VAL}, {"PLL_ALPHA_VAL", PLL_OFF_ALPHA_VAL}, {"PLL_USER_CTL", PLL_OFF_USER_CTL}, {"PLL_CONFIG_CTL", PLL_OFF_CONFIG_CTL}, {"PLL_CONFIG_CTL_U", PLL_OFF_CONFIG_CTL_U}, {"PLL_CONFIG_CTL_U1", PLL_OFF_CONFIG_CTL_U1}, {"PLL_TEST_CTL", PLL_OFF_TEST_CTL}, {"PLL_TEST_CTL_U", PLL_OFF_TEST_CTL_U}, {"PLL_TEST_CTL_U1", PLL_OFF_TEST_CTL_U1}, {"PLL_OPMODE", PLL_OFF_OPMODE}, {"PLL_STATUS", PLL_OFF_STATUS}, }; static struct clk_register_data data1[] = { {"APSS_PLL_VOTE", 0x0}, }; size = ARRAY_SIZE(data); for (i = 0; i < size; i++) { regmap_read(pll->clkr.regmap, pll->offset + pll->regs[data[i].offset], &val); clock_debug_output(f, false, "%20s: 0x%.8x\n", data[i].name, val); } regmap_read(pll->clkr.regmap, pll->offset + pll->regs[data[0].offset], &val); if (val & PLL_FSM_ENA) { regmap_read(pll->clkr.regmap, pll->clkr.enable_reg + data1[0].offset, &val); clock_debug_output(f, false, "%20s: 0x%.8x\n", data1[0].name, val); } } static void clk_alpha_pll_list_registers(struct seq_file *f, struct clk_hw *hw) static void clk_alpha_pll_list_registers(struct seq_file *f, struct clk_hw *hw) { { struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); Loading Loading @@ -1200,6 +1305,7 @@ const struct clk_ops clk_alpha_pll_huayra_ops = { .recalc_rate = alpha_pll_huayra_recalc_rate, .recalc_rate = alpha_pll_huayra_recalc_rate, .round_rate = alpha_pll_huayra_round_rate, .round_rate = alpha_pll_huayra_round_rate, .set_rate = alpha_pll_huayra_set_rate, .set_rate = alpha_pll_huayra_set_rate, .list_registers = clk_huayra_pll_list_registers, .bus_vote = clk_debug_bus_vote, .bus_vote = clk_debug_bus_vote, }; }; EXPORT_SYMBOL_GPL(clk_alpha_pll_huayra_ops); EXPORT_SYMBOL_GPL(clk_alpha_pll_huayra_ops); Loading
drivers/clk/qcom/clk-alpha-pll.h +3 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2015, 2018-2019, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2015, 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef __QCOM_CLK_ALPHA_PLL_H__ #ifndef __QCOM_CLK_ALPHA_PLL_H__ #define __QCOM_CLK_ALPHA_PLL_H__ #define __QCOM_CLK_ALPHA_PLL_H__ Loading Loading @@ -152,4 +152,6 @@ void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); const struct alpha_pll_config *config); int clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, int clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); const struct alpha_pll_config *config); void clk_huayra_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); #endif #endif