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