Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.19 97 lines 2.5 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2// 3// OWL divider clock driver 4// 5// Copyright (c) 2014 Actions Semi Inc. 6// Author: David Liu <liuwei@actions-semi.com> 7// 8// Copyright (c) 2018 Linaro Ltd. 9// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 10 11#include <linux/clk-provider.h> 12#include <linux/regmap.h> 13 14#include "owl-divider.h" 15 16long owl_divider_helper_round_rate(struct owl_clk_common *common, 17 const struct owl_divider_hw *div_hw, 18 unsigned long rate, 19 unsigned long *parent_rate) 20{ 21 return divider_round_rate(&common->hw, rate, parent_rate, 22 div_hw->table, div_hw->width, 23 div_hw->div_flags); 24} 25 26static int owl_divider_determine_rate(struct clk_hw *hw, 27 struct clk_rate_request *req) 28{ 29 struct owl_divider *div = hw_to_owl_divider(hw); 30 31 req->rate = owl_divider_helper_round_rate(&div->common, &div->div_hw, 32 req->rate, 33 &req->best_parent_rate); 34 35 return 0; 36} 37 38unsigned long owl_divider_helper_recalc_rate(struct owl_clk_common *common, 39 const struct owl_divider_hw *div_hw, 40 unsigned long parent_rate) 41{ 42 unsigned long val; 43 unsigned int reg; 44 45 regmap_read(common->regmap, div_hw->reg, &reg); 46 val = reg >> div_hw->shift; 47 val &= (1 << div_hw->width) - 1; 48 49 return divider_recalc_rate(&common->hw, parent_rate, 50 val, div_hw->table, 51 div_hw->div_flags, 52 div_hw->width); 53} 54 55static unsigned long owl_divider_recalc_rate(struct clk_hw *hw, 56 unsigned long parent_rate) 57{ 58 struct owl_divider *div = hw_to_owl_divider(hw); 59 60 return owl_divider_helper_recalc_rate(&div->common, 61 &div->div_hw, parent_rate); 62} 63 64int owl_divider_helper_set_rate(const struct owl_clk_common *common, 65 const struct owl_divider_hw *div_hw, 66 unsigned long rate, 67 unsigned long parent_rate) 68{ 69 unsigned long val; 70 unsigned int reg; 71 72 val = divider_get_val(rate, parent_rate, div_hw->table, 73 div_hw->width, 0); 74 75 regmap_read(common->regmap, div_hw->reg, &reg); 76 reg &= ~GENMASK(div_hw->width + div_hw->shift - 1, div_hw->shift); 77 78 regmap_write(common->regmap, div_hw->reg, 79 reg | (val << div_hw->shift)); 80 81 return 0; 82} 83 84static int owl_divider_set_rate(struct clk_hw *hw, unsigned long rate, 85 unsigned long parent_rate) 86{ 87 struct owl_divider *div = hw_to_owl_divider(hw); 88 89 return owl_divider_helper_set_rate(&div->common, &div->div_hw, 90 rate, parent_rate); 91} 92 93const struct clk_ops owl_divider_ops = { 94 .recalc_rate = owl_divider_recalc_rate, 95 .determine_rate = owl_divider_determine_rate, 96 .set_rate = owl_divider_set_rate, 97};