mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 20:24:12 +08:00
80fd61ec46
Add clock definition and driver code for CV1800 SoC. Signed-off-by: Inochi Amaoto <inochiama@outlook.com> Link:6f4e9b8ecb/duo/datasheet/CV180X-Clock-v1.xlsx
Link:6f4e9b8ecb/duo/datasheet/CV1800B-CV1801B-Preliminary-Datasheet-full-en.pdf
Link: https://lore.kernel.org/r/IA1PR20MB49534F37F802CAF117364D66BB262@IA1PR20MB4953.namprd20.prod.outlook.com Signed-off-by: Stephen Boyd <sboyd@kernel.org>
262 lines
8.1 KiB
C
262 lines
8.1 KiB
C
/* 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_
|