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 */ 144