Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

clk: mediatek: clk-mux: Add ops for mux gates with set/clr/upd and FENC

MT8196 uses set/clr/upd registers for mux gate enable/disable control,
along with a FENC bit to check the status. Add new set of mux gate
clock operations with support for set/clr/upd and FENC status logic.

Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
Signed-off-by: Laura Nao <laura.nao@collabora.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>

authored by

Laura Nao and committed by
Stephen Boyd
d3c4dde9 2c327a17

+94
+49
drivers/clk/mediatek/clk-mux.c
··· 17 17 18 18 #include "clk-mux.h" 19 19 20 + #define MTK_WAIT_FENC_DONE_US 30 21 + 20 22 struct mtk_clk_mux { 21 23 struct clk_hw hw; 22 24 struct regmap *regmap; ··· 30 28 static inline struct mtk_clk_mux *to_mtk_clk_mux(struct clk_hw *hw) 31 29 { 32 30 return container_of(hw, struct mtk_clk_mux, hw); 31 + } 32 + 33 + static int mtk_clk_mux_fenc_enable_setclr(struct clk_hw *hw) 34 + { 35 + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); 36 + unsigned long flags; 37 + u32 val; 38 + int ret; 39 + 40 + if (mux->lock) 41 + spin_lock_irqsave(mux->lock, flags); 42 + else 43 + __acquire(mux->lock); 44 + 45 + regmap_write(mux->regmap, mux->data->clr_ofs, 46 + BIT(mux->data->gate_shift)); 47 + 48 + ret = regmap_read_poll_timeout_atomic(mux->regmap, mux->data->fenc_sta_mon_ofs, 49 + val, val & BIT(mux->data->fenc_shift), 1, 50 + MTK_WAIT_FENC_DONE_US); 51 + 52 + if (mux->lock) 53 + spin_unlock_irqrestore(mux->lock, flags); 54 + else 55 + __release(mux->lock); 56 + 57 + return ret; 33 58 } 34 59 35 60 static int mtk_clk_mux_enable_setclr(struct clk_hw *hw) ··· 97 68 98 69 regmap_write(mux->regmap, mux->data->set_ofs, 99 70 BIT(mux->data->gate_shift)); 71 + } 72 + 73 + static int mtk_clk_mux_fenc_is_enabled(struct clk_hw *hw) 74 + { 75 + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); 76 + u32 val; 77 + 78 + regmap_read(mux->regmap, mux->data->fenc_sta_mon_ofs, &val); 79 + 80 + return !!(val & BIT(mux->data->fenc_shift)); 100 81 } 101 82 102 83 static int mtk_clk_mux_is_enabled(struct clk_hw *hw) ··· 204 165 .determine_rate = mtk_clk_mux_determine_rate, 205 166 }; 206 167 EXPORT_SYMBOL_GPL(mtk_mux_gate_clr_set_upd_ops); 168 + 169 + const struct clk_ops mtk_mux_gate_fenc_clr_set_upd_ops = { 170 + .enable = mtk_clk_mux_fenc_enable_setclr, 171 + .disable = mtk_clk_mux_disable_setclr, 172 + .is_enabled = mtk_clk_mux_fenc_is_enabled, 173 + .get_parent = mtk_clk_mux_get_parent, 174 + .set_parent = mtk_clk_mux_set_parent_setclr_lock, 175 + .determine_rate = mtk_clk_mux_determine_rate, 176 + }; 177 + EXPORT_SYMBOL_GPL(mtk_mux_gate_fenc_clr_set_upd_ops); 207 178 208 179 static struct clk_hw *mtk_clk_register_mux(struct device *dev, 209 180 const struct mtk_mux *mux,
+45
drivers/clk/mediatek/clk-mux.h
··· 28 28 u32 set_ofs; 29 29 u32 clr_ofs; 30 30 u32 upd_ofs; 31 + u32 fenc_sta_mon_ofs; 31 32 32 33 u8 mux_shift; 33 34 u8 mux_width; 34 35 u8 gate_shift; 35 36 s8 upd_shift; 37 + u8 fenc_shift; 36 38 37 39 const struct clk_ops *ops; 38 40 signed char num_parents; ··· 79 77 80 78 extern const struct clk_ops mtk_mux_clr_set_upd_ops; 81 79 extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops; 80 + extern const struct clk_ops mtk_mux_gate_fenc_clr_set_upd_ops; 82 81 83 82 #define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ 84 83 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ ··· 120 117 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 121 118 0, _upd_ofs, _upd, CLK_SET_RATE_PARENT, \ 122 119 mtk_mux_clr_set_upd_ops) 120 + 121 + #define MUX_GATE_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, _paridx, \ 122 + _num_parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ 123 + _shift, _width, _gate, _upd_ofs, _upd, \ 124 + _fenc_sta_mon_ofs, _fenc, _flags) { \ 125 + .id = _id, \ 126 + .name = _name, \ 127 + .mux_ofs = _mux_ofs, \ 128 + .set_ofs = _mux_set_ofs, \ 129 + .clr_ofs = _mux_clr_ofs, \ 130 + .upd_ofs = _upd_ofs, \ 131 + .fenc_sta_mon_ofs = _fenc_sta_mon_ofs, \ 132 + .mux_shift = _shift, \ 133 + .mux_width = _width, \ 134 + .gate_shift = _gate, \ 135 + .upd_shift = _upd, \ 136 + .fenc_shift = _fenc, \ 137 + .parent_names = _parents, \ 138 + .parent_index = _paridx, \ 139 + .num_parents = _num_parents, \ 140 + .flags = _flags, \ 141 + .ops = &mtk_mux_gate_fenc_clr_set_upd_ops, \ 142 + } 143 + 144 + #define MUX_GATE_FENC_CLR_SET_UPD(_id, _name, _parents, \ 145 + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ 146 + _shift, _width, _gate, _upd_ofs, _upd, \ 147 + _fenc_sta_mon_ofs, _fenc) \ 148 + MUX_GATE_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, \ 149 + NULL, ARRAY_SIZE(_parents), _mux_ofs, \ 150 + _mux_set_ofs, _mux_clr_ofs, _shift, \ 151 + _width, _gate, _upd_ofs, _upd, \ 152 + _fenc_sta_mon_ofs, _fenc, 0) 153 + 154 + #define MUX_GATE_FENC_CLR_SET_UPD_INDEXED(_id, _name, _parents, _paridx, \ 155 + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ 156 + _shift, _width, _gate, _upd_ofs, _upd, \ 157 + _fenc_sta_mon_ofs, _fenc) \ 158 + MUX_GATE_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, _paridx, \ 159 + ARRAY_SIZE(_paridx), _mux_ofs, _mux_set_ofs, \ 160 + _mux_clr_ofs, _shift, _width, _gate, _upd_ofs, _upd, \ 161 + _fenc_sta_mon_ofs, _fenc, 0) 123 162 124 163 int mtk_clk_register_muxes(struct device *dev, 125 164 const struct mtk_mux *muxes,