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 unsigned int flags; 25 26 u32 mux_ofs; 27 u32 set_ofs; 28 u32 clr_ofs; 29 u32 upd_ofs; 30 31 u8 mux_shift; 32 u8 mux_width; 33 u8 gate_shift; 34 s8 upd_shift; 35 36 const struct clk_ops *ops; 37 signed char num_parents; 38 }; 39 40 #define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ 41 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 42 _gate, _upd_ofs, _upd, _flags, _ops) { \ 43 .id = _id, \ 44 .name = _name, \ 45 .mux_ofs = _mux_ofs, \ 46 .set_ofs = _mux_set_ofs, \ 47 .clr_ofs = _mux_clr_ofs, \ 48 .upd_ofs = _upd_ofs, \ 49 .mux_shift = _shift, \ 50 .mux_width = _width, \ 51 .gate_shift = _gate, \ 52 .upd_shift = _upd, \ 53 .parent_names = _parents, \ 54 .num_parents = ARRAY_SIZE(_parents), \ 55 .flags = _flags, \ 56 .ops = &_ops, \ 57 } 58 59 extern const struct clk_ops mtk_mux_clr_set_upd_ops; 60 extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops; 61 62 #define MUX_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) \ 65 GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ 66 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 67 _gate, _upd_ofs, _upd, _flags, \ 68 mtk_mux_gate_clr_set_upd_ops) 69 70 #define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \ 71 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 72 _gate, _upd_ofs, _upd) \ 73 MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, \ 74 _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift, \ 75 _width, _gate, _upd_ofs, _upd, \ 76 CLK_SET_RATE_PARENT) 77 78 #define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \ 79 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 80 _upd_ofs, _upd) \ 81 GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ 82 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 83 0, _upd_ofs, _upd, CLK_SET_RATE_PARENT, \ 84 mtk_mux_clr_set_upd_ops) 85 86 int mtk_clk_register_muxes(struct device *dev, 87 const struct mtk_mux *muxes, 88 int num, struct device_node *node, 89 spinlock_t *lock, 90 struct clk_hw_onecell_data *clk_data); 91 92 void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num, 93 struct clk_hw_onecell_data *clk_data); 94 95 struct mtk_mux_nb { 96 struct notifier_block nb; 97 const struct clk_ops *ops; 98 99 u8 bypass_index; /* Which parent to temporarily use */ 100 u8 original_index; /* Set by notifier callback */ 101 }; 102 103 #define to_mtk_mux_nb(_nb) container_of(_nb, struct mtk_mux_nb, nb) 104 105 int devm_mtk_clk_mux_notifier_register(struct device *dev, struct clk *clk, 106 struct mtk_mux_nb *mux_nb); 107 108 #endif /* __DRV_CLK_MTK_MUX_H */ 109