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