mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-26 15:28:50 +00:00

Add clock controller driver for sophgo cv1800b SoC Signed-off-by: Kongyang Liu <seashell11234455@gmail.com> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
288 lines
7.9 KiB
C
288 lines
7.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
/*
|
|
* Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
|
|
*
|
|
*/
|
|
|
|
#ifndef __CLK_SOPHGO_IP_H__
|
|
#define __CLK_SOPHGO_IP_H__
|
|
|
|
#include <clk.h>
|
|
|
|
#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__ */
|