1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (c) 2018 MediaTek Inc.
4 * Author: Owen Chen <owen.chen@mediatek.com>
7 #ifndef __DRV_CLK_MTK_MUX_H
8 #define __DRV_CLK_MTK_MUX_H
10 #include <linux/notifier.h>
11 #include <linux/spinlock.h>
12 #include <linux/types.h>
15 struct clk_hw_onecell_data
;
23 const char * const *parent_names
;
24 const u8
*parent_index
;
37 const struct clk_ops
*ops
;
38 signed char num_parents
;
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) { \
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, \
55 .parent_names = _parents, \
56 .parent_index = _paridx, \
57 .num_parents = _num_parents, \
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) \
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) \
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
;
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)
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)
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, \
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)
113 #define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \
114 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
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)
121 int mtk_clk_register_muxes(struct device
*dev
,
122 const struct mtk_mux
*muxes
,
123 int num
, struct device_node
*node
,
125 struct clk_hw_onecell_data
*clk_data
);
127 void mtk_clk_unregister_muxes(const struct mtk_mux
*muxes
, int num
,
128 struct clk_hw_onecell_data
*clk_data
);
131 struct notifier_block nb
;
132 const struct clk_ops
*ops
;
134 u8 bypass_index
; /* Which parent to temporarily use */
135 u8 original_index
; /* Set by notifier callback */
138 #define to_mtk_mux_nb(_nb) container_of(_nb, struct mtk_mux_nb, nb)
140 int devm_mtk_clk_mux_notifier_register(struct device
*dev
, struct clk
*clk
,
141 struct mtk_mux_nb
*mux_nb
);
143 #endif /* __DRV_CLK_MTK_MUX_H */