Loading drivers/clk/qcom/clk-pll.c +77 −2 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2021, The Linux Foundation. All rights reserved. */ #include <linux/kernel.h> Loading @@ -14,6 +14,7 @@ #include <asm/div64.h> #include "clk-debug.h" #include "clk-pll.h" #include "common.h" Loading Loading @@ -130,7 +131,8 @@ clk_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) f = find_freq(pll->freq_tbl, req->rate); if (!f) req->rate = clk_pll_recalc_rate(hw, req->best_parent_rate); req->rate = DIV_ROUND_UP_ULL(req->rate, req->best_parent_rate) * req->best_parent_rate; else req->rate = f->freq; Loading Loading @@ -334,3 +336,76 @@ const struct clk_ops clk_pll_sr2_ops = { .determine_rate = clk_pll_determine_rate, }; EXPORT_SYMBOL_GPL(clk_pll_sr2_ops); static int clk_pll_hf_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate) { struct clk_pll *pll = to_clk_pll(hw); bool enabled; u32 mode, l_val; u32 enable_mask = PLL_OUTCTRL | PLL_BYPASSNL | PLL_RESET_N; l_val = rate / prate; regmap_read(pll->clkr.regmap, pll->mode_reg, &mode); enabled = (mode & enable_mask) == enable_mask; if (enabled) clk_pll_disable(hw); regmap_update_bits(pll->clkr.regmap, pll->l_reg, 0x3ff, l_val); regmap_update_bits(pll->clkr.regmap, pll->m_reg, 0x7ffff, 0); regmap_update_bits(pll->clkr.regmap, pll->n_reg, 0x7ffff, 1); if (enabled) clk_pll_sr2_enable(hw); return 0; } static void clk_pll_hf_list_registers(struct seq_file *f, struct clk_hw *hw) { struct clk_pll *pll = to_clk_pll(hw); int size, i, val; static struct clk_register_data data[] = { {"PLL_MODE", 0x0}, {"PLL_L_VAL", 0x4}, {"PLL_M_VAL", 0x8}, {"PLL_N_VAL", 0xC}, {"PLL_USER_CTL", 0x10}, {"PLL_CONFIG_CTL", 0x14}, {"PLL_STATUS_CTL", 0x1C}, }; size = ARRAY_SIZE(data); for (i = 0; i < size; i++) { regmap_read(pll->clkr.regmap, pll->mode_reg + data[i].offset, &val); clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val); } } static struct clk_regmap_ops clk_pll_hf_regmap_ops = { .list_registers = &clk_pll_hf_list_registers, }; static void clk_pll_hf_init(struct clk_hw *hw) { struct clk_regmap *rclk = to_clk_regmap(hw); if (!rclk->ops) rclk->ops = &clk_pll_hf_regmap_ops; } const struct clk_ops clk_pll_hf_ops = { .enable = clk_pll_sr2_enable, .disable = clk_pll_disable, .set_rate = clk_pll_hf_set_rate, .recalc_rate = clk_pll_recalc_rate, .determine_rate = clk_pll_determine_rate, .debug_init = clk_common_debug_init, .init = clk_pll_hf_init, }; EXPORT_SYMBOL(clk_pll_hf_ops); drivers/clk/qcom/clk-pll.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2021, The Linux Foundation. All rights reserved. */ #ifndef __QCOM_CLK_PLL_H__ Loading Loading @@ -55,6 +55,7 @@ struct clk_pll { extern const struct clk_ops clk_pll_ops; extern const struct clk_ops clk_pll_vote_ops; extern const struct clk_ops clk_pll_sr2_ops; extern const struct clk_ops clk_pll_hf_ops; #define to_clk_pll(_hw) container_of(to_clk_regmap(_hw), struct clk_pll, clkr) Loading include/dt-bindings/clock/qcom,cmn-blk-pll.h 0 → 100644 +11 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved. */ #ifndef _DT_BINDINGS_CLK_QCOM_CMN_BLK_PLL_H #define _DT_BINDINGS_CLK_QCOM_CMN_BLK_PLL_H #define CMN_BLK_PLL 0 #endif Loading
drivers/clk/qcom/clk-pll.c +77 −2 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2021, The Linux Foundation. All rights reserved. */ #include <linux/kernel.h> Loading @@ -14,6 +14,7 @@ #include <asm/div64.h> #include "clk-debug.h" #include "clk-pll.h" #include "common.h" Loading Loading @@ -130,7 +131,8 @@ clk_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) f = find_freq(pll->freq_tbl, req->rate); if (!f) req->rate = clk_pll_recalc_rate(hw, req->best_parent_rate); req->rate = DIV_ROUND_UP_ULL(req->rate, req->best_parent_rate) * req->best_parent_rate; else req->rate = f->freq; Loading Loading @@ -334,3 +336,76 @@ const struct clk_ops clk_pll_sr2_ops = { .determine_rate = clk_pll_determine_rate, }; EXPORT_SYMBOL_GPL(clk_pll_sr2_ops); static int clk_pll_hf_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate) { struct clk_pll *pll = to_clk_pll(hw); bool enabled; u32 mode, l_val; u32 enable_mask = PLL_OUTCTRL | PLL_BYPASSNL | PLL_RESET_N; l_val = rate / prate; regmap_read(pll->clkr.regmap, pll->mode_reg, &mode); enabled = (mode & enable_mask) == enable_mask; if (enabled) clk_pll_disable(hw); regmap_update_bits(pll->clkr.regmap, pll->l_reg, 0x3ff, l_val); regmap_update_bits(pll->clkr.regmap, pll->m_reg, 0x7ffff, 0); regmap_update_bits(pll->clkr.regmap, pll->n_reg, 0x7ffff, 1); if (enabled) clk_pll_sr2_enable(hw); return 0; } static void clk_pll_hf_list_registers(struct seq_file *f, struct clk_hw *hw) { struct clk_pll *pll = to_clk_pll(hw); int size, i, val; static struct clk_register_data data[] = { {"PLL_MODE", 0x0}, {"PLL_L_VAL", 0x4}, {"PLL_M_VAL", 0x8}, {"PLL_N_VAL", 0xC}, {"PLL_USER_CTL", 0x10}, {"PLL_CONFIG_CTL", 0x14}, {"PLL_STATUS_CTL", 0x1C}, }; size = ARRAY_SIZE(data); for (i = 0; i < size; i++) { regmap_read(pll->clkr.regmap, pll->mode_reg + data[i].offset, &val); clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val); } } static struct clk_regmap_ops clk_pll_hf_regmap_ops = { .list_registers = &clk_pll_hf_list_registers, }; static void clk_pll_hf_init(struct clk_hw *hw) { struct clk_regmap *rclk = to_clk_regmap(hw); if (!rclk->ops) rclk->ops = &clk_pll_hf_regmap_ops; } const struct clk_ops clk_pll_hf_ops = { .enable = clk_pll_sr2_enable, .disable = clk_pll_disable, .set_rate = clk_pll_hf_set_rate, .recalc_rate = clk_pll_recalc_rate, .determine_rate = clk_pll_determine_rate, .debug_init = clk_common_debug_init, .init = clk_pll_hf_init, }; EXPORT_SYMBOL(clk_pll_hf_ops);
drivers/clk/qcom/clk-pll.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2021, The Linux Foundation. All rights reserved. */ #ifndef __QCOM_CLK_PLL_H__ Loading Loading @@ -55,6 +55,7 @@ struct clk_pll { extern const struct clk_ops clk_pll_ops; extern const struct clk_ops clk_pll_vote_ops; extern const struct clk_ops clk_pll_sr2_ops; extern const struct clk_ops clk_pll_hf_ops; #define to_clk_pll(_hw) container_of(to_clk_regmap(_hw), struct clk_pll, clkr) Loading
include/dt-bindings/clock/qcom,cmn-blk-pll.h 0 → 100644 +11 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved. */ #ifndef _DT_BINDINGS_CLK_QCOM_CMN_BLK_PLL_H #define _DT_BINDINGS_CLK_QCOM_CMN_BLK_PLL_H #define CMN_BLK_PLL 0 #endif