/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 2024, Kongyang Liu * */ #ifndef __CLK_SOPHGO_IP_H__ #define __CLK_SOPHGO_IP_H__ #include #include "clk-common.h" struct cv1800b_mmux_parent_info { const char *name; u8 clk_sel; u8 index; }; struct cv1800b_clk_gate { struct clk clk; const char *name; const char *parent_name; void __iomem *base; struct cv1800b_clk_regbit gate; }; struct cv1800b_clk_div { struct clk clk; const char *name; const char *parent_name; void __iomem *base; struct cv1800b_clk_regbit gate; struct cv1800b_clk_regfield div; int div_init; }; struct cv1800b_clk_bypass_div { struct cv1800b_clk_div div; struct cv1800b_clk_regbit bypass; }; struct cv1800b_clk_fixed_div { struct clk clk; const char *name; const char *parent_name; void __iomem *base; struct cv1800b_clk_regbit gate; int div; }; struct cv1800b_clk_bypass_fixed_div { struct cv1800b_clk_fixed_div div; struct cv1800b_clk_regbit bypass; }; struct cv1800b_clk_mux { struct clk clk; const char *name; const char * const *parent_names; u8 num_parents; void __iomem *base; struct cv1800b_clk_regbit gate; struct cv1800b_clk_regfield div; int div_init; struct cv1800b_clk_regfield mux; }; struct cv1800b_clk_bypass_mux { struct cv1800b_clk_mux mux; struct cv1800b_clk_regbit bypass; }; struct cv1800b_clk_mmux { struct clk clk; const char *name; const struct cv1800b_mmux_parent_info *parent_infos; u8 num_parents; void __iomem *base; struct cv1800b_clk_regbit gate; struct cv1800b_clk_regfield div[2]; int div_init[2]; struct cv1800b_clk_regfield mux[2]; struct cv1800b_clk_regbit bypass; struct cv1800b_clk_regbit clk_sel; }; struct cv1800b_clk_audio { struct clk clk; const char *name; const char *parent_name; void __iomem *base; struct cv1800b_clk_regbit src_en; struct cv1800b_clk_regbit output_en; struct cv1800b_clk_regbit div_en; struct cv1800b_clk_regbit div_up; struct cv1800b_clk_regfield m; struct cv1800b_clk_regfield n; }; #define CV1800B_GATE(_id, _name, _parent, \ _gate_offset, _gate_shift, \ _flags) \ { \ .clk = { \ .id = CV1800B_CLK_ID_TRANSFORM(_id), \ .flags = _flags, \ }, \ .name = _name, \ .parent_name = _parent, \ .gate = CV1800B_CLK_REGBIT(_gate_offset, _gate_shift), \ } #define CV1800B_DIV(_id, _name, _parent, \ _gate_offset, _gate_shift, \ _div_offset, _div_shift, _div_width, \ _div_init, _flags) \ { \ .clk = { \ .id = CV1800B_CLK_ID_TRANSFORM(_id), \ .flags = _flags, \ }, \ .name = _name, \ .parent_name = _parent, \ .gate = CV1800B_CLK_REGBIT(_gate_offset, _gate_shift), \ .div = CV1800B_CLK_REGFIELD(_div_offset, _div_shift, \ _div_width), \ .div_init = _div_init, \ } #define CV1800B_BYPASS_DIV(_id, _name, _parent, \ _gate_offset, _gate_shift, \ _div_offset, _div_shift, \ _div_width, _div_init, \ _bypass_offset, _bypass_shift, \ _flags) \ { \ .div = CV1800B_DIV(_id, _name, _parent, \ _gate_offset, _gate_shift, \ _div_offset, _div_shift, _div_width, \ _div_init, _flags), \ .bypass = CV1800B_CLK_REGBIT(_bypass_offset, \ _bypass_shift), \ } #define CV1800B_FIXED_DIV(_id, _name, _parent, \ _gate_offset, _gate_shift, \ _div, _flags) \ { \ .clk = { \ .id = CV1800B_CLK_ID_TRANSFORM(_id), \ .flags = _flags, \ }, \ .name = _name, \ .parent_name = _parent, \ .gate = CV1800B_CLK_REGBIT(_gate_offset, _gate_shift), \ .div = _div, \ } #define CV1800B_BYPASS_FIXED_DIV(_id, _name, _parent, \ _gate_offset, _gate_shift, \ _div, \ _bypass_offset, _bypass_shift, \ _flags) \ { \ .div = CV1800B_FIXED_DIV(_id, _name, _parent, \ _gate_offset, _gate_shift, \ _div, _flags), \ .bypass = CV1800B_CLK_REGBIT(_bypass_offset, \ _bypass_shift) \ } #define CV1800B_MUX(_id, _name, _parents, \ _gate_offset, _gate_shift, \ _div_offset, _div_shift, _div_width, _div_init, \ _mux_offset, _mux_shift, _mux_width, \ _flags) \ { \ .clk = { \ .id = CV1800B_CLK_ID_TRANSFORM(_id), \ .flags = _flags, \ }, \ .name = _name, \ .parent_names = _parents, \ .num_parents = ARRAY_SIZE(_parents), \ .gate = CV1800B_CLK_REGBIT(_gate_offset, _gate_shift), \ .div = CV1800B_CLK_REGFIELD(_div_offset, _div_shift, \ _div_width), \ .div_init = _div_init, \ .mux = CV1800B_CLK_REGFIELD(_mux_offset, _mux_shift, \ _mux_width), \ } #define CV1800B_BYPASS_MUX(_id, _name, _parents, \ _gate_offset, _gate_shift, \ _div_offset, _div_shift, \ _div_width, _div_init, \ _mux_offset, _mux_shift, _mux_width, \ _bypass_offset, _bypass_shift, \ _flags) \ { \ .mux = CV1800B_MUX(_id, _name, _parents, \ _gate_offset, _gate_shift, \ _div_offset, _div_shift, \ _div_width, _div_init, \ _mux_offset, _mux_shift, _mux_width, \ _flags), \ .bypass = CV1800B_CLK_REGBIT(_bypass_offset, \ _bypass_shift), \ } #define CV1800B_MMUX(_id, _name, _parents, \ _gate_offset, _gate_shift, \ _div0_offset, _div0_shift, _div0_width, _div0_init,\ _div1_offset, _div1_shift, _div1_width, _div1_init,\ _mux0_offset, _mux0_shift, _mux0_width, \ _mux1_offset, _mux1_shift, _mux1_width, \ _bypass_offset, _bypass_shift, \ _clk_sel_offset, _clk_sel_shift, \ _flags) \ { \ .clk = { \ .id = CV1800B_CLK_ID_TRANSFORM(_id), \ .flags = _flags, \ }, \ .name = _name, \ .parent_infos = _parents, \ .num_parents = ARRAY_SIZE(_parents), \ .gate = CV1800B_CLK_REGBIT(_gate_offset, _gate_shift), \ .div = { \ CV1800B_CLK_REGFIELD(_div0_offset, _div0_shift, \ _div0_width), \ CV1800B_CLK_REGFIELD(_div1_offset, _div1_shift, \ _div1_width), \ }, \ .div_init = { _div0_init, _div1_init }, \ .mux = { \ CV1800B_CLK_REGFIELD(_mux0_offset, _mux0_shift, \ _mux0_width), \ CV1800B_CLK_REGFIELD(_mux1_offset, _mux1_shift, \ _mux1_width), \ }, \ .bypass = CV1800B_CLK_REGBIT(_bypass_offset, \ _bypass_shift), \ .clk_sel = CV1800B_CLK_REGBIT(_clk_sel_offset, \ _clk_sel_shift), \ } #define CV1800B_AUDIO(_id, _name, _parent, \ _src_en_offset, _src_en_shift, \ _output_en_offset, _output_en_shift, \ _div_en_offset, _div_en_shift, \ _div_up_offset, _div_up_shift, \ _m_offset, _m_shift, _m_width, \ _n_offset, _n_shift, _n_width, \ _flags) \ { \ .clk = { \ .id = CV1800B_CLK_ID_TRANSFORM(_id), \ .flags = _flags, \ }, \ .name = _name, \ .parent_name = _parent, \ .src_en = CV1800B_CLK_REGBIT(_src_en_offset, \ _src_en_shift), \ .output_en = CV1800B_CLK_REGBIT(_output_en_offset, \ _output_en_shift), \ .div_en = CV1800B_CLK_REGBIT(_div_en_offset, \ _div_en_shift), \ .div_up = CV1800B_CLK_REGBIT(_div_up_offset, \ _div_up_shift), \ .m = CV1800B_CLK_REGFIELD(_m_offset, _m_shift, \ _m_width), \ .n = CV1800B_CLK_REGFIELD(_n_offset, _n_shift, \ _n_width), \ } extern const struct clk_ops cv1800b_clk_gate_ops; extern const struct clk_ops cv1800b_clk_div_ops; extern const struct clk_ops cv1800b_clk_bypass_div_ops; extern const struct clk_ops cv1800b_clk_fixed_div_ops; extern const struct clk_ops cv1800b_clk_bypass_fixed_div_ops; extern const struct clk_ops cv1800b_clk_mux_ops; extern const struct clk_ops cv1800b_clk_bypass_mux_ops; extern const struct clk_ops cv1800b_clk_mmux_ops; extern const struct clk_ops cv1800b_clk_audio_ops; #endif /* __CLK_SOPHGO_IP_H__ */