162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2018 MediaTek Inc. 462306a36Sopenharmony_ci * Author: Owen Chen <owen.chen@mediatek.com> 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef __DRV_CLK_MTK_MUX_H 862306a36Sopenharmony_ci#define __DRV_CLK_MTK_MUX_H 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/notifier.h> 1162306a36Sopenharmony_ci#include <linux/spinlock.h> 1262306a36Sopenharmony_ci#include <linux/types.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistruct clk; 1562306a36Sopenharmony_cistruct clk_hw_onecell_data; 1662306a36Sopenharmony_cistruct clk_ops; 1762306a36Sopenharmony_cistruct device; 1862306a36Sopenharmony_cistruct device_node; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistruct mtk_mux { 2162306a36Sopenharmony_ci int id; 2262306a36Sopenharmony_ci const char *name; 2362306a36Sopenharmony_ci const char * const *parent_names; 2462306a36Sopenharmony_ci unsigned int flags; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci u32 mux_ofs; 2762306a36Sopenharmony_ci u32 set_ofs; 2862306a36Sopenharmony_ci u32 clr_ofs; 2962306a36Sopenharmony_ci u32 upd_ofs; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci u8 mux_shift; 3262306a36Sopenharmony_ci u8 mux_width; 3362306a36Sopenharmony_ci u8 gate_shift; 3462306a36Sopenharmony_ci s8 upd_shift; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci const struct clk_ops *ops; 3762306a36Sopenharmony_ci signed char num_parents; 3862306a36Sopenharmony_ci}; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ 4162306a36Sopenharmony_ci _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 4262306a36Sopenharmony_ci _gate, _upd_ofs, _upd, _flags, _ops) { \ 4362306a36Sopenharmony_ci .id = _id, \ 4462306a36Sopenharmony_ci .name = _name, \ 4562306a36Sopenharmony_ci .mux_ofs = _mux_ofs, \ 4662306a36Sopenharmony_ci .set_ofs = _mux_set_ofs, \ 4762306a36Sopenharmony_ci .clr_ofs = _mux_clr_ofs, \ 4862306a36Sopenharmony_ci .upd_ofs = _upd_ofs, \ 4962306a36Sopenharmony_ci .mux_shift = _shift, \ 5062306a36Sopenharmony_ci .mux_width = _width, \ 5162306a36Sopenharmony_ci .gate_shift = _gate, \ 5262306a36Sopenharmony_ci .upd_shift = _upd, \ 5362306a36Sopenharmony_ci .parent_names = _parents, \ 5462306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(_parents), \ 5562306a36Sopenharmony_ci .flags = _flags, \ 5662306a36Sopenharmony_ci .ops = &_ops, \ 5762306a36Sopenharmony_ci } 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ciextern const struct clk_ops mtk_mux_clr_set_upd_ops; 6062306a36Sopenharmony_ciextern const struct clk_ops mtk_mux_gate_clr_set_upd_ops; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ 6362306a36Sopenharmony_ci _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 6462306a36Sopenharmony_ci _gate, _upd_ofs, _upd, _flags) \ 6562306a36Sopenharmony_ci GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ 6662306a36Sopenharmony_ci _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 6762306a36Sopenharmony_ci _gate, _upd_ofs, _upd, _flags, \ 6862306a36Sopenharmony_ci mtk_mux_gate_clr_set_upd_ops) 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci#define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \ 7162306a36Sopenharmony_ci _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 7262306a36Sopenharmony_ci _gate, _upd_ofs, _upd) \ 7362306a36Sopenharmony_ci MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, \ 7462306a36Sopenharmony_ci _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift, \ 7562306a36Sopenharmony_ci _width, _gate, _upd_ofs, _upd, \ 7662306a36Sopenharmony_ci CLK_SET_RATE_PARENT) 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci#define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \ 7962306a36Sopenharmony_ci _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 8062306a36Sopenharmony_ci _upd_ofs, _upd) \ 8162306a36Sopenharmony_ci GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ 8262306a36Sopenharmony_ci _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ 8362306a36Sopenharmony_ci 0, _upd_ofs, _upd, CLK_SET_RATE_PARENT, \ 8462306a36Sopenharmony_ci mtk_mux_clr_set_upd_ops) 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ciint mtk_clk_register_muxes(struct device *dev, 8762306a36Sopenharmony_ci const struct mtk_mux *muxes, 8862306a36Sopenharmony_ci int num, struct device_node *node, 8962306a36Sopenharmony_ci spinlock_t *lock, 9062306a36Sopenharmony_ci struct clk_hw_onecell_data *clk_data); 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_civoid mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num, 9362306a36Sopenharmony_ci struct clk_hw_onecell_data *clk_data); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistruct mtk_mux_nb { 9662306a36Sopenharmony_ci struct notifier_block nb; 9762306a36Sopenharmony_ci const struct clk_ops *ops; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci u8 bypass_index; /* Which parent to temporarily use */ 10062306a36Sopenharmony_ci u8 original_index; /* Set by notifier callback */ 10162306a36Sopenharmony_ci}; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci#define to_mtk_mux_nb(_nb) container_of(_nb, struct mtk_mux_nb, nb) 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ciint devm_mtk_clk_mux_notifier_register(struct device *dev, struct clk *clk, 10662306a36Sopenharmony_ci struct mtk_mux_nb *mux_nb); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci#endif /* __DRV_CLK_MTK_MUX_H */ 109