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