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

283 lines
13 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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