Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2a65ed42 MR |
2 | #ifndef _CCU_MUX_H_ |
3 | #define _CCU_MUX_H_ | |
4 | ||
5 | #include <linux/clk-provider.h> | |
6 | ||
7 | #include "ccu_common.h" | |
8 | ||
ff5294db CYT |
9 | struct ccu_mux_fixed_prediv { |
10 | u8 index; | |
11 | u16 div; | |
12 | }; | |
13 | ||
13e0dde8 CYT |
14 | struct ccu_mux_var_prediv { |
15 | u8 index; | |
16 | u8 shift; | |
17 | u8 width; | |
18 | }; | |
19 | ||
2a65ed42 | 20 | struct ccu_mux_internal { |
2b9c875c CYT |
21 | u8 shift; |
22 | u8 width; | |
23 | const u8 *table; | |
2a65ed42 | 24 | |
ff5294db CYT |
25 | const struct ccu_mux_fixed_prediv *fixed_predivs; |
26 | u8 n_predivs; | |
2a65ed42 | 27 | |
13e0dde8 CYT |
28 | const struct ccu_mux_var_prediv *var_predivs; |
29 | u8 n_var_predivs; | |
2a65ed42 MR |
30 | }; |
31 | ||
2b9c875c CYT |
32 | #define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table) \ |
33 | { \ | |
34 | .shift = _shift, \ | |
35 | .width = _width, \ | |
36 | .table = _table, \ | |
2a65ed42 MR |
37 | } |
38 | ||
2b9c875c CYT |
39 | #define _SUNXI_CCU_MUX(_shift, _width) \ |
40 | _SUNXI_CCU_MUX_TABLE(_shift, _width, NULL) | |
41 | ||
2a65ed42 MR |
42 | struct ccu_mux { |
43 | u16 reg; | |
44 | u32 enable; | |
45 | ||
46 | struct ccu_mux_internal mux; | |
47 | struct ccu_common common; | |
48 | }; | |
49 | ||
13e91e45 MR |
50 | #define SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, _table, \ |
51 | _reg, _shift, _width, _gate, \ | |
52 | _flags) \ | |
2a65ed42 | 53 | struct ccu_mux _struct = { \ |
13e91e45 MR |
54 | .enable = _gate, \ |
55 | .mux = _SUNXI_CCU_MUX_TABLE(_shift, _width, _table), \ | |
2a65ed42 MR |
56 | .common = { \ |
57 | .reg = _reg, \ | |
58 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ | |
59 | _parents, \ | |
60 | &ccu_mux_ops, \ | |
61 | _flags), \ | |
62 | } \ | |
63 | } | |
64 | ||
65 | #define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg, \ | |
66 | _shift, _width, _gate, _flags) \ | |
13e91e45 MR |
67 | SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \ |
68 | _reg, _shift, _width, _gate, \ | |
69 | _flags) | |
70 | ||
71 | #define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, \ | |
72 | _flags) \ | |
73 | SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \ | |
74 | _reg, _shift, _width, 0, _flags) | |
2a65ed42 MR |
75 | |
76 | static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw) | |
77 | { | |
78 | struct ccu_common *common = hw_to_ccu_common(hw); | |
79 | ||
80 | return container_of(common, struct ccu_mux, common); | |
81 | } | |
82 | ||
83 | extern const struct clk_ops ccu_mux_ops; | |
84 | ||
d754b159 MR |
85 | unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common, |
86 | struct ccu_mux_internal *cm, | |
87 | int parent_index, | |
88 | unsigned long parent_rate); | |
2a65ed42 MR |
89 | int ccu_mux_helper_determine_rate(struct ccu_common *common, |
90 | struct ccu_mux_internal *cm, | |
91 | struct clk_rate_request *req, | |
92 | unsigned long (*round)(struct ccu_mux_internal *, | |
10a8d9b9 MR |
93 | struct clk_hw *, |
94 | unsigned long *, | |
2a65ed42 MR |
95 | unsigned long, |
96 | void *), | |
97 | void *data); | |
98 | u8 ccu_mux_helper_get_parent(struct ccu_common *common, | |
99 | struct ccu_mux_internal *cm); | |
100 | int ccu_mux_helper_set_parent(struct ccu_common *common, | |
101 | struct ccu_mux_internal *cm, | |
102 | u8 index); | |
103 | ||
8adfb086 CYT |
104 | struct ccu_mux_nb { |
105 | struct notifier_block clk_nb; | |
106 | struct ccu_common *common; | |
107 | struct ccu_mux_internal *cm; | |
108 | ||
109 | u32 delay_us; /* How many us to wait after reparenting */ | |
110 | u8 bypass_index; /* Which parent to temporarily use */ | |
111 | u8 original_index; /* This is set by the notifier callback */ | |
112 | }; | |
113 | ||
114 | #define to_ccu_mux_nb(_nb) container_of(_nb, struct ccu_mux_nb, clk_nb) | |
115 | ||
116 | int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb); | |
117 | ||
2a65ed42 | 118 | #endif /* _CCU_MUX_H_ */ |