Linux 6.9-rc1
[linux-2.6-microblaze.git] / drivers / clk / mediatek / clk-mux.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (c) 2018 MediaTek Inc.
4  * Author: Owen Chen <owen.chen@mediatek.com>
5  */
6
7 #ifndef __DRV_CLK_MTK_MUX_H
8 #define __DRV_CLK_MTK_MUX_H
9
10 #include <linux/notifier.h>
11 #include <linux/spinlock.h>
12 #include <linux/types.h>
13
14 struct clk;
15 struct clk_hw_onecell_data;
16 struct clk_ops;
17 struct device;
18 struct device_node;
19
20 struct mtk_mux {
21         int id;
22         const char *name;
23         const char * const *parent_names;
24         const u8 *parent_index;
25         unsigned int flags;
26
27         u32 mux_ofs;
28         u32 set_ofs;
29         u32 clr_ofs;
30         u32 upd_ofs;
31
32         u8 mux_shift;
33         u8 mux_width;
34         u8 gate_shift;
35         s8 upd_shift;
36
37         const struct clk_ops *ops;
38         signed char num_parents;
39 };
40
41 #define __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _paridx,         \
42                          _num_parents, _mux_ofs, _mux_set_ofs,          \
43                          _mux_clr_ofs, _shift, _width, _gate, _upd_ofs, \
44                          _upd, _flags, _ops) {                          \
45                 .id = _id,                                              \
46                 .name = _name,                                          \
47                 .mux_ofs = _mux_ofs,                                    \
48                 .set_ofs = _mux_set_ofs,                                \
49                 .clr_ofs = _mux_clr_ofs,                                \
50                 .upd_ofs = _upd_ofs,                                    \
51                 .mux_shift = _shift,                                    \
52                 .mux_width = _width,                                    \
53                 .gate_shift = _gate,                                    \
54                 .upd_shift = _upd,                                      \
55                 .parent_names = _parents,                               \
56                 .parent_index = _paridx,                                \
57                 .num_parents = _num_parents,                            \
58                 .flags = _flags,                                        \
59                 .ops = &_ops,                                           \
60         }
61
62 #define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,          \
63                         _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
64                         _gate, _upd_ofs, _upd, _flags, _ops)            \
65                 __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents,          \
66                         NULL, ARRAY_SIZE(_parents), _mux_ofs,           \
67                         _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
68                         _gate, _upd_ofs, _upd, _flags, _ops)            \
69
70 #define GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents, _paridx,   \
71                          _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift,  \
72                          _width, _gate, _upd_ofs, _upd, _flags, _ops)   \
73                 __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents,          \
74                         _paridx, ARRAY_SIZE(_paridx), _mux_ofs,         \
75                         _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
76                         _gate, _upd_ofs, _upd, _flags, _ops)            \
77
78 extern const struct clk_ops mtk_mux_clr_set_upd_ops;
79 extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
80
81 #define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,      \
82                         _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
83                         _gate, _upd_ofs, _upd, _flags)                  \
84                 GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,  \
85                         _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
86                         _gate, _upd_ofs, _upd, _flags,                  \
87                         mtk_mux_gate_clr_set_upd_ops)
88
89 #define MUX_GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents,        \
90                         _paridx, _mux_ofs, _mux_set_ofs, _mux_clr_ofs,  \
91                         _shift, _width, _gate, _upd_ofs, _upd, _flags)  \
92                 GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents,    \
93                         _paridx, _mux_ofs, _mux_set_ofs, _mux_clr_ofs,  \
94                         _shift, _width, _gate, _upd_ofs, _upd, _flags,  \
95                         mtk_mux_gate_clr_set_upd_ops)
96
97 #define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs,            \
98                         _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
99                         _gate, _upd_ofs, _upd)                          \
100                 MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents,        \
101                         _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift,   \
102                         _width, _gate, _upd_ofs, _upd,                  \
103                         CLK_SET_RATE_PARENT)
104
105 #define MUX_GATE_CLR_SET_UPD_INDEXED(_id, _name, _parents, _paridx,     \
106                         _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift,   \
107                         _width, _gate, _upd_ofs, _upd)                  \
108                 MUX_GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name,          \
109                         _parents, _paridx, _mux_ofs, _mux_set_ofs,      \
110                         _mux_clr_ofs, _shift, _width, _gate, _upd_ofs,  \
111                         _upd, CLK_SET_RATE_PARENT)
112
113 #define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs,                 \
114                         _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
115                         _upd_ofs, _upd)                                 \
116                 GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,  \
117                         _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
118                         0, _upd_ofs, _upd, CLK_SET_RATE_PARENT,         \
119                         mtk_mux_clr_set_upd_ops)
120
121 int mtk_clk_register_muxes(struct device *dev,
122                            const struct mtk_mux *muxes,
123                            int num, struct device_node *node,
124                            spinlock_t *lock,
125                            struct clk_hw_onecell_data *clk_data);
126
127 void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,
128                               struct clk_hw_onecell_data *clk_data);
129
130 struct mtk_mux_nb {
131         struct notifier_block   nb;
132         const struct clk_ops    *ops;
133
134         u8      bypass_index;   /* Which parent to temporarily use */
135         u8      original_index; /* Set by notifier callback */
136 };
137
138 #define to_mtk_mux_nb(_nb)      container_of(_nb, struct mtk_mux_nb, nb)
139
140 int devm_mtk_clk_mux_notifier_register(struct device *dev, struct clk *clk,
141                                        struct mtk_mux_nb *mux_nb);
142
143 #endif /* __DRV_CLK_MTK_MUX_H */