1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
/* 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 PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
* IN ALLWINNERS’SDK 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 PARTY’S 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 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
|