262 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com>4 */5 6#ifndef _CLK_SOPHGO_CV1800_IP_H_7#define _CLK_SOPHGO_CV1800_IP_H_8 9#include "clk-cv18xx-common.h"10 11struct cv1800_clk_gate {12 struct cv1800_clk_common common;13 struct cv1800_clk_regbit gate;14};15 16struct cv1800_clk_div_data {17 u32 reg;18 u32 mask;19 u32 width;20 u32 init;21 u32 flags;22};23 24struct cv1800_clk_div {25 struct cv1800_clk_common common;26 struct cv1800_clk_regbit gate;27 struct cv1800_clk_regfield div;28};29 30struct cv1800_clk_bypass_div {31 struct cv1800_clk_div div;32 struct cv1800_clk_regbit bypass;33};34 35struct cv1800_clk_mux {36 struct cv1800_clk_common common;37 struct cv1800_clk_regbit gate;38 struct cv1800_clk_regfield div;39 struct cv1800_clk_regfield mux;40};41 42struct cv1800_clk_bypass_mux {43 struct cv1800_clk_mux mux;44 struct cv1800_clk_regbit bypass;45};46 47struct cv1800_clk_mmux {48 struct cv1800_clk_common common;49 struct cv1800_clk_regbit gate;50 struct cv1800_clk_regfield div[2];51 struct cv1800_clk_regfield mux[2];52 struct cv1800_clk_regbit bypass;53 struct cv1800_clk_regbit clk_sel;54 const s8 *parent2sel;55 const u8 *sel2parent[2];56};57 58struct cv1800_clk_audio {59 struct cv1800_clk_common common;60 struct cv1800_clk_regbit src_en;61 struct cv1800_clk_regbit output_en;62 struct cv1800_clk_regbit div_en;63 struct cv1800_clk_regbit div_up;64 struct cv1800_clk_regfield m;65 struct cv1800_clk_regfield n;66 u32 target_rate;67};68 69#define CV1800_GATE(_name, _parent, _gate_reg, _gate_shift, _flags) \70 struct cv1800_clk_gate _name = { \71 .common = CV1800_CLK_COMMON(#_name, _parent, \72 &cv1800_clk_gate_ops, \73 _flags), \74 .gate = CV1800_CLK_BIT(_gate_reg, _gate_shift), \75 }76 77#define _CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \78 _div_reg, _div_shift, _div_width, _div_init, \79 _div_flag, _ops, _flags) \80 { \81 .common = CV1800_CLK_COMMON(#_name, _parent, \82 _ops, _flags), \83 .gate = CV1800_CLK_BIT(_gate_reg, \84 _gate_shift), \85 .div = CV1800_CLK_REG(_div_reg, _div_shift, \86 _div_width, _div_init, \87 _div_flag), \88 }89 90#define _CV1800_FIXED_DIV_FLAG \91 (CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ROUND_CLOSEST)92 93#define _CV1800_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \94 _fix_div, _ops, _flags) \95 { \96 .common = CV1800_CLK_COMMON(#_name, _parent, \97 _ops, _flags), \98 .gate = CV1800_CLK_BIT(_gate_reg, \99 _gate_shift), \100 .div = CV1800_CLK_REG(0, 0, 0, \101 _fix_div, \102 _CV1800_FIXED_DIV_FLAG),\103 }104 105#define CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \106 _div_reg, _div_shift, _div_width, _div_init, \107 _div_flag, _flags) \108 struct cv1800_clk_div _name = \109 _CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \110 _div_reg, _div_shift, _div_width, _div_init,\111 _div_flag, &cv1800_clk_div_ops, _flags)112 113#define CV1800_BYPASS_DIV(_name, _parent, _gate_reg, _gate_shift, \114 _div_reg, _div_shift, _div_width, _div_init, \115 _div_flag, _bypass_reg, _bypass_shift, _flags)\116 struct cv1800_clk_bypass_div _name = { \117 .div = _CV1800_DIV(_name, _parent, \118 _gate_reg, _gate_shift, \119 _div_reg, _div_shift, \120 _div_width, _div_init, _div_flag, \121 &cv1800_clk_bypass_div_ops, \122 _flags), \123 .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \124 }125 126#define CV1800_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \127 _fix_div, _flags) \128 struct cv1800_clk_div _name = \129 _CV1800_FIXED_DIV(_name, _parent, \130 _gate_reg, _gate_shift, \131 _fix_div, \132 &cv1800_clk_div_ops, _flags) \133 134#define CV1800_BYPASS_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \135 _fix_div, _bypass_reg, _bypass_shift, \136 _flags) \137 struct cv1800_clk_bypass_div _name = { \138 .div = _CV1800_FIXED_DIV(_name, _parent, \139 _gate_reg, _gate_shift, \140 _fix_div, \141 &cv1800_clk_bypass_div_ops, \142 _flags), \143 .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \144 }145 146#define _CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \147 _div_reg, _div_shift, _div_width, _div_init, \148 _div_flag, \149 _mux_reg, _mux_shift, _mux_width, \150 _ops, _flags) \151 { \152 .common = CV1800_CLK_COMMON(#_name, _parent, \153 _ops, _flags), \154 .gate = CV1800_CLK_BIT(_gate_reg, \155 _gate_shift), \156 .div = CV1800_CLK_REG(_div_reg, _div_shift, \157 _div_width, _div_init, \158 _div_flag), \159 .mux = CV1800_CLK_REG(_mux_reg, _mux_shift, \160 _mux_width, 0, 0), \161 }162 163#define CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \164 _div_reg, _div_shift, _div_width, _div_init, \165 _div_flag, \166 _mux_reg, _mux_shift, _mux_width, _flags) \167 struct cv1800_clk_mux _name = \168 _CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \169 _div_reg, _div_shift, _div_width, _div_init,\170 _div_flag, _mux_reg, _mux_shift, _mux_width,\171 &cv1800_clk_mux_ops, _flags)172 173#define CV1800_BYPASS_MUX(_name, _parent, _gate_reg, _gate_shift, \174 _div_reg, _div_shift, _div_width, _div_init, \175 _div_flag, \176 _mux_reg, _mux_shift, _mux_width, \177 _bypass_reg, _bypass_shift, _flags) \178 struct cv1800_clk_bypass_mux _name = { \179 .mux = _CV1800_MUX(_name, _parent, \180 _gate_reg, _gate_shift, \181 _div_reg, _div_shift, _div_width, \182 _div_init, _div_flag, \183 _mux_reg, _mux_shift, _mux_width, \184 &cv1800_clk_bypass_mux_ops, \185 _flags), \186 .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \187 }188 189#define CV1800_MMUX(_name, _parent, _gate_reg, _gate_shift, \190 _div0_reg, _div0_shift, _div0_width, _div0_init, \191 _div0_flag, \192 _div1_reg, _div1_shift, _div1_width, _div1_init, \193 _div1_flag, \194 _mux0_reg, _mux0_shift, _mux0_width, \195 _mux1_reg, _mux1_shift, _mux1_width, \196 _bypass_reg, _bypass_shift, \197 _clk_sel_reg, _clk_sel_shift, \198 _parent2sel, _sel2parent0, _sel2parent1, _flags) \199 struct cv1800_clk_mmux _name = { \200 .common = CV1800_CLK_COMMON(#_name, _parent, \201 &cv1800_clk_mmux_ops,\202 _flags), \203 .gate = CV1800_CLK_BIT(_gate_reg, _gate_shift),\204 .div = { \205 CV1800_CLK_REG(_div0_reg, _div0_shift, \206 _div0_width, _div0_init, \207 _div0_flag), \208 CV1800_CLK_REG(_div1_reg, _div1_shift, \209 _div1_width, _div1_init, \210 _div1_flag), \211 }, \212 .mux = { \213 CV1800_CLK_REG(_mux0_reg, _mux0_shift, \214 _mux0_width, 0, 0), \215 CV1800_CLK_REG(_mux1_reg, _mux1_shift, \216 _mux1_width, 0, 0), \217 }, \218 .bypass = CV1800_CLK_BIT(_bypass_reg, \219 _bypass_shift), \220 .clk_sel = CV1800_CLK_BIT(_clk_sel_reg, \221 _clk_sel_shift), \222 .parent2sel = _parent2sel, \223 .sel2parent = { _sel2parent0, _sel2parent1 }, \224 }225 226#define CV1800_ACLK(_name, _parent, \227 _src_en_reg, _src_en_reg_shift, \228 _output_en_reg, _output_en_shift, \229 _div_en_reg, _div_en_reg_shift, \230 _div_up_reg, _div_up_reg_shift, \231 _m_reg, _m_shift, _m_width, _m_flag, \232 _n_reg, _n_shift, _n_width, _n_flag, \233 _target_rate, _flags) \234 struct cv1800_clk_audio _name = { \235 .common = CV1800_CLK_COMMON(#_name, _parent, \236 &cv1800_clk_audio_ops,\237 _flags), \238 .src_en = CV1800_CLK_BIT(_src_en_reg, \239 _src_en_reg_shift), \240 .output_en = CV1800_CLK_BIT(_output_en_reg, \241 _output_en_shift), \242 .div_en = CV1800_CLK_BIT(_div_en_reg, \243 _div_en_reg_shift), \244 .div_up = CV1800_CLK_BIT(_div_up_reg, \245 _div_up_reg_shift), \246 .m = CV1800_CLK_REG(_m_reg, _m_shift, \247 _m_width, 0, _m_flag), \248 .n = CV1800_CLK_REG(_n_reg, _n_shift, \249 _n_width, 0, _n_flag), \250 .target_rate = _target_rate, \251 }252 253extern const struct clk_ops cv1800_clk_gate_ops;254extern const struct clk_ops cv1800_clk_div_ops;255extern const struct clk_ops cv1800_clk_bypass_div_ops;256extern const struct clk_ops cv1800_clk_mux_ops;257extern const struct clk_ops cv1800_clk_bypass_mux_ops;258extern const struct clk_ops cv1800_clk_mmux_ops;259extern const struct clk_ops cv1800_clk_audio_ops;260 261#endif // _CLK_SOPHGO_CV1800_IP_H_262