xref: /openbmc/linux/drivers/clk/mediatek/clk-mux.h (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
1a3ae5499SOwen Chen /* SPDX-License-Identifier: GPL-2.0 */
2a3ae5499SOwen Chen /*
3a3ae5499SOwen Chen  * Copyright (c) 2018 MediaTek Inc.
4a3ae5499SOwen Chen  * Author: Owen Chen <owen.chen@mediatek.com>
5a3ae5499SOwen Chen  */
6a3ae5499SOwen Chen 
7a3ae5499SOwen Chen #ifndef __DRV_CLK_MTK_MUX_H
8a3ae5499SOwen Chen #define __DRV_CLK_MTK_MUX_H
9a3ae5499SOwen Chen 
10b66add7aSChen-Yu Tsai #include <linux/notifier.h>
11dc46de49SChen-Yu Tsai #include <linux/spinlock.h>
12dc46de49SChen-Yu Tsai #include <linux/types.h>
13dc46de49SChen-Yu Tsai 
14dc46de49SChen-Yu Tsai struct clk;
15609cc5e1SChen-Yu Tsai struct clk_hw_onecell_data;
16dc46de49SChen-Yu Tsai struct clk_ops;
17b66add7aSChen-Yu Tsai struct device;
18dc46de49SChen-Yu Tsai struct device_node;
19a3ae5499SOwen Chen 
20a3ae5499SOwen Chen struct mtk_mux {
21a3ae5499SOwen Chen 	int id;
22a3ae5499SOwen Chen 	const char *name;
23a3ae5499SOwen Chen 	const char * const *parent_names;
24a3ae5499SOwen Chen 	unsigned int flags;
25a3ae5499SOwen Chen 
26a3ae5499SOwen Chen 	u32 mux_ofs;
27a3ae5499SOwen Chen 	u32 set_ofs;
28a3ae5499SOwen Chen 	u32 clr_ofs;
29a3ae5499SOwen Chen 	u32 upd_ofs;
30a3ae5499SOwen Chen 
31a3ae5499SOwen Chen 	u8 mux_shift;
32a3ae5499SOwen Chen 	u8 mux_width;
33a3ae5499SOwen Chen 	u8 gate_shift;
34a3ae5499SOwen Chen 	s8 upd_shift;
35a3ae5499SOwen Chen 
36710573deSChun-Jie Chen 	const struct clk_ops *ops;
37a3ae5499SOwen Chen 	signed char num_parents;
38a3ae5499SOwen Chen };
39a3ae5499SOwen Chen 
40a3ae5499SOwen Chen #define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,		\
41a3ae5499SOwen Chen 			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
42710573deSChun-Jie Chen 			_gate, _upd_ofs, _upd, _flags, _ops) {		\
43a3ae5499SOwen Chen 		.id = _id,						\
44a3ae5499SOwen Chen 		.name = _name,						\
45a3ae5499SOwen Chen 		.mux_ofs = _mux_ofs,					\
46a3ae5499SOwen Chen 		.set_ofs = _mux_set_ofs,				\
47a3ae5499SOwen Chen 		.clr_ofs = _mux_clr_ofs,				\
48a3ae5499SOwen Chen 		.upd_ofs = _upd_ofs,					\
49a3ae5499SOwen Chen 		.mux_shift = _shift,					\
50a3ae5499SOwen Chen 		.mux_width = _width,					\
51a3ae5499SOwen Chen 		.gate_shift = _gate,					\
52a3ae5499SOwen Chen 		.upd_shift = _upd,					\
53a3ae5499SOwen Chen 		.parent_names = _parents,				\
54a3ae5499SOwen Chen 		.num_parents = ARRAY_SIZE(_parents),			\
55a3ae5499SOwen Chen 		.flags = _flags,					\
56710573deSChun-Jie Chen 		.ops = &_ops,						\
57a3ae5499SOwen Chen 	}
58a3ae5499SOwen Chen 
59710573deSChun-Jie Chen extern const struct clk_ops mtk_mux_clr_set_upd_ops;
60710573deSChun-Jie Chen extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
61710573deSChun-Jie Chen 
62a3ae5499SOwen Chen #define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
63a3ae5499SOwen Chen 			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
64a3ae5499SOwen Chen 			_gate, _upd_ofs, _upd, _flags)			\
65a3ae5499SOwen Chen 		GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
66a3ae5499SOwen Chen 			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
67710573deSChun-Jie Chen 			_gate, _upd_ofs, _upd, _flags,			\
68710573deSChun-Jie Chen 			mtk_mux_gate_clr_set_upd_ops)
69a3ae5499SOwen Chen 
70a3ae5499SOwen Chen #define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs,		\
71a3ae5499SOwen Chen 			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
72a3ae5499SOwen Chen 			_gate, _upd_ofs, _upd)				\
73a3ae5499SOwen Chen 		MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents,	\
74a3ae5499SOwen Chen 			_mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift,	\
75a3ae5499SOwen Chen 			_width, _gate, _upd_ofs, _upd,			\
76a3ae5499SOwen Chen 			CLK_SET_RATE_PARENT)
77a3ae5499SOwen Chen 
78710573deSChun-Jie Chen #define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs,			\
79710573deSChun-Jie Chen 			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
80710573deSChun-Jie Chen 			_upd_ofs, _upd)					\
81710573deSChun-Jie Chen 		GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,	\
82710573deSChun-Jie Chen 			_mux_set_ofs, _mux_clr_ofs, _shift, _width,	\
83710573deSChun-Jie Chen 			0, _upd_ofs, _upd, CLK_SET_RATE_PARENT,		\
84710573deSChun-Jie Chen 			mtk_mux_clr_set_upd_ops)
85710573deSChun-Jie Chen 
86*d3d6bd5eSAngeloGioacchino Del Regno int mtk_clk_register_muxes(struct device *dev,
87*d3d6bd5eSAngeloGioacchino Del Regno 			   const struct mtk_mux *muxes,
88a3ae5499SOwen Chen 			   int num, struct device_node *node,
89a3ae5499SOwen Chen 			   spinlock_t *lock,
90609cc5e1SChen-Yu Tsai 			   struct clk_hw_onecell_data *clk_data);
91a3ae5499SOwen Chen 
920b4b0387SChen-Yu Tsai void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,
93609cc5e1SChen-Yu Tsai 			      struct clk_hw_onecell_data *clk_data);
940b4b0387SChen-Yu Tsai 
95b66add7aSChen-Yu Tsai struct mtk_mux_nb {
96b66add7aSChen-Yu Tsai 	struct notifier_block	nb;
97b66add7aSChen-Yu Tsai 	const struct clk_ops	*ops;
98b66add7aSChen-Yu Tsai 
99b66add7aSChen-Yu Tsai 	u8	bypass_index;	/* Which parent to temporarily use */
100b66add7aSChen-Yu Tsai 	u8	original_index;	/* Set by notifier callback */
101b66add7aSChen-Yu Tsai };
102b66add7aSChen-Yu Tsai 
103b66add7aSChen-Yu Tsai #define to_mtk_mux_nb(_nb)	container_of(_nb, struct mtk_mux_nb, nb)
104b66add7aSChen-Yu Tsai 
105b66add7aSChen-Yu Tsai int devm_mtk_clk_mux_notifier_register(struct device *dev, struct clk *clk,
106b66add7aSChen-Yu Tsai 				       struct mtk_mux_nb *mux_nb);
107b66add7aSChen-Yu Tsai 
108a3ae5499SOwen Chen #endif /* __DRV_CLK_MTK_MUX_H */
109