| /* SPDX-License-Identifier: GPL-2.0 */ |
| /* |
| * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com> |
| */ |
| |
| #ifndef _CLK_SOPHGO_CV1800_IP_H_ |
| #define _CLK_SOPHGO_CV1800_IP_H_ |
| |
| #include "clk-cv18xx-common.h" |
| |
| struct cv1800_clk_gate { |
| struct cv1800_clk_common common; |
| struct cv1800_clk_regbit gate; |
| }; |
| |
| struct cv1800_clk_div_data { |
| u32 reg; |
| u32 mask; |
| u32 width; |
| u32 init; |
| u32 flags; |
| }; |
| |
| struct cv1800_clk_div { |
| struct cv1800_clk_common common; |
| struct cv1800_clk_regbit gate; |
| struct cv1800_clk_regfield div; |
| }; |
| |
| struct cv1800_clk_bypass_div { |
| struct cv1800_clk_div div; |
| struct cv1800_clk_regbit bypass; |
| }; |
| |
| struct cv1800_clk_mux { |
| struct cv1800_clk_common common; |
| struct cv1800_clk_regbit gate; |
| struct cv1800_clk_regfield div; |
| struct cv1800_clk_regfield mux; |
| }; |
| |
| struct cv1800_clk_bypass_mux { |
| struct cv1800_clk_mux mux; |
| struct cv1800_clk_regbit bypass; |
| }; |
| |
| struct cv1800_clk_mmux { |
| struct cv1800_clk_common common; |
| struct cv1800_clk_regbit gate; |
| struct cv1800_clk_regfield div[2]; |
| struct cv1800_clk_regfield mux[2]; |
| struct cv1800_clk_regbit bypass; |
| struct cv1800_clk_regbit clk_sel; |
| const s8 *parent2sel; |
| const u8 *sel2parent[2]; |
| }; |
| |
| struct cv1800_clk_audio { |
| struct cv1800_clk_common common; |
| struct cv1800_clk_regbit src_en; |
| struct cv1800_clk_regbit output_en; |
| struct cv1800_clk_regbit div_en; |
| struct cv1800_clk_regbit div_up; |
| struct cv1800_clk_regfield m; |
| struct cv1800_clk_regfield n; |
| u32 target_rate; |
| }; |
| |
| #define CV1800_GATE(_name, _parent, _gate_reg, _gate_shift, _flags) \ |
| struct cv1800_clk_gate _name = { \ |
| .common = CV1800_CLK_COMMON(#_name, _parent, \ |
| &cv1800_clk_gate_ops, \ |
| _flags), \ |
| .gate = CV1800_CLK_BIT(_gate_reg, _gate_shift), \ |
| } |
| |
| #define _CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \ |
| _div_reg, _div_shift, _div_width, _div_init, \ |
| _div_flag, _ops, _flags) \ |
| { \ |
| .common = CV1800_CLK_COMMON(#_name, _parent, \ |
| _ops, _flags), \ |
| .gate = CV1800_CLK_BIT(_gate_reg, \ |
| _gate_shift), \ |
| .div = CV1800_CLK_REG(_div_reg, _div_shift, \ |
| _div_width, _div_init, \ |
| _div_flag), \ |
| } |
| |
| #define _CV1800_FIXED_DIV_FLAG \ |
| (CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ROUND_CLOSEST) |
| |
| #define _CV1800_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \ |
| _fix_div, _ops, _flags) \ |
| { \ |
| .common = CV1800_CLK_COMMON(#_name, _parent, \ |
| _ops, _flags), \ |
| .gate = CV1800_CLK_BIT(_gate_reg, \ |
| _gate_shift), \ |
| .div = CV1800_CLK_REG(0, 0, 0, \ |
| _fix_div, \ |
| _CV1800_FIXED_DIV_FLAG),\ |
| } |
| |
| #define CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \ |
| _div_reg, _div_shift, _div_width, _div_init, \ |
| _div_flag, _flags) \ |
| struct cv1800_clk_div _name = \ |
| _CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \ |
| _div_reg, _div_shift, _div_width, _div_init,\ |
| _div_flag, &cv1800_clk_div_ops, _flags) |
| |
| #define CV1800_BYPASS_DIV(_name, _parent, _gate_reg, _gate_shift, \ |
| _div_reg, _div_shift, _div_width, _div_init, \ |
| _div_flag, _bypass_reg, _bypass_shift, _flags)\ |
| struct cv1800_clk_bypass_div _name = { \ |
| .div = _CV1800_DIV(_name, _parent, \ |
| _gate_reg, _gate_shift, \ |
| _div_reg, _div_shift, \ |
| _div_width, _div_init, _div_flag, \ |
| &cv1800_clk_bypass_div_ops, \ |
| _flags), \ |
| .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \ |
| } |
| |
| #define CV1800_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \ |
| _fix_div, _flags) \ |
| struct cv1800_clk_div _name = \ |
| _CV1800_FIXED_DIV(_name, _parent, \ |
| _gate_reg, _gate_shift, \ |
| _fix_div, \ |
| &cv1800_clk_div_ops, _flags) \ |
| |
| #define CV1800_BYPASS_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \ |
| _fix_div, _bypass_reg, _bypass_shift, \ |
| _flags) \ |
| struct cv1800_clk_bypass_div _name = { \ |
| .div = _CV1800_FIXED_DIV(_name, _parent, \ |
| _gate_reg, _gate_shift, \ |
| _fix_div, \ |
| &cv1800_clk_bypass_div_ops, \ |
| _flags), \ |
| .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \ |
| } |
| |
| #define _CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \ |
| _div_reg, _div_shift, _div_width, _div_init, \ |
| _div_flag, \ |
| _mux_reg, _mux_shift, _mux_width, \ |
| _ops, _flags) \ |
| { \ |
| .common = CV1800_CLK_COMMON(#_name, _parent, \ |
| _ops, _flags), \ |
| .gate = CV1800_CLK_BIT(_gate_reg, \ |
| _gate_shift), \ |
| .div = CV1800_CLK_REG(_div_reg, _div_shift, \ |
| _div_width, _div_init, \ |
| _div_flag), \ |
| .mux = CV1800_CLK_REG(_mux_reg, _mux_shift, \ |
| _mux_width, 0, 0), \ |
| } |
| |
| #define CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \ |
| _div_reg, _div_shift, _div_width, _div_init, \ |
| _div_flag, \ |
| _mux_reg, _mux_shift, _mux_width, _flags) \ |
| struct cv1800_clk_mux _name = \ |
| _CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \ |
| _div_reg, _div_shift, _div_width, _div_init,\ |
| _div_flag, _mux_reg, _mux_shift, _mux_width,\ |
| &cv1800_clk_mux_ops, _flags) |
| |
| #define CV1800_BYPASS_MUX(_name, _parent, _gate_reg, _gate_shift, \ |
| _div_reg, _div_shift, _div_width, _div_init, \ |
| _div_flag, \ |
| _mux_reg, _mux_shift, _mux_width, \ |
| _bypass_reg, _bypass_shift, _flags) \ |
| struct cv1800_clk_bypass_mux _name = { \ |
| .mux = _CV1800_MUX(_name, _parent, \ |
| _gate_reg, _gate_shift, \ |
| _div_reg, _div_shift, _div_width, \ |
| _div_init, _div_flag, \ |
| _mux_reg, _mux_shift, _mux_width, \ |
| &cv1800_clk_bypass_mux_ops, \ |
| _flags), \ |
| .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \ |
| } |
| |
| #define CV1800_MMUX(_name, _parent, _gate_reg, _gate_shift, \ |
| _div0_reg, _div0_shift, _div0_width, _div0_init, \ |
| _div0_flag, \ |
| _div1_reg, _div1_shift, _div1_width, _div1_init, \ |
| _div1_flag, \ |
| _mux0_reg, _mux0_shift, _mux0_width, \ |
| _mux1_reg, _mux1_shift, _mux1_width, \ |
| _bypass_reg, _bypass_shift, \ |
| _clk_sel_reg, _clk_sel_shift, \ |
| _parent2sel, _sel2parent0, _sel2parent1, _flags) \ |
| struct cv1800_clk_mmux _name = { \ |
| .common = CV1800_CLK_COMMON(#_name, _parent, \ |
| &cv1800_clk_mmux_ops,\ |
| _flags), \ |
| .gate = CV1800_CLK_BIT(_gate_reg, _gate_shift),\ |
| .div = { \ |
| CV1800_CLK_REG(_div0_reg, _div0_shift, \ |
| _div0_width, _div0_init, \ |
| _div0_flag), \ |
| CV1800_CLK_REG(_div1_reg, _div1_shift, \ |
| _div1_width, _div1_init, \ |
| _div1_flag), \ |
| }, \ |
| .mux = { \ |
| CV1800_CLK_REG(_mux0_reg, _mux0_shift, \ |
| _mux0_width, 0, 0), \ |
| CV1800_CLK_REG(_mux1_reg, _mux1_shift, \ |
| _mux1_width, 0, 0), \ |
| }, \ |
| .bypass = CV1800_CLK_BIT(_bypass_reg, \ |
| _bypass_shift), \ |
| .clk_sel = CV1800_CLK_BIT(_clk_sel_reg, \ |
| _clk_sel_shift), \ |
| .parent2sel = _parent2sel, \ |
| .sel2parent = { _sel2parent0, _sel2parent1 }, \ |
| } |
| |
| #define CV1800_ACLK(_name, _parent, \ |
| _src_en_reg, _src_en_reg_shift, \ |
| _output_en_reg, _output_en_shift, \ |
| _div_en_reg, _div_en_reg_shift, \ |
| _div_up_reg, _div_up_reg_shift, \ |
| _m_reg, _m_shift, _m_width, _m_flag, \ |
| _n_reg, _n_shift, _n_width, _n_flag, \ |
| _target_rate, _flags) \ |
| struct cv1800_clk_audio _name = { \ |
| .common = CV1800_CLK_COMMON(#_name, _parent, \ |
| &cv1800_clk_audio_ops,\ |
| _flags), \ |
| .src_en = CV1800_CLK_BIT(_src_en_reg, \ |
| _src_en_reg_shift), \ |
| .output_en = CV1800_CLK_BIT(_output_en_reg, \ |
| _output_en_shift), \ |
| .div_en = CV1800_CLK_BIT(_div_en_reg, \ |
| _div_en_reg_shift), \ |
| .div_up = CV1800_CLK_BIT(_div_up_reg, \ |
| _div_up_reg_shift), \ |
| .m = CV1800_CLK_REG(_m_reg, _m_shift, \ |
| _m_width, 0, _m_flag), \ |
| .n = CV1800_CLK_REG(_n_reg, _n_shift, \ |
| _n_width, 0, _n_flag), \ |
| .target_rate = _target_rate, \ |
| } |
| |
| extern const struct clk_ops cv1800_clk_gate_ops; |
| extern const struct clk_ops cv1800_clk_div_ops; |
| extern const struct clk_ops cv1800_clk_bypass_div_ops; |
| extern const struct clk_ops cv1800_clk_mux_ops; |
| extern const struct clk_ops cv1800_clk_bypass_mux_ops; |
| extern const struct clk_ops cv1800_clk_mmux_ops; |
| extern const struct clk_ops cv1800_clk_audio_ops; |
| |
| #endif // _CLK_SOPHGO_CV1800_IP_H_ |