1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2020 Rockchip Electronics Co. Ltd.
4 *
5 * Author: Guochun Huang <hero.huang@rock-chips.com>
6 */
7
8 #include "rk628_cru.h"
9
10 #define REFCLK_RATE 24000000UL
11 #define MIN_FREF_RATE 10000000UL
12 #define MAX_FREF_RATE 800000000UL
13 #define MIN_FREFDIV_RATE 1000000UL
14 #define MAX_FREFDIV_RATE 100000000UL
15 #define MIN_FVCO_RATE 600000000UL
16 #define MAX_FVCO_RATE 1600000000UL
17 #define MIN_FOUTPOSTDIV_RATE 12000000UL
18 #define MAX_FOUTPOSTDIV_RATE 1600000000UL
19
rational_best_approximation(unsigned long given_numerator,unsigned long given_denominator,unsigned long max_numerator,unsigned long max_denominator,unsigned long * best_numerator,unsigned long * best_denominator)20 static void rational_best_approximation(unsigned long given_numerator,
21 unsigned long given_denominator,
22 unsigned long max_numerator,
23 unsigned long max_denominator,
24 unsigned long *best_numerator,
25 unsigned long *best_denominator)
26 {
27 unsigned long n, d, n0, d0, n1, d1;
28
29 n = given_numerator;
30 d = given_denominator;
31 n0 = d1 = 0;
32 n1 = d0 = 1;
33 for (;;) {
34 unsigned long t, a;
35
36 if ((n1 > max_numerator) || (d1 > max_denominator)) {
37 n1 = n0;
38 d1 = d0;
39 break;
40 }
41 if (d == 0)
42 break;
43 t = d;
44 a = n / d;
45 d = n % d;
46 n = t;
47 t = n0 + a * n1;
48 n0 = n1;
49 n1 = t;
50 t = d0 + a * d1;
51 d0 = d1;
52 d1 = t;
53 }
54 *best_numerator = n1;
55 *best_denominator = d1;
56 }
57
rk628_cru_clk_get_rate_pll(struct rk628 * rk628,unsigned int id)58 static unsigned long rk628_cru_clk_get_rate_pll(struct rk628 *rk628,
59 unsigned int id)
60 {
61 unsigned long parent_rate = REFCLK_RATE;
62 u32 postdiv1, fbdiv, dsmpd, postdiv2, refdiv, frac, bypass;
63 u32 con0 = 0, con1 = 0, con2 = 0;
64 u64 foutvco, foutpostdiv;
65 u32 offset, val = 0;
66
67 if (id == CGU_CLK_APLL && rk628->version < RK628F_VERSION)
68 return 0;
69
70 rk628_i2c_read(rk628, CRU_MODE_CON00, &val);
71 if (id == CGU_CLK_CPLL) {
72 val &= CLK_CPLL_MODE_MASK;
73 val >>= CLK_CPLL_MODE_SHIFT;
74 if (val == CLK_CPLL_MODE_OSC)
75 return parent_rate;
76
77 offset = 0x00;
78 } else if (id == CGU_CLK_GPLL) {
79 val &= CLK_GPLL_MODE_MASK;
80 val >>= CLK_GPLL_MODE_SHIFT;
81 if (val == CLK_GPLL_MODE_OSC)
82 return parent_rate;
83
84 offset = 0x20;
85 } else {
86 val &= CLK_APLL_MODE_MASK;
87 val >>= CLK_APLL_MODE_SHIFT;
88 if (val == CLK_APLL_MODE_OSC)
89 return parent_rate;
90
91 offset = 0x40;
92 }
93
94 rk628_i2c_read(rk628, offset + CRU_CPLL_CON0, &con0);
95 rk628_i2c_read(rk628, offset + CRU_CPLL_CON1, &con1);
96 rk628_i2c_read(rk628, offset + CRU_CPLL_CON2, &con2);
97
98 bypass = (con0 & PLL_BYPASS_MASK) >> PLL_BYPASS_SHIFT;
99 postdiv1 = (con0 & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
100 fbdiv = (con0 & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
101 dsmpd = (con1 & PLL_DSMPD_MASK) >> PLL_DSMPD_SHIFT;
102 postdiv2 = (con1 & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
103 refdiv = (con1 & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
104 frac = (con2 & PLL_FRAC_MASK) >> PLL_FRAC_SHIFT;
105
106 if (bypass)
107 return parent_rate;
108
109 foutvco = parent_rate * fbdiv;
110 do_div(foutvco, refdiv);
111
112 if (!dsmpd) {
113 u64 frac_rate = (u64)parent_rate * frac;
114
115 do_div(frac_rate, refdiv);
116 foutvco += frac_rate >> 24;
117 }
118
119 foutpostdiv = foutvco;
120 do_div(foutpostdiv, postdiv1);
121 do_div(foutpostdiv, postdiv2);
122
123 return foutpostdiv;
124 }
125
rk628_cru_clk_set_rate_pll(struct rk628 * rk628,unsigned int id,unsigned long rate)126 static unsigned long rk628_cru_clk_set_rate_pll(struct rk628 *rk628,
127 unsigned int id,
128 unsigned long rate)
129 {
130 unsigned long fin = REFCLK_RATE, fout = rate;
131 u8 min_refdiv, max_refdiv, postdiv;
132 u8 dsmpd = 1, postdiv1 = 0, postdiv2 = 0, refdiv = 0;
133 u16 fbdiv = 0;
134 u32 frac = 0;
135 u64 foutvco, foutpostdiv, div1, div2;
136 u32 offset, val = 0;
137
138 /*
139 * FREF : 10MHz ~ 800MHz
140 * FREFDIV : 1MHz ~ 40MHz
141 * FOUTVCO : 400MHz ~ 1.6GHz
142 * FOUTPOSTDIV : 8MHz ~ 1.6GHz
143 */
144 if (fin < MIN_FREF_RATE || fin > MAX_FREF_RATE)
145 return 0;
146
147 if (fout < MIN_FOUTPOSTDIV_RATE || fout > MAX_FOUTPOSTDIV_RATE)
148 return 0;
149
150 if (id == CGU_CLK_CPLL)
151 offset = 0x00;
152 else if (id == CGU_CLK_GPLL)
153 offset = 0x20;
154 else
155 offset = 0x40;
156
157 if (id != CGU_CLK_APLL)
158 rk628_i2c_write(rk628, offset + CRU_CPLL_CON1, PLL_PD(1));
159
160 if (fin == fout) {
161 rk628_i2c_write(rk628, offset + CRU_CPLL_CON0, PLL_BYPASS(1));
162 rk628_i2c_write(rk628, offset + CRU_CPLL_CON1, PLL_PD(0));
163 while (1) {
164 rk628_i2c_read(rk628, offset + CRU_CPLL_CON1, &val);
165 if (val & PLL_LOCK)
166 break;
167 }
168 return fin;
169 }
170
171 min_refdiv = fin / MAX_FREFDIV_RATE + 1;
172 max_refdiv = fin / MIN_FREFDIV_RATE;
173 if (max_refdiv > 64)
174 max_refdiv = 64;
175
176 if (fout < MIN_FVCO_RATE) {
177 div1 = DIV_ROUND_UP(MIN_FVCO_RATE, fout);
178 div2 = DIV_ROUND_UP(MAX_FVCO_RATE, fout);
179 for (postdiv = div1; postdiv <= div2; postdiv++) {
180 /* fix prime number that can not find right div*/
181 for (postdiv2 = 1; postdiv2 < 8; postdiv2++) {
182 if (postdiv % postdiv2)
183 continue;
184 postdiv1 = postdiv / postdiv2;
185 if (postdiv1 > 0 && postdiv1 < 8)
186 break;
187 }
188 if (postdiv2 > 7)
189 continue;
190 else
191 break;
192 }
193 if (postdiv > div2)
194 return 0;
195 fout *= postdiv1 * postdiv2;
196 } else {
197 postdiv1 = 1;
198 postdiv2 = 1;
199 }
200
201 for (refdiv = min_refdiv; refdiv <= max_refdiv; refdiv++) {
202 u64 tmp, frac_rate;
203
204 if (fin % refdiv)
205 continue;
206
207 tmp = (u64)fout * refdiv;
208 do_div(tmp, fin);
209 fbdiv = tmp;
210 if (fbdiv < 10 || fbdiv > 1600)
211 continue;
212
213 tmp = (u64)fbdiv * fin;
214 do_div(tmp, refdiv);
215 if (fout < MIN_FVCO_RATE || fout > MAX_FVCO_RATE)
216 continue;
217
218 frac_rate = fout - tmp;
219
220 if (frac_rate) {
221 tmp = (u64)frac_rate * refdiv;
222 tmp <<= 24;
223 do_div(tmp, fin);
224 frac = tmp;
225 dsmpd = 0;
226 }
227
228 break;
229 }
230
231 /*
232 * If DSMPD = 1 (DSM is disabled, "integer mode")
233 * FOUTVCO = FREF / REFDIV * FBDIV
234 * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
235 *
236 * If DSMPD = 0 (DSM is enabled, "fractional mode")
237 * FOUTVCO = FREF / REFDIV * (FBDIV + FRAC / 2^24)
238 * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
239 */
240 foutvco = fin * fbdiv;
241 do_div(foutvco, refdiv);
242
243 if (!dsmpd) {
244 u64 frac_rate = (u64)fin * frac;
245
246 do_div(frac_rate, refdiv);
247 foutvco += frac_rate >> 24;
248 }
249
250 foutpostdiv = foutvco;
251 do_div(foutpostdiv, postdiv1);
252 do_div(foutpostdiv, postdiv2);
253
254 rk628_i2c_write(rk628, offset + CRU_CPLL_CON0,
255 PLL_BYPASS(0) | PLL_POSTDIV1(postdiv1) |
256 PLL_FBDIV(fbdiv));
257 rk628_i2c_write(rk628, offset + CRU_CPLL_CON1,
258 PLL_DSMPD(dsmpd) | PLL_POSTDIV2(postdiv2) |
259 PLL_REFDIV(refdiv));
260 rk628_i2c_write(rk628, offset + CRU_CPLL_CON2, PLL_FRAC(frac));
261
262 if (id != CGU_CLK_APLL)
263 rk628_i2c_write(rk628, offset + CRU_CPLL_CON1, PLL_PD(0));
264
265 while (1) {
266 rk628_i2c_read(rk628, offset + CRU_CPLL_CON1, &val);
267 if (val & PLL_LOCK)
268 break;
269 }
270
271 return (unsigned long)foutpostdiv;
272 }
273
rk628_cru_clk_set_rate_sclk_vop(struct rk628 * rk628,unsigned long rate)274 static unsigned long rk628_cru_clk_set_rate_sclk_vop(struct rk628 *rk628,
275 unsigned long rate)
276 {
277 unsigned long m, n, parent_rate;
278 u32 val = 0;
279
280 rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &val);
281 val &= SCLK_VOP_SEL_MASK;
282 val >>= SCLK_VOP_SEL_SHIFT;
283 if (val == SCLK_VOP_SEL_GPLL)
284 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
285 else
286 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
287
288 rational_best_approximation(rate, parent_rate,
289 GENMASK(15, 0), GENMASK(15, 0),
290 &m, &n);
291 rk628_i2c_write(rk628, CRU_CLKSEL_CON13, m << 16 | n);
292
293 return rate;
294 }
295
rk628_cru_clk_get_rate_sclk_vop(struct rk628 * rk628)296 static unsigned long rk628_cru_clk_get_rate_sclk_vop(struct rk628 *rk628)
297 {
298 unsigned long rate, parent_rate, m, n;
299 u32 mux, div = 0;
300
301 rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &mux);
302 mux &= CLK_UART_SRC_SEL_MASK;
303 mux >>= SCLK_VOP_SEL_SHIFT;
304 if (mux == SCLK_VOP_SEL_GPLL)
305 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
306 else
307 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
308
309 rk628_i2c_read(rk628, CRU_CLKSEL_CON13, &div);
310 m = div >> 16 & 0xffff;
311 n = div & 0xffff;
312 rate = parent_rate * m / n;
313
314 return rate;
315 }
316
rk628_cru_clk_get_rate_clk_imodet(struct rk628 * rk628)317 static unsigned long rk628_cru_clk_get_rate_clk_imodet(struct rk628 *rk628)
318 {
319 unsigned long rate, parent_rate, n;
320 u32 mux = 0, div = 0;
321
322 rk628_i2c_read(rk628, CRU_CLKSEL_CON05, &mux);
323 mux &= CLK_IMODET_SEL_MASK;
324 mux >>= CLK_IMODET_SEL_SHIFT;
325 if (mux == SCLK_VOP_SEL_GPLL)
326 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
327 else
328 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
329
330 rk628_i2c_read(rk628, CRU_CLKSEL_CON05, &div);
331 n = div & 0x1f;
332 rate = parent_rate / (n + 1);
333
334 return rate;
335 }
336
rk628_cru_clk_set_rate_rx_read(struct rk628 * rk628,unsigned long rate)337 static unsigned long rk628_cru_clk_set_rate_rx_read(struct rk628 *rk628,
338 unsigned long rate)
339 {
340 unsigned long m, n, parent_rate;
341 u32 val = 0;
342
343 rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &val);
344 val &= CLK_RX_READ_SEL_MASK;
345 val >>= CLK_RX_READ_SEL_SHIFT;
346 if (val == CLK_RX_READ_SEL_GPLL)
347 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
348 else
349 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
350
351 rational_best_approximation(rate, parent_rate,
352 GENMASK(15, 0), GENMASK(15, 0),
353 &m, &n);
354 rk628_i2c_write(rk628, CRU_CLKSEL_CON14, m << 16 | n);
355
356 return rate;
357 }
358
rk628_cru_clk_get_rate_uart_src(struct rk628 * rk628)359 static unsigned long rk628_cru_clk_get_rate_uart_src(struct rk628 *rk628)
360 {
361 unsigned long rate, parent_rate;
362 u32 mux, div = 0;
363
364 rk628_i2c_read(rk628, CRU_CLKSEL_CON21, &mux);
365 mux &= SCLK_VOP_SEL_MASK;
366 if (mux == CLK_UART_SRC_SEL_GPLL)
367 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
368 else
369 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
370
371 rk628_i2c_read(rk628, CRU_CLKSEL_CON21, &div);
372 div &= CLK_UART_SRC_DIV_MASK;
373 div >>= CLK_UART_SRC_DIV_SHIFT;
374 rate = parent_rate / (div + 1);
375
376 return rate;
377 }
378
rk628_cru_clk_set_rate_sclk_uart(struct rk628 * rk628,unsigned long rate)379 static unsigned long rk628_cru_clk_set_rate_sclk_uart(struct rk628 *rk628,
380 unsigned long rate)
381 {
382 unsigned long m, n, parent_rate;
383
384 parent_rate = rk628_cru_clk_get_rate_uart_src(rk628);
385
386 if (rate == REFCLK_RATE) {
387 rk628_i2c_write(rk628, CRU_CLKSEL_CON06,
388 SCLK_UART_SEL(SCLK_UART_SEL_OSC));
389 return rate;
390 } else if (rate == parent_rate) {
391 rk628_i2c_write(rk628, CRU_CLKSEL_CON06,
392 SCLK_UART_SEL(SCLK_UART_SEL_UART_SRC));
393 return rate;
394 }
395
396 rk628_i2c_write(rk628, CRU_CLKSEL_CON06,
397 SCLK_UART_SEL(SCLK_UART_SEL_UART_FRAC));
398
399 rational_best_approximation(rate, parent_rate,
400 GENMASK(15, 0), GENMASK(15, 0),
401 &m, &n);
402 rk628_i2c_write(rk628, CRU_CLKSEL_CON20, m << 16 | n);
403
404 return rate;
405 }
406
rk628_cru_clk_set_rate_sclk_hdmirx_aud(struct rk628 * rk628,unsigned long rate)407 static unsigned long rk628_cru_clk_set_rate_sclk_hdmirx_aud(struct rk628 *rk628, unsigned long rate)
408 {
409 u64 parent_rate;
410 u8 div;
411
412 if (rk628->version >= RK628F_VERSION)
413 parent_rate = rk628_cru_clk_set_rate_pll(rk628, CGU_CLK_APLL, rate*4);
414 else
415 parent_rate = rk628_cru_clk_set_rate_pll(rk628, CGU_CLK_GPLL, rate*4);
416 div = DIV_ROUND_CLOSEST(parent_rate, rate);
417 do_div(parent_rate, div);
418 rate = parent_rate;
419 if (rk628->version >= RK628F_VERSION)
420 rk628_i2c_write(rk628, CRU_CLKSEL_CON05, CLK_HDMIRX_AUD_DIV(div - 1) |
421 CLK_HDMIRX_AUD_SEL_V2(2));
422 else
423 rk628_i2c_write(rk628, CRU_CLKSEL_CON05, CLK_HDMIRX_AUD_DIV(div - 1) |
424 CLK_HDMIRX_AUD_SEL_V1(1));
425 return rate;
426 }
427
rk628_cru_clk_get_rate_sclk_hdmirx_aud(struct rk628 * rk628)428 static unsigned long rk628_cru_clk_get_rate_sclk_hdmirx_aud(struct rk628 *rk628)
429 {
430 unsigned long rate;
431 u64 parent_rate;
432 u8 div = 0;
433 u32 val = 0;
434
435 rk628_i2c_read(rk628, CRU_CLKSEL_CON05, &val);
436 div = ((val & CLK_HDMIRX_AUD_DIV_MASK) >> 6) + 1;
437 if (rk628->version >= RK628F_VERSION)
438 val = (val & CLK_HDMIRX_AUD_SEL_MASK_V2) >> 14;
439 else
440 val = (val & CLK_HDMIRX_AUD_SEL_MASK_V1) >> 15;
441 if (!val)
442 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
443 else if (val == 2)
444 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_APLL);
445 else
446 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
447 do_div(parent_rate, div);
448 rate = parent_rate;
449 return rate;
450 }
451
452 static unsigned long
rk628_cru_clk_get_rate_bt1120_dec_parent(struct rk628 * rk628)453 rk628_cru_clk_get_rate_bt1120_dec_parent(struct rk628 *rk628)
454 {
455 unsigned long parent_rate;
456 u32 mux;
457
458 rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &mux);
459 mux &= CLK_BT1120DEC_SEL_MASK;
460 if (mux == CLK_BT1120DEC_SEL_GPLL)
461 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL);
462 else
463 parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL);
464
465 return parent_rate;
466 }
467
rk628_cru_clk_set_rate_bt1120_dec(struct rk628 * rk628,unsigned long rate)468 static unsigned long rk628_cru_clk_set_rate_bt1120_dec(struct rk628 *rk628,
469 unsigned long rate)
470 {
471 unsigned long parent_rate;
472 u32 div;
473
474 parent_rate = rk628_cru_clk_get_rate_bt1120_dec_parent(rk628);
475 div = DIV_ROUND_UP(parent_rate, rate);
476 rk628_i2c_write(rk628, CRU_CLKSEL_CON02, CLK_BT1120DEC_DIV(div-1));
477
478 return parent_rate / div;
479 }
480
rk628_cru_clk_get_rate_bt1120_dec(struct rk628 * rk628)481 static unsigned long rk628_cru_clk_get_rate_bt1120_dec(struct rk628 *rk628)
482 {
483 unsigned long parent_rate;
484 u32 div = 0;
485
486 parent_rate = rk628_cru_clk_get_rate_bt1120_dec_parent(rk628);
487
488 rk628_i2c_read(rk628, CRU_CLKSEL_CON02, &div);
489 div = (div & 0x1f) + 1;
490
491 return parent_rate / div;
492 }
493
rk628_cru_clk_set_rate(struct rk628 * rk628,unsigned int id,unsigned long rate)494 int rk628_cru_clk_set_rate(struct rk628 *rk628, unsigned int id,
495 unsigned long rate)
496 {
497 if (id == CGU_CLK_APLL && rk628->version < RK628F_VERSION)
498 return -EINVAL;
499
500 switch (id) {
501 case CGU_CLK_APLL:
502 case CGU_CLK_CPLL:
503 case CGU_CLK_GPLL:
504 rk628_cru_clk_set_rate_pll(rk628, id, rate);
505 break;
506 case CGU_CLK_RX_READ:
507 rk628_cru_clk_set_rate_rx_read(rk628, rate);
508 break;
509 case CGU_SCLK_VOP:
510 rk628_cru_clk_set_rate_sclk_vop(rk628, rate);
511 break;
512 case CGU_SCLK_UART:
513 rk628_cru_clk_set_rate_sclk_uart(rk628, rate);
514 break;
515 case CGU_BT1120DEC:
516 rk628_cru_clk_set_rate_bt1120_dec(rk628, rate);
517 break;
518 case CGU_CLK_HDMIRX_AUD:
519 rk628_cru_clk_set_rate_sclk_hdmirx_aud(rk628, rate);
520 break;
521 default:
522 return -EINVAL;
523 }
524
525 return 0;
526 }
527
rk628_cru_clk_get_rate(struct rk628 * rk628,unsigned int id)528 unsigned long rk628_cru_clk_get_rate(struct rk628 *rk628, unsigned int id)
529 {
530 unsigned long rate;
531
532 if (id == CGU_CLK_APLL && rk628->version < RK628F_VERSION)
533 return 0;
534
535 switch (id) {
536 case CGU_CLK_APLL:
537 case CGU_CLK_CPLL:
538 case CGU_CLK_GPLL:
539 rate = rk628_cru_clk_get_rate_pll(rk628, id);
540 break;
541 case CGU_SCLK_VOP:
542 rate = rk628_cru_clk_get_rate_sclk_vop(rk628);
543 break;
544 case CGU_CLK_IMODET:
545 rate = rk628_cru_clk_get_rate_clk_imodet(rk628);
546 break;
547 case CGU_CLK_HDMIRX_AUD:
548 rate = rk628_cru_clk_get_rate_sclk_hdmirx_aud(rk628);
549 break;
550 case CGU_BT1120DEC:
551 rate = rk628_cru_clk_get_rate_bt1120_dec(rk628);
552 break;
553 default:
554 return 0;
555 }
556
557 return rate;
558 }
559
rk628_cru_init(struct rk628 * rk628)560 void rk628_cru_init(struct rk628 *rk628)
561 {
562 u32 val = 0;
563 u8 mcu_mode;
564
565 rk628_i2c_read(rk628, GRF_SYSTEM_STATUS0, &val);
566 mcu_mode = (val & I2C_ONLY_FLAG) ? 0 : 1;
567 if (mcu_mode || rk628->version >= RK628F_VERSION) {
568 rk628_i2c_write(rk628, CRU_MODE_CON00, HIWORD_UPDATE(1, 4, 4));
569 return;
570 }
571 rk628_i2c_write(rk628, CRU_GPLL_CON0, 0xffff701d);
572 mdelay(1);
573 rk628_i2c_write(rk628, CRU_MODE_CON00, 0xffff0004);
574 mdelay(1);
575 rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff0080);
576 rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff0083);
577 rk628_i2c_write(rk628, CRU_CPLL_CON0, 0xffff3063);
578 mdelay(1);
579 rk628_i2c_write(rk628, CRU_MODE_CON00, 0xffff0005);
580 rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff0003);
581 rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff000b);
582 rk628_i2c_write(rk628, CRU_GPLL_CON0, 0xffff1028);
583 mdelay(1);
584 rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff008b);
585 rk628_i2c_write(rk628, CRU_CPLL_CON0, 0xffff1063);
586 mdelay(1);
587 rk628_i2c_write(rk628, CRU_CLKSEL_CON00, 0x00ff000b);
588 }
589