File Index
Files and directories
Sign in
FILE

owl-divider.c

File preview with syntax highlighting.

linux-6.19.14/drivers/clk/actions/owl-divider.c C
 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
16static int owl_divider_determine_rate(struct clk_hw *hw,
17				      struct clk_rate_request *req)
18{
19	struct owl_divider *div = hw_to_owl_divider(hw);
20
21	return divider_determine_rate(hw, req, div->div_hw.table,
22				      div->div_hw.width, div->div_hw.div_flags);
23}
24
25unsigned long owl_divider_helper_recalc_rate(struct owl_clk_common *common,
26					 const struct owl_divider_hw *div_hw,
27					 unsigned long parent_rate)
28{
29	unsigned long val;
30	unsigned int reg;
31
32	regmap_read(common->regmap, div_hw->reg, &reg);
33	val = reg >> div_hw->shift;
34	val &= (1 << div_hw->width) - 1;
35
36	return divider_recalc_rate(&common->hw, parent_rate,
37				   val, div_hw->table,
38				   div_hw->div_flags,
39				   div_hw->width);
40}
41
42static unsigned long owl_divider_recalc_rate(struct clk_hw *hw,
43					  unsigned long parent_rate)
44{
45	struct owl_divider *div = hw_to_owl_divider(hw);
46
47	return owl_divider_helper_recalc_rate(&div->common,
48					      &div->div_hw, parent_rate);
49}
50
51int owl_divider_helper_set_rate(const struct owl_clk_common *common,
52				const struct owl_divider_hw *div_hw,
53				unsigned long rate,
54				unsigned long parent_rate)
55{
56	unsigned long val;
57	unsigned int reg;
58
59	val = divider_get_val(rate, parent_rate, div_hw->table,
60			      div_hw->width, 0);
61
62	regmap_read(common->regmap, div_hw->reg, &reg);
63	reg &= ~GENMASK(div_hw->width + div_hw->shift - 1, div_hw->shift);
64
65	regmap_write(common->regmap, div_hw->reg,
66			  reg | (val << div_hw->shift));
67
68	return 0;
69}
70
71static int owl_divider_set_rate(struct clk_hw *hw, unsigned long rate,
72				unsigned long parent_rate)
73{
74	struct owl_divider *div = hw_to_owl_divider(hw);
75
76	return owl_divider_helper_set_rate(&div->common, &div->div_hw,
77					rate, parent_rate);
78}
79
80const struct clk_ops owl_divider_ops = {
81	.recalc_rate = owl_divider_recalc_rate,
82	.determine_rate = owl_divider_determine_rate,
83	.set_rate = owl_divider_set_rate,
84};
~/ Read-only file preview.