1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | // |
3 | // OWL pll 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 | #ifndef _OWL_PLL_H_ |
12 | #define _OWL_PLL_H_ |
13 | |
14 | #include "owl-common.h" |
15 | |
16 | #define OWL_PLL_DEF_DELAY 50 |
17 | |
18 | /* last entry should have rate = 0 */ |
19 | struct clk_pll_table { |
20 | unsigned int val; |
21 | unsigned long rate; |
22 | }; |
23 | |
24 | struct owl_pll_hw { |
25 | u32 reg; |
26 | u32 bfreq; |
27 | u8 bit_idx; |
28 | u8 shift; |
29 | u8 width; |
30 | u8 min_mul; |
31 | u8 max_mul; |
32 | u8 delay; |
33 | const struct clk_pll_table *table; |
34 | }; |
35 | |
36 | struct owl_pll { |
37 | struct owl_pll_hw pll_hw; |
38 | struct owl_clk_common common; |
39 | }; |
40 | |
41 | #define OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ |
42 | _width, _min_mul, _max_mul, _delay, _table) \ |
43 | { \ |
44 | .reg = _reg, \ |
45 | .bfreq = _bfreq, \ |
46 | .bit_idx = _bit_idx, \ |
47 | .shift = _shift, \ |
48 | .width = _width, \ |
49 | .min_mul = _min_mul, \ |
50 | .max_mul = _max_mul, \ |
51 | .delay = _delay, \ |
52 | .table = _table, \ |
53 | } |
54 | |
55 | #define OWL_PLL(_struct, _name, _parent, _reg, _bfreq, _bit_idx, \ |
56 | _shift, _width, _min_mul, _max_mul, _table, _flags) \ |
57 | struct owl_pll _struct = { \ |
58 | .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ |
59 | _width, _min_mul, _max_mul, \ |
60 | OWL_PLL_DEF_DELAY, _table), \ |
61 | .common = { \ |
62 | .regmap = NULL, \ |
63 | .hw.init = CLK_HW_INIT(_name, \ |
64 | _parent, \ |
65 | &owl_pll_ops, \ |
66 | _flags), \ |
67 | }, \ |
68 | } |
69 | |
70 | #define OWL_PLL_NO_PARENT(_struct, _name, _reg, _bfreq, _bit_idx, \ |
71 | _shift, _width, _min_mul, _max_mul, _table, _flags) \ |
72 | struct owl_pll _struct = { \ |
73 | .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ |
74 | _width, _min_mul, _max_mul, \ |
75 | OWL_PLL_DEF_DELAY, _table), \ |
76 | .common = { \ |
77 | .regmap = NULL, \ |
78 | .hw.init = CLK_HW_INIT_NO_PARENT(_name, \ |
79 | &owl_pll_ops, \ |
80 | _flags), \ |
81 | }, \ |
82 | } |
83 | |
84 | #define OWL_PLL_NO_PARENT_DELAY(_struct, _name, _reg, _bfreq, _bit_idx, \ |
85 | _shift, _width, _min_mul, _max_mul, _delay, _table, \ |
86 | _flags) \ |
87 | struct owl_pll _struct = { \ |
88 | .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ |
89 | _width, _min_mul, _max_mul, \ |
90 | _delay, _table), \ |
91 | .common = { \ |
92 | .regmap = NULL, \ |
93 | .hw.init = CLK_HW_INIT_NO_PARENT(_name, \ |
94 | &owl_pll_ops, \ |
95 | _flags), \ |
96 | }, \ |
97 | } |
98 | |
99 | #define mul_mask(m) ((1 << ((m)->width)) - 1) |
100 | |
101 | static inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw) |
102 | { |
103 | struct owl_clk_common *common = hw_to_owl_clk_common(hw); |
104 | |
105 | return container_of(common, struct owl_pll, common); |
106 | } |
107 | |
108 | extern const struct clk_ops owl_pll_ops; |
109 | |
110 | #endif /* _OWL_PLL_H_ */ |
111 | |