sdk-hwV1.3/lichee/rtos-hal/hal/source/ccmu/sunxi/clk_factors.h

283 lines
13 KiB
C
Raw Normal View History

2024-05-07 10:09:20 +00:00
/* Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
*
* Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
*the the People's Republic of China and other countries.
* All Allwinner Technology Co.,Ltd. trademarks are used with permission.
*
* DISCLAIMER
* THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
* IF YOU NEED TO INTEGRATE THIRD PARTYS TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
* IN ALLWINNERSSDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
* ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
* ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
* COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
* YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTYS TECHNOLOGY.
*
*
* THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
* PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
* THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
* OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __CLK_FACTORS_H__
#define __CLK_FACTORS_H__
#include "clk.h"
struct sunxi_clk_factor_freq
{
u32 factor;
u32 freq;
};
#define FACTOR_ALL(nv, ns, nw, kv, ks, kw, mv, ms, mw, \
pv, ps, pw, d1v, d1s, d1w, d2v, d2s, d2w) \
((((nv & ((1 << nw) - 1)) << ns) | \
((kv & ((1 << kw) - 1)) << ks) | \
((mv & ((1 << mw) - 1)) << ms) | \
((pv & ((1 << pw) - 1)) << ps) | \
((d1v & ((1 << d1w) - 1)) << d1s) | \
((d2v & ((1 << d2w) - 1)) << d2s)))
#define F_N8X8_P16x2(nv, pv) (FACTOR_ALL(nv, 8, 8, 0, 0, 0, 0, 0, 0, pv, 16, 2, 0, 0, 0, 0, 0, 0))
#define F_N8X8_D1V1X1_D2V0X1(nv, d1v, d2v) (FACTOR_ALL(nv, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, d1v, 1, 1, d2v, 0, 1))
#define F_N8X8_D1V1X1(nv, d1v) (FACTOR_ALL(nv, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, d1v, 1, 1, 0, 0, 0))
#define F_N8X8_D1V4X2_D2V0X2(nv, d1v, d2v) (FACTOR_ALL(nv, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, d1v, 4, 2, d2v, 0, 2))
#define F_N8X8_P16X6_D1V1X1_D2V0X1(nv, pv, d1v, d2v) (FACTOR_ALL(nv, 8, 8, 0, 0, 0, 0, 0, 0, pv, 16, 6, d1v, 1, 1, d2v, 0, 1))
#define PLLCPU(n, p, freq) {F_N8X8_P16x2(n, p), freq}
#define PLLDDR(n, d1, d2, freq) {F_N8X8_D1V1X1_D2V0X1(n, d1, d2), freq}
#define PLLPERIPH0(n, d1, d2, freq) {F_N8X8_D1V1X1_D2V0X1(n, d1, d2), freq}
#define PLLPERIPH1(n, d1, d2, freq) {F_N8X8_D1V1X1_D2V0X1(n, d1, d2), freq}
#define PLLVIDEO0(n, d1, freq) {F_N8X8_D1V1X1(n, d1), freq}
#define PLLAUDIO(n, p, d1, d2, freq) {F_N8X8_P16X6_D1V1X1_D2V0X1(n, p, d1, d2), freq}
#define PLLCSI(n, d1, freq) {F_N8X8_D1V1X1(n, d1), freq}
#define PLLNPU(n, d1, freq) {F_N8X8_D1V1X1(n, d1), freq}
#define SUNXI_CLK_FACTORS_CONFIG(name, _nshift, _nwidth, _kshift, _kwidth, \
_mshift, _mwidth, _pshift, _pwidth, _d1shift, _d1width, \
_d2shift, _d2width, _frac, _outshift, _modeshift, \
_enshift, _sdmshift, _sdmwidth, _sdmpat, _sdmval, \
_mux_inshift, _out_enshift) \
struct sunxi_clk_factors_config sunxi_clk_factor_config_##name = { \
.nshift = _nshift, \
.nwidth = _nwidth, \
.kshift = _kshift, \
.kwidth = _kwidth, \
.mshift = _mshift, \
.mwidth = _mwidth, \
.pshift = _pshift, \
.pwidth = _pwidth, \
.d1shift = _d1shift, \
.d1width = _d1width, \
.d2shift = _d2shift, \
.d2width = _d2width, \
.frac = _frac, \
.outshift = _outshift, \
.modeshift = _modeshift, \
.enshift = _enshift, \
.sdmshift = _sdmshift, \
.sdmwidth = _sdmwidth, \
.sdmpat = _sdmpat, \
.sdmval = _sdmval, \
.updshift = 0, \
.mux_inshift = _mux_inshift, \
.out_enshift = _out_enshift, \
}
#define SUNXI_CLK_FACTORS_INIT(_name, _reg, _lock_reg, _lock_bit, _pll_lock_ctrl_reg, _lock_en_bit ) \
struct factor_init_data sunxi_clk_factor_init_##_name = { \
.reg =_reg, \
.lock_reg = _lock_reg, \
.pll_lock_ctrl_reg = _pll_lock_ctrl_reg, \
.lock_bit = _lock_bit, \
.lock_en_bit = _lock_en_bit, \
.lock_mode = PLL_LOCK_NEW_MODE, \
.config = &sunxi_clk_factor_config_##_name, \
.get_factors = &get_factors_##_name, \
.calc_rate = &calc_rate_##_name, \
}
#define SUNXI_CLK_FACTOR(_name, _clk, _current_parent, _current_parent_type, _clk_rate, _parent_rate ) \
clk_factor_t sunxi_clk_factor_##_name = { \
.clk_core = { \
.clk = _clk, \
.clk_type = HAL_CLK_FACTOR, \
.current_parent = _current_parent, \
.current_parent_type = _current_parent_type, \
.clk_rate = _clk_rate, \
.parent_rate = _parent_rate, \
.clk_enbale = HAL_CLK_STATUS_DISABLED, \
}, \
.factor_data = &sunxi_clk_factor_init_##_name, \
}
/*no-change-from-linux*/
typedef enum pll_lock_mode
{
PLL_LOCK_NEW_MODE = 0x0,
PLL_LOCK_OLD_MODE,
PLL_LOCK_NONE_MODE,
PLL_LOCK_MODE_MAX,
} pll_lock_mode_e;
/**
* struct clk_factors_value - factor value
*
* @factorn: factor-n value
* @factork: factor-k value
* @factorm: factor-m value
* @factorp: factor-p value
* @factord1: factor-d1 value
* @factord2: factor-d2 value
* @frac_mode: fraction mode value
* @frac_freq: fraction frequnecy value
*/
/*no-change-from-linux*/
struct clk_factors_value
{
u16 factorn;
u16 factork;
u16 factorm;
u16 factorp;
u16 factord1;
u16 factord2;
u16 frac_mode;
u16 frac_freq;
};
/**
* struct sunxi_clk_factors_config - factor config
*
* @nshift: shift to factor-n bit field
* @nwidth: width of factor-n bit field
* @kshift: shift to factor-k bit field
* @kwidth: width of factor-k bit field
* @mshift: shift to factor-m bit field
* @mwidth: width of factor-m bit field
* @pshift: shift to factor-p bit field
* @pwidth: width of factor-p bit field
* @d1shift: shift to factor-d1 bit field
* @d1width: width of factor-d1 bit field
* @d2shift: shift to factor-d2 bit field
* @d2width: width of factor-d2 bit field
* @frac: flag of fraction
* @outshift: shift to frequency select bit field
* @modeshift: shift to fraction/integer mode select
* @enshift: shift to factor enable bit field
* @lockshift: shift to factor lock status bit filed
* @sdmshift: shift to factor sdm enable bit filed
* @sdmwidth shift to factor sdm width bit filed
* @sdmpat sdmpat reg address offset
* @sdmval sdm default value
* @updshift shift to update bit (especial for ddr/ddr0/ddr1)
* @delay for flat factors delay.
* @mux_inshift shift to multiplexer(multiple 24M source clocks) bit field
* @out_enshift shift to enable pll clock output bit field
*/
/*no-change-from-linux*/
struct sunxi_clk_factors_config
{
u8 nshift;
u8 nwidth;
u8 kshift;
u8 kwidth;
u8 mshift;
u8 mwidth;
u8 pshift;
u8 pwidth;
u8 d1shift;
u8 d1width;
u8 d2shift;
u8 d2width;
u8 frac;
u8 outshift;
u8 modeshift;
u8 enshift;
u8 lockshift;
u8 sdmshift;
u8 sdmwidth;
volatile uint32_t *sdmpat;
u32 sdmval;
u32 updshift;
u32 delay;
u32 mux_inshift;
u32 out_enshift;
};
/**
* struct factor_init_data - factor init data
*
* @name: name of the clock
* @parent_name:name of the parent
* @num_parents:counter of the parents
* @flags: factor optimal configurations
* @reg: register address for the factor
* @lock_reg: register address for check if the pll has locked
* @lock_bit: bit offset of the lock_reg, to check if the the pll has locked
* @pll_lock_ctrl_reg: pll lock control register, this function is first used on
* the sun50i, to enable the function of pll hardlock
* @lock_en_bit:bit offset of the pll_lock_ctrl_reg, to enable the function
* @config: configuration of the factor
* @get_factors:function for get factors parameter under a given frequency
* @calc_rate: function for calculate the factor frequency
* @priv_ops: private operations hook for the special factor
* @priv_regops:register operation hook for read/write the register
*
*/
struct factor_init_data
{
//const char *name;
//const char **parent_names;
//int num_parents;
//unsigned long flags;
volatile uint32_t *reg;
volatile uint32_t *lock_reg;
volatile uint32_t *pll_lock_ctrl_reg;
u8 lock_bit;
u8 lock_en_bit;
pll_lock_mode_e lock_mode;
struct sunxi_clk_factors_config *config;
int (*get_factors)(u32 rate, u32 parent_rate, struct clk_factors_value *factor);
int (*calc_rate)(u32 parent_rate, struct clk_factors_value *factor);
//struct clk_ops *priv_ops;
//struct sunxi_reg_ops *priv_regops;
};
hal_clk_status_t sunxi_clk_fators_enable(clk_factor_pt clk);
hal_clk_status_t sunxi_clk_fators_disable(clk_factor_pt clk);
hal_clk_status_t sunxi_clk_fators_is_enabled(clk_factor_pt clk);
hal_clk_status_t sunxi_clk_factors_recalc_rate(clk_factor_pt clk, u32 *rate);
hal_clk_status_t sunxi_clk_factors_set_rate(clk_factor_pt clk, u32 rate);
u32 sunxi_clk_factors_round_rate(clk_factor_pt clk, u32 rate);
int sunxi_clk_com_ftr_sr(struct sunxi_clk_factors_config *f_config,
struct clk_factors_value *factor,
struct sunxi_clk_factor_freq table[],
unsigned long index, unsigned long tbl_count);
#endif