144 lines · c
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_H8#define __DRV_CLK_MTK_MUX_H9 10#include <linux/notifier.h>11#include <linux/spinlock.h>12#include <linux/types.h>13 14struct clk;15struct clk_hw_onecell_data;16struct clk_ops;17struct device;18struct device_node;19 20struct 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 78extern const struct clk_ops mtk_mux_clr_set_upd_ops;79extern 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 121int 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 127void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,128 struct clk_hw_onecell_data *clk_data);129 130struct 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 140int 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