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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
|
/*
*********************************************************************************************************
* AR100 SYSTEM
* AR100 Software System Develop Kits
* clock control unit module
*
* (c) Copyright 2012-2016, Sunny China
* All Rights Reserved
*
* File : sclk.c
* By : Sunny
* Version : v1.0
* Date : 2012-5-7
* Descript: system clock management.
* Update : date auther ver notes
* 2012-5-7 8:43:10 Sunny 1.0 Create this file.
*********************************************************************************************************
*/
#include <delay.h>
#include "ccu_i.h"
#include "errno.h"
#include "hal_prcm.h"
#include "stdio.h"
#include "aw_common.h"
#include "compiler_attributes.h"
static ccu_pll_audio0_reg_t *pll_audio0 = (ccu_pll_audio0_reg_t *)CCU_PLL_AUDIO0_REG;
static ccu_pll_audio1_reg_t *pll_audio1 = (ccu_pll_audio1_reg_t *)CCU_PLL_AUDIO1_REG;
static ccu_pll_audio0_pat0_reg_t *pll_audio0_pat0 = (ccu_pll_audio0_pat0_reg_t *)CCU_PLL_AUDIO0_PAT0_REG;
static ccu_pll_audio1_pat0_reg_t *pll_audio1_pat0 = (ccu_pll_audio1_pat0_reg_t *)CCU_PLL_AUDIO1_PAT0_REG;
static s32 ccu_set_pll_audio0(u32 freq)
{
static u32 old_freq = 0;
s32 loop = 0;
if (freq == old_freq)
return 0;
UNUSED(pll_audio0_pat0);
old_freq = freq;
/* make sure pll new mode is disable */
pll_audio0->lock_en = 0;
pll_audio0->lock_st = 0;
switch (freq) {
default:
printf("not support freq:%d, now set freq:24576000Hz.\n", freq);
case 24576000:
#if 0
/* *pll_audio0_pat0 = 0xc00126e9;*/
/* bit0 - bit16, wave bottom */
pll_audio0_pat0->wave_bot = 0x126e9;
/* bit17 - bit18, frequency */
pll_audio0_pat0->freq = 0;
/* bit19, 0:24M, 1:12M, SDM clk select */
pll_audio0_pat0->clk_sel = 0;
/* bit20 - bit28, wave step */
pll_audio0_pat0->wave_step = 0;
/* bit29 - bit30, Spread frequency mode */
pll_audio0_pat0->freq_mode = 0;
/* bit31, 0-disable, 1-enable, Sigma-Delta Pattern Enable */
pll_audio0_pat0->enable = 1;
/* fix for arch32 or arch64 */
*((unsigned long *)pll_audio0) = 0x890b1701;
#endif
break;
case 22579200:
#if 0
/* *pll_audio1_pat0 = 0xc001288d;*/
/* bit0 - bit16, wave bottom */
pll_audio1_pat0->wave_bot = 0x1288d;
/* bit17 - bit18, frequency */
pll_audio1_pat0->freq = 0;
/* bit19, 0:24M, 1:12M, SDM clk select */
pll_audio1_pat0->clk_sel = 0;
/* bit20 - bit28, wave step */
pll_audio1_pat0->wave_step = 0;
/* bit29 - bit30, Spread frequency mode */
pll_audio1_pat0->freq_mode = 0;
/* bit31, 0-disable, 1-enable, Sigma-Delta Pattern Enable */
pll_audio1_pat0->enable = 1;
*((unsigned long *)pll_audio1) = 0x890b1501;
#endif
break;
}
if (pll_audio0->enable) {
pll_audio0->lock_st = 1;
pll_audio0->lock_en = 1;
while (pll_audio0->lock_st && (--loop > 0)) {
udelay(1);
}
pll_audio0->lock_en = 0;
pll_audio0->lock_st = 0;
}
return 0;
}
static s32 ccu_set_pll_audio1(u32 freq)
{
static u32 old_freq = 0;
s32 loop = 0;
if (freq == old_freq)
return 0;
old_freq = freq;
/* make sure pll new mode is disable */
pll_audio1->lock_en = 0;
pll_audio1->lock_st = 0;
switch (freq) {
default:
printf("not support freq:%d, now set freq:24576000Hz.\n", freq);
case 24576000:
/* *pll_audio1_pat0 = 0xc00126e9;*/
/* bit0 - bit16, wave bottom */
pll_audio1_pat0->wave_bot = 0x126e9;
/* bit17 - bit18, frequency */
pll_audio1_pat0->freq = 0;
/* bit19, 0:24M, 1:12M, SDM clk select */
pll_audio1_pat0->clk_sel = 0;
/* bit20 - bit28, wave step */
pll_audio1_pat0->wave_step = 0;
/* bit29 - bit30, Spread frequency mode */
pll_audio1_pat0->freq_mode = 0;
/* bit31, 0-disable, 1-enable, Sigma-Delta Pattern Enable */
pll_audio1_pat0->enable = 1;
/* fix for arch32 or arch64 */
*((unsigned long *)pll_audio1) = 0x890b1701;
break;
case 22579200:
/* *pll_audio1_pat0 = 0xc001288d;*/
/* bit0 - bit16, wave bottom */
pll_audio1_pat0->wave_bot = 0x1288d;
/* bit17 - bit18, frequency */
pll_audio1_pat0->freq = 0;
/* bit19, 0:24M, 1:12M, SDM clk select */
pll_audio1_pat0->clk_sel = 0;
/* bit20 - bit28, wave step */
pll_audio1_pat0->wave_step = 0;
/* bit29 - bit30, Spread frequency mode */
pll_audio1_pat0->freq_mode = 0;
/* bit31, 0-disable, 1-enable, Sigma-Delta Pattern Enable */
pll_audio1_pat0->enable = 1;
*((unsigned long *)pll_audio1) = 0x890b1501;
break;
case 90316800:
/* *pll_audio1_pat0 = 0xc001288d;*/
/* bit0 - bit16, wave bottom */
pll_audio1_pat0->wave_bot = 0x1288d;
/* bit17 - bit18, frequency */
pll_audio1_pat0->freq = 0;
/* bit19, 0:24M, 1:12M, SDM clk select */
pll_audio1_pat0->clk_sel = 0;
/* bit20 - bit28, wave step */
pll_audio1_pat0->wave_step = 0;
/* bit29 - bit30, Spread frequency mode */
pll_audio1_pat0->freq_mode = 0;
/* bit31, 0-disable, 1-enable, Sigma-Delta Pattern Enable */
pll_audio1_pat0->enable = 1;
*((unsigned long *)pll_audio1) = 0x89021501;
break;
case 98304000:
/* *pll_audio1_pat0 = 0xc00126e9;*/
/* bit0 - bit16, wave bottom */
pll_audio1_pat0->wave_bot = 0x126e9;
/* bit17 - bit18, frequency */
pll_audio1_pat0->freq = 0;
/* bit19, 0:24M, 1:12M, SDM clk select */
pll_audio1_pat0->clk_sel = 0;
/* bit20 - bit28, wave step */
pll_audio1_pat0->wave_step = 0;
/* bit29 - bit30, Spread frequency mode */
pll_audio1_pat0->freq_mode = 0;
/* bit31, 0-disable, 1-enable, Sigma-Delta Pattern Enable */
pll_audio1_pat0->enable = 1;
*((unsigned long *)pll_audio1) = 0x89021701;
break;
}
if (pll_audio1->enable) {
pll_audio1->lock_st = 1;
pll_audio1->lock_en = 1;
while (pll_audio1->lock_st && (--loop > 0)) {
udelay(1);
}
pll_audio1->lock_en = 0;
pll_audio1->lock_st = 0;
}
return 0;
}
/*
*********************************************************************************************************
* SET SOURCE FREQUENCY
*
* Description: set the frequency of a specific source clock.
*
* Arguments : sclk : the source clock ID which we want to set frequency.
* freq : the frequency which we want to set.
*
* Returns : OK if set source frequency succeeded, others if failed.
*********************************************************************************************************
*/
s32 ccu_set_sclk_freq(u32 sclk, __maybe_unused u32 freq)
{
switch (sclk) {
case CCU_SYS_CLK_AUDIO0:
return ccu_set_pll_audio0(freq);
case CCU_SYS_CLK_AUDIO1:
return ccu_set_pll_audio1(freq);
default:
pr_warning("invaid clock id (%d) when set freq(%d)\n", sclk);
return -EINVAL;
}
/* un-reached */
}
/*
*********************************************************************************************************
* GET SOURCE FREQUENCY
*
* Description: get the frequency of a specific source clock.
*
* Arguments : sclk : the source clock ID which we want to get frequency.
*
* Returns : frequency of the specific source clock.
*********************************************************************************************************
*/
u32 ccu_get_sclk_freq(u32 sclk)
{
switch (sclk) {
case CCU_SYS_CLK_LOSC: {
return losc_freq;
}
case CCU_SYS_CLK_HOSC: {
return CCU_HOSC_FREQ;
}
case CCU_SYS_CLK_CPUX: {
/* maybe should delete */
ccu_pll_c0_cpux_reg0000_t pll_c0 = *(ccu_pll_c0_cpux_reg_addr);
return (CCU_HOSC_FREQ * (pll_c0.factor_n + 1)) /
((pll_c0.factor_m + 1) * (1 << pll_c0.factor_p));
}
case CCU_SYS_CLK_CPUS: {
switch (ccu_reg_addr->cpus_clk_cfg.src_sel) {
case 0: {
/* cpus clock source is losc */
return CCU_HOSC_FREQ;
}
case 1: {
/* cpus clock source is hosc */
return losc_freq;
}
case 2: {
/* cpus clock source is internal-osc */
return iosc_freq;
}
case 3: {
/* cpus clock source is pll_peri0(2x) */
return ccu_get_sclk_freq(CCU_SYS_CLK_PERI_2X) /
(1 << ccu_reg_addr->cpus_clk_cfg.factor_n) /
(ccu_reg_addr->cpus_clk_cfg.factor_m + 1);
}
case 4: {
return ccu_get_sclk_freq(CCU_SYS_CLK_AUDIO0_DIV2) /
(1 << ccu_reg_addr->cpus_clk_cfg.factor_n) /
(ccu_reg_addr->cpus_clk_cfg.factor_m + 1);
}
default: {
return 0;
}
}
}
case CCU_SYS_CLK_AHBS: {
return ccu_get_sclk_freq(CCU_SYS_CLK_CPUS);
}
case CCU_SYS_CLK_APBS1: {
return ccu_get_sclk_freq(CCU_SYS_CLK_AHBS) /
ccu_get_mclk_div(CCU_MOD_CLK_APBS1);
}
case CCU_SYS_CLK_APBS2: {
switch (ccu_reg_addr->apbs2_cfg.src_sel) {
case 0: {
/* cpus clock source is losc */
return CCU_HOSC_FREQ;
}
case 1: {
/* cpus clock source is hosc */
return losc_freq;
}
case 2: {
/* cpus clock source is internal-osc */
return iosc_freq;
}
case 3: {
/* cpus clock source is pll6 */
return ccu_get_sclk_freq(CCU_SYS_CLK_PLL3) /
(ccu_reg_addr->apbs2_cfg.factor_m + 1) /
(1 << ccu_reg_addr->apbs2_cfg.factor_n);
}
default: {
return 0;
}
}
}
case CCU_SYS_CLK_PERI_1X: {
/* output=24M*N*K/2 */
ccu_pll_periph_reg0010_t pll_periph0 =
*(ccu_pll_periph0_reg_addr);
return ((long long)CCU_HOSC_FREQ * (pll_periph0.factor_n + 1) /
(pll_periph0.factor_m + 1) /
(pll_periph0.factor_p0 + 1) / 2);
}
case CCU_SYS_CLK_PERI_2X: {
ccu_pll_periph_reg0010_t pll_periph0 =
*(ccu_pll_periph0_reg_addr);
return ((long long)CCU_HOSC_FREQ * (pll_periph0.factor_n + 1) /
(pll_periph0.factor_m + 1) /
(pll_periph0.factor_p0 + 1));
}
case CCU_SYS_CLK_AUDIO0_DIV2: {
ccu_pll_audio0_reg0020_t pll_audio0 =
*(ccu_pll_audio0_reg_addr);
return ((long long)CCU_HOSC_FREQ * (pll_audio0.factor_n + 1) /
(pll_audio0.factor_m + 1) / (pll_audio0.factor_p0 + 1));
}
}
pr_warning("invalid clock id for get source freq\n");
return 0;
}
s32 ccu_set_sclk_onoff(u32 sclk, s32 onoff)
{
switch (sclk) {
case CCU_SYS_CLK_C0:
{
ccu_pll_c0_cpux_reg_addr->enable = onoff;
return OK;
}
case CCU_SYS_CLK_DDR0:
{
ccu_pll_ddr0_reg_addr->enable = onoff;
return OK;
}
case CCU_SYS_CLK_PERI0:
{
ccu_pll_periph0_reg_addr->enable = onoff;
return OK;
}
case CCU_SYS_CLK_AUDIO0:
{
pll_audio0->enable = onoff;
return OK;
}
case CCU_SYS_CLK_AUDIO1:
{
pll_audio1->enable = onoff;
return OK;
}
default:
pr_warning("invalid clock id for get source freq\n");
}
return 0;
}
|