xref: /aosp_15_r20/external/coreboot/src/soc/samsung/exynos5250/clock.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <assert.h>
5 #include <console/console.h>
6 #include <soc/clk.h>
7 #include <soc/periph.h>
8 #include <timer.h>
9 
10 /* input clock of PLL: SMDK5250 has 24MHz input clock */
11 #define CONF_SYS_CLK_FREQ            24000000
12 
13 static struct arm_clk_ratios arm_clk_ratios[] = {
14 	{
15 		.arm_freq_mhz = 600,
16 
17 		.apll_mdiv = 0xc8,
18 		.apll_pdiv = 0x4,
19 		.apll_sdiv = 0x1,
20 
21 		.arm2_ratio = 0x0,
22 		.apll_ratio = 0x1,
23 		.pclk_dbg_ratio = 0x1,
24 		.atb_ratio = 0x2,
25 		.periph_ratio = 0x7,
26 		.acp_ratio = 0x7,
27 		.cpud_ratio = 0x1,
28 		.arm_ratio = 0x0,
29 	}, {
30 		.arm_freq_mhz = 800,
31 
32 		.apll_mdiv = 0x64,
33 		.apll_pdiv = 0x3,
34 		.apll_sdiv = 0x0,
35 
36 		.arm2_ratio = 0x0,
37 		.apll_ratio = 0x1,
38 		.pclk_dbg_ratio = 0x1,
39 		.atb_ratio = 0x3,
40 		.periph_ratio = 0x7,
41 		.acp_ratio = 0x7,
42 		.cpud_ratio = 0x2,
43 		.arm_ratio = 0x0,
44 	}, {
45 		.arm_freq_mhz = 1000,
46 
47 		.apll_mdiv = 0x7d,
48 		.apll_pdiv = 0x3,
49 		.apll_sdiv = 0x0,
50 
51 		.arm2_ratio = 0x0,
52 		.apll_ratio = 0x1,
53 		.pclk_dbg_ratio = 0x1,
54 		.atb_ratio = 0x4,
55 		.periph_ratio = 0x7,
56 		.acp_ratio = 0x7,
57 		.cpud_ratio = 0x2,
58 		.arm_ratio = 0x0,
59 	}, {
60 		.arm_freq_mhz = 1200,
61 
62 		.apll_mdiv = 0x96,
63 		.apll_pdiv = 0x3,
64 		.apll_sdiv = 0x0,
65 
66 		.arm2_ratio = 0x0,
67 		.apll_ratio = 0x3,
68 		.pclk_dbg_ratio = 0x1,
69 		.atb_ratio = 0x5,
70 		.periph_ratio = 0x7,
71 		.acp_ratio = 0x7,
72 		.cpud_ratio = 0x3,
73 		.arm_ratio = 0x0,
74 	}, {
75 		.arm_freq_mhz = 1400,
76 
77 		.apll_mdiv = 0xaf,
78 		.apll_pdiv = 0x3,
79 		.apll_sdiv = 0x0,
80 
81 		.arm2_ratio = 0x0,
82 		.apll_ratio = 0x3,
83 		.pclk_dbg_ratio = 0x1,
84 		.atb_ratio = 0x6,
85 		.periph_ratio = 0x7,
86 		.acp_ratio = 0x7,
87 		.cpud_ratio = 0x3,
88 		.arm_ratio = 0x0,
89 	}, {
90 		.arm_freq_mhz = 1700,
91 
92 		.apll_mdiv = 0x1a9,
93 		.apll_pdiv = 0x6,
94 		.apll_sdiv = 0x0,
95 
96 		.arm2_ratio = 0x0,
97 		.apll_ratio = 0x3,
98 		.pclk_dbg_ratio = 0x1,
99 		.atb_ratio = 0x6,
100 		.periph_ratio = 0x7,
101 		.acp_ratio = 0x7,
102 		.cpud_ratio = 0x3,
103 		.arm_ratio = 0x0,
104 	}
105 };
106 
107 /* src_bit div_bit prediv_bit */
108 static struct clk_bit_info clk_bit_info[PERIPH_ID_COUNT] = {
109 	{0,	4,	0,	-1},
110 	{4,	4,	4,	-1},
111 	{8,	4,	8,	-1},
112 	{12,	4,	12,	-1},
113 	{0,	4,	0,	8},
114 	{4,	4,	16,	24},
115 	{8,	4,	0,	8},
116 	{12,	4,	16,	24},
117 	{-1,	-1,	-1,	-1},
118 	{16,	4,	0,	8}, /* PERIPH_ID_SROMC */
119 	{20,	4,	16,	24},
120 	{24,	4,	0,	8},
121 	{0,	4,	0,	4},
122 	{4,	4,	12,	16},
123 	{-1,	4,	-1,	-1},
124 	{-1,	4,	-1,	-1},
125 	{-1,	4,	24,	0},
126 	{-1,	4,	24,	0},
127 	{-1,	4,	24,	0},
128 	{-1,	4,	24,	0},
129 	{-1,	4,	24,	0},
130 	{-1,	4,	24,	0},
131 	{-1,	4,	24,	0},
132 	{-1,	4,	24,	0},
133 	{24,	4,	0,	-1},
134 	{24,	4,	0,	-1},
135 	{24,	4,	0,	-1},
136 	{24,	4,	0,	-1},
137 	{24,	4,	0,	-1},
138 	{-1,	-1,	-1,	-1},
139 	{-1,	-1,	-1,	-1},
140 	{-1,	-1,	-1,	-1}, /* PERIPH_ID_I2S1 */
141 	{24,	1,	20,	-1}, /* PERIPH_ID_SATA */
142 };
143 
144 /* Epll Clock division values to achieve different frequency output */
145 static struct st_epll_con_val epll_div[] = {
146 	{ 192000000, 0, 48, 3, 1, 0 },
147 	{ 180000000, 0, 45, 3, 1, 0 },
148 	{  73728000, 1, 73, 3, 3, 47710 },
149 	{  67737600, 1, 90, 4, 3, 20762 },
150 	{  49152000, 0, 49, 3, 3, 9961 },
151 	{  45158400, 0, 45, 3, 3, 10381 },
152 	{ 180633600, 0, 45, 3, 1, 10381 }
153 };
154 
155 /* exynos5: return pll clock frequency */
get_pll_clk(int pllreg)156 unsigned long get_pll_clk(int pllreg)
157 {
158 	unsigned long r, m, p, s, k = 0, mask, fout;
159 	unsigned int freq;
160 
161 	switch (pllreg) {
162 	case APLL:
163 		r = read32(&exynos_clock->apll_con0);
164 		break;
165 	case BPLL:
166 		r = read32(&exynos_clock->bpll_con0);
167 		break;
168 	case MPLL:
169 		r = read32(&exynos_clock->mpll_con0);
170 		break;
171 	case EPLL:
172 		r = read32(&exynos_clock->epll_con0);
173 		k = read32(&exynos_clock->epll_con1);
174 		break;
175 	case VPLL:
176 		r = read32(&exynos_clock->vpll_con0);
177 		k = read32(&exynos_clock->vpll_con1);
178 		break;
179 	default:
180 		printk(BIOS_DEBUG, "Unsupported PLL (%d)\n", pllreg);
181 		return 0;
182 	}
183 
184 	/*
185 	 * APLL_CON: MIDV [25:16]
186 	 * MPLL_CON: MIDV [25:16]
187 	 * EPLL_CON: MIDV [24:16]
188 	 * VPLL_CON: MIDV [24:16]
189 	 */
190 	if (pllreg == APLL || pllreg == BPLL || pllreg == MPLL)
191 		mask = 0x3ff;
192 	else
193 		mask = 0x1ff;
194 
195 	m = (r >> 16) & mask;
196 
197 	/* PDIV [13:8] */
198 	p = (r >> 8) & 0x3f;
199 	/* SDIV [2:0] */
200 	s = r & 0x7;
201 
202 	freq = CONF_SYS_CLK_FREQ;
203 
204 	if (pllreg == EPLL) {
205 		k = k & 0xffff;
206 		/* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
207 		fout = (m + k / 65536) * (freq / (p * (1 << s)));
208 	} else if (pllreg == VPLL) {
209 		k = k & 0xfff;
210 		/* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */
211 		fout = (m + k / 1024) * (freq / (p * (1 << s)));
212 	} else {
213 		/* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
214 		fout = m * (freq / (p * (1 << s)));
215 	}
216 
217 	return fout;
218 }
219 
clock_get_periph_rate(enum periph_id peripheral)220 unsigned long clock_get_periph_rate(enum periph_id peripheral)
221 {
222 	struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
223 	unsigned long sclk, sub_clk;
224 	unsigned int src, div, sub_div;
225 
226 	switch (peripheral) {
227 	case PERIPH_ID_UART0:
228 	case PERIPH_ID_UART1:
229 	case PERIPH_ID_UART2:
230 	case PERIPH_ID_UART3:
231 		src = read32(&exynos_clock->src_peric0);
232 		div = read32(&exynos_clock->div_peric0);
233 		break;
234 	case PERIPH_ID_PWM0:
235 	case PERIPH_ID_PWM1:
236 	case PERIPH_ID_PWM2:
237 	case PERIPH_ID_PWM3:
238 	case PERIPH_ID_PWM4:
239 		src = read32(&exynos_clock->src_peric0);
240 		div = read32(&exynos_clock->div_peric3);
241 		break;
242 	case PERIPH_ID_SPI0:
243 	case PERIPH_ID_SPI1:
244 		src = read32(&exynos_clock->src_peric1);
245 		div = read32(&exynos_clock->div_peric1);
246 		break;
247 	case PERIPH_ID_SPI2:
248 		src = read32(&exynos_clock->src_peric1);
249 		div = read32(&exynos_clock->div_peric2);
250 		break;
251 	case PERIPH_ID_SPI3:
252 	case PERIPH_ID_SPI4:
253 		src = read32(&exynos_clock->sclk_src_isp);
254 		div = read32(&exynos_clock->sclk_div_isp);
255 		break;
256 	case PERIPH_ID_SATA:
257 		src = read32(&exynos_clock->src_fsys);
258 		div = read32(&exynos_clock->div_fsys0);
259 		break;
260 	case PERIPH_ID_SDMMC0:
261 	case PERIPH_ID_SDMMC1:
262 	case PERIPH_ID_SDMMC2:
263 	case PERIPH_ID_SDMMC3:
264 		src = read32(&exynos_clock->src_fsys);
265 		div = read32(&exynos_clock->div_fsys1);
266 		break;
267 	case PERIPH_ID_I2C0:
268 	case PERIPH_ID_I2C1:
269 	case PERIPH_ID_I2C2:
270 	case PERIPH_ID_I2C3:
271 	case PERIPH_ID_I2C4:
272 	case PERIPH_ID_I2C5:
273 	case PERIPH_ID_I2C6:
274 	case PERIPH_ID_I2C7:
275 		sclk = get_pll_clk(MPLL);
276 		sub_div = ((read32(&exynos_clock->div_top1)
277 			    >> bit_info->div_bit) & 0x7) + 1;
278 		div = ((read32(&exynos_clock->div_top0)
279 		        >> bit_info->prediv_bit) & 0x7) + 1;
280 		return (sclk / sub_div) / div;
281 	default:
282 		printk(BIOS_DEBUG, "%s: invalid peripheral %d", __func__, peripheral);
283 		return -1;
284 	};
285 
286 	src = (src >> bit_info->src_bit) & ((1 << bit_info->n_src_bits) - 1);
287 	if (peripheral == PERIPH_ID_SATA) {
288 		if (src)
289 			sclk = get_pll_clk(BPLL);
290 		else
291 			sclk = get_pll_clk(MPLL);
292 	} else {
293 		if (src == SRC_MPLL)
294 			sclk = get_pll_clk(MPLL);
295 		else if (src == SRC_EPLL)
296 			sclk = get_pll_clk(EPLL);
297 		else if (src == SRC_VPLL)
298 			sclk = get_pll_clk(VPLL);
299 		else
300 			return 0;
301 	}
302 
303 	sub_div = (div >> bit_info->div_bit) & 0xf;
304 	sub_clk = sclk / (sub_div + 1);
305 
306 	if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) {
307 		div = (div >> bit_info->prediv_bit) & 0xff;
308 		return sub_clk / (div + 1);
309 	}
310 
311 	return sub_clk;
312 }
313 
314 /* exynos5: return ARM clock frequency */
get_arm_clk(void)315 unsigned long get_arm_clk(void)
316 {
317 	unsigned long div;
318 	unsigned long armclk;
319 	unsigned int arm_ratio;
320 	unsigned int arm2_ratio;
321 
322 	div = read32(&exynos_clock->div_cpu0);
323 
324 	/* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
325 	arm_ratio = (div >> 0) & 0x7;
326 	arm2_ratio = (div >> 28) & 0x7;
327 
328 	armclk = get_pll_clk(APLL) / (arm_ratio + 1);
329 	armclk /= (arm2_ratio + 1);
330 
331 	return armclk;
332 }
333 
get_arm_clk_ratios(void)334 struct arm_clk_ratios *get_arm_clk_ratios(void)
335 {
336 	struct arm_clk_ratios *arm_ratio;
337 	unsigned long arm_freq = 1700;	/* FIXME: use get_arm_clk() */
338 	int i;
339 
340 	for (i = 0, arm_ratio = arm_clk_ratios; i < ARRAY_SIZE(arm_clk_ratios);
341 		i++, arm_ratio++) {
342 		if (arm_ratio->arm_freq_mhz == arm_freq)
343 			return arm_ratio;
344 	}
345 
346 	return NULL;
347 }
348 
349 /* exynos5: set the mmc clock */
set_mmc_clk(int dev_index,unsigned int div)350 void set_mmc_clk(int dev_index, unsigned int div)
351 {
352 	unsigned int *addr;
353 	unsigned int val;
354 
355 	/*
356 	 * CLK_DIV_FSYS1
357 	 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
358 	 * CLK_DIV_FSYS2
359 	 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
360 	 */
361 	if (dev_index < 2) {
362 		addr = &exynos_clock->div_fsys1;
363 	} else {
364 		addr = &exynos_clock->div_fsys2;
365 		dev_index -= 2;
366 	}
367 
368 	val = read32(addr);
369 	val &= ~(0xff << ((dev_index << 4) + 8));
370 	val |= (div & 0xff) << ((dev_index << 4) + 8);
371 	write32(addr, val);
372 }
373 
clock_ll_set_pre_ratio(enum periph_id periph_id,unsigned int divisor)374 void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned int divisor)
375 {
376 	unsigned int shift;
377 	unsigned int mask = 0xff;
378 	u32 *reg;
379 
380 	/*
381 	 * For now we only handle a very small subset of peripherals here.
382 	 * Others will need to (and do) mangle the clock registers
383 	 * themselves, At some point it is hoped that this function can work
384 	 * from a table or calculated register offset / mask. For now this
385 	 * is at least better than spreading clock control code around
386 	 * U-Boot.
387 	 */
388 	switch (periph_id) {
389 	case PERIPH_ID_SPI0:
390 		reg = &exynos_clock->div_peric1;
391 		shift = 8;
392 		break;
393 	case PERIPH_ID_SPI1:
394 		reg = &exynos_clock->div_peric1;
395 		shift = 24;
396 		break;
397 	case PERIPH_ID_SPI2:
398 		reg = &exynos_clock->div_peric2;
399 		shift = 8;
400 		break;
401 	case PERIPH_ID_SPI3:
402 		reg = &exynos_clock->sclk_div_isp;
403 		shift = 4;
404 		break;
405 	case PERIPH_ID_SPI4:
406 		reg = &exynos_clock->sclk_div_isp;
407 		shift = 16;
408 		break;
409 	default:
410 		printk(BIOS_DEBUG, "%s: Unsupported peripheral ID %d\n", __func__,
411 		      periph_id);
412 		return;
413 	}
414 	clrsetbits32(reg, mask << shift, (divisor & mask) << shift);
415 }
416 
clock_ll_set_ratio(enum periph_id periph_id,unsigned int divisor)417 void clock_ll_set_ratio(enum periph_id periph_id, unsigned int divisor)
418 {
419 	unsigned int shift;
420 	unsigned int mask = 0xff;
421 	u32 *reg;
422 
423 	switch (periph_id) {
424 	case PERIPH_ID_SPI0:
425 		reg = &exynos_clock->div_peric1;
426 		shift = 0;
427 		break;
428 	case PERIPH_ID_SPI1:
429 		reg = &exynos_clock->div_peric1;
430 		shift = 16;
431 		break;
432 	case PERIPH_ID_SPI2:
433 		reg = &exynos_clock->div_peric2;
434 		shift = 0;
435 		break;
436 	case PERIPH_ID_SPI3:
437 		reg = &exynos_clock->sclk_div_isp;
438 		shift = 0;
439 		break;
440 	case PERIPH_ID_SPI4:
441 		reg = &exynos_clock->sclk_div_isp;
442 		shift = 12;
443 		break;
444 	default:
445 		printk(BIOS_DEBUG, "%s: Unsupported peripheral ID %d\n", __func__,
446 		      periph_id);
447 		return;
448 	}
449 	clrsetbits32(reg, mask << shift, (divisor & mask) << shift);
450 }
451 
452 /**
453  * Linearly searches for the most accurate main and fine stage clock scalars
454  * (divisors) for a specified target frequency and scalar bit sizes by checking
455  * all multiples of main_scalar_bits values. Will always return scalars up to or
456  * slower than target.
457  *
458  * @param main_scalar_bits	Number of main scalar bits, must be > 0 and < 32
459  * @param fine_scalar_bits	Number of fine scalar bits, must be > 0 and < 32
460  * @param input_rate		Clock frequency to be scaled in Hz
461  * @param target_rate		Desired clock frequency in Hz
462  * @param best_fine_scalar	Pointer to store the fine stage divisor
463  *
464  * @return best_main_scalar	Main scalar for desired frequency or -1 if none
465  * found
466  */
clock_calc_best_scalar(unsigned int main_scaler_bits,unsigned int fine_scalar_bits,unsigned int input_rate,unsigned int target_rate,unsigned int * best_fine_scalar)467 static int clock_calc_best_scalar(unsigned int main_scaler_bits,
468 	unsigned int fine_scalar_bits, unsigned int input_rate,
469 	unsigned int target_rate, unsigned int *best_fine_scalar)
470 {
471 	int i;
472 	int best_main_scalar = -1;
473 	unsigned int best_error = target_rate;
474 	const unsigned int cap = (1 << fine_scalar_bits) - 1;
475 	const unsigned int loops = 1 << main_scaler_bits;
476 
477 	printk(BIOS_DEBUG, "Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
478 			target_rate, cap);
479 
480 	ASSERT(best_fine_scalar != NULL);
481 	ASSERT(main_scaler_bits <= fine_scalar_bits);
482 
483 	*best_fine_scalar = 1;
484 
485 	if (input_rate == 0 || target_rate == 0)
486 		return -1;
487 
488 	if (target_rate >= input_rate)
489 		return 1;
490 
491 	for (i = 1; i <= loops; i++) {
492 		const unsigned int effective_div = MAX(MIN(input_rate / i /
493 							target_rate, cap), 1);
494 		const unsigned int effective_rate = input_rate / i /
495 							effective_div;
496 		const int error = target_rate - effective_rate;
497 
498 		printk(BIOS_DEBUG, "%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
499 				effective_rate, error);
500 
501 		if (error >= 0 && error <= best_error) {
502 			best_error = error;
503 			best_main_scalar = i;
504 			*best_fine_scalar = effective_div;
505 		}
506 	}
507 
508 	return best_main_scalar;
509 }
510 
clock_set_rate(enum periph_id periph_id,unsigned int rate)511 int clock_set_rate(enum periph_id periph_id, unsigned int rate)
512 {
513 	int main_scalar;
514 	unsigned int fine;
515 
516 	switch (periph_id) {
517 	case PERIPH_ID_SPI0:
518 	case PERIPH_ID_SPI1:
519 	case PERIPH_ID_SPI2:
520 	case PERIPH_ID_SPI3:
521 	case PERIPH_ID_SPI4:
522 		main_scalar = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
523 		if (main_scalar < 0) {
524 			printk(BIOS_DEBUG, "%s: Cannot set clock rate for periph %d",
525 					__func__, periph_id);
526 			return -1;
527 		}
528 		clock_ll_set_ratio(periph_id, main_scalar - 1);
529 		clock_ll_set_pre_ratio(periph_id, fine - 1);
530 		break;
531 	default:
532 		printk(BIOS_DEBUG, "%s: Unsupported peripheral ID %d\n", __func__,
533 		      periph_id);
534 		return -1;
535 	}
536 
537 	return 0;
538 }
539 
clock_set_mshci(enum periph_id peripheral)540 int clock_set_mshci(enum periph_id peripheral)
541 {
542 	u32 *addr;
543 	unsigned int clock;
544 	unsigned int tmp;
545 	unsigned int i;
546 
547 	/* get mpll clock */
548 	clock = get_pll_clk(MPLL) / 1000000;
549 
550 	/*
551 	 * CLK_DIV_FSYS1
552 	 * MMC0_PRE_RATIO [15:8], MMC0_RATIO [3:0]
553 	 * CLK_DIV_FSYS2
554 	 * MMC2_PRE_RATIO [15:8], MMC2_RATIO [3:0]
555 	 */
556 	switch (peripheral) {
557 	case PERIPH_ID_SDMMC0:
558 		addr = &exynos_clock->div_fsys1;
559 		break;
560 	case PERIPH_ID_SDMMC2:
561 		addr = &exynos_clock->div_fsys2;
562 		break;
563 	default:
564 		printk(BIOS_DEBUG, "invalid peripheral\n");
565 		return -1;
566 	}
567 	tmp = read32(addr) & ~0xff0f;
568 	for (i = 0; i <= 0xf; i++) {
569 		if ((clock / (i + 1)) <= 400) {
570 			write32(addr, tmp | i << 0);
571 			break;
572 		}
573 	}
574 	return 0;
575 }
576 
clock_epll_set_rate(unsigned long rate)577 int clock_epll_set_rate(unsigned long rate)
578 {
579 	unsigned int epll_con, epll_con_k;
580 	unsigned int i;
581 	unsigned int lockcnt;
582 	struct stopwatch sw;
583 
584 	epll_con = read32(&exynos_clock->epll_con0);
585 	epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
586 			EPLL_CON0_LOCK_DET_EN_SHIFT) |
587 		EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
588 		EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
589 		EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
590 
591 	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
592 		if (epll_div[i].freq_out == rate)
593 			break;
594 	}
595 
596 	if (i == ARRAY_SIZE(epll_div))
597 		return -1;
598 
599 	epll_con_k = epll_div[i].k_dsm << 0;
600 	epll_con |= epll_div[i].en_lock_det << EPLL_CON0_LOCK_DET_EN_SHIFT;
601 	epll_con |= epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
602 	epll_con |= epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
603 	epll_con |= epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
604 
605 	/*
606 	 * Required period (in cycles) to generate a stable clock output.
607 	 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
608 	 * frequency input (as per spec)
609 	 */
610 	lockcnt = 3000 * epll_div[i].p_div;
611 
612 	write32(&exynos_clock->epll_lock, lockcnt);
613 	write32(&exynos_clock->epll_con0, epll_con);
614 	write32(&exynos_clock->epll_con1, epll_con_k);
615 
616 	stopwatch_init_msecs_expire(&sw, TIMEOUT_EPLL_LOCK);
617 
618 	while (!(read32(&exynos_clock->epll_con0) &
619 			(0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
620 		if (stopwatch_expired(&sw)) {
621 			printk(BIOS_DEBUG,
622 				"%s: Timeout waiting for EPLL lock\n",
623 				__func__);
624 			return -1;
625 		}
626 	}
627 
628 	return 0;
629 }
630 
clock_select_i2s_clk_source(void)631 void clock_select_i2s_clk_source(void)
632 {
633 	clrsetbits32(&exynos_clock->src_peric1, AUDIO1_SEL_MASK,
634 			(CLK_SRC_SCLK_EPLL));
635 }
636 
clock_set_i2s_clk_prescaler(unsigned int src_frq,unsigned int dst_frq)637 int clock_set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq)
638 {
639 	unsigned int div;
640 
641 	if ((dst_frq == 0) || (src_frq == 0)) {
642 		printk(BIOS_DEBUG, "%s: Invalid frequency input for prescaler\n", __func__);
643 		printk(BIOS_DEBUG, "src frq = %d des frq = %d ", src_frq, dst_frq);
644 		return -1;
645 	}
646 
647 	div = (src_frq / dst_frq);
648 	if (div > AUDIO_1_RATIO_MASK) {
649 		printk(BIOS_DEBUG, "%s: Frequency ratio is out of range\n", __func__);
650 		printk(BIOS_DEBUG, "src frq = %d des frq = %d ", src_frq, dst_frq);
651 		return -1;
652 	}
653 	clrsetbits32(&exynos_clock->div_peric4, AUDIO_1_RATIO_MASK,
654 				(div & AUDIO_1_RATIO_MASK));
655 	return 0;
656 }
657