1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2010 Samsung Electronics
4  * Minkyu Kang <mk7.kang@samsung.com>
5  */
6 
7 #include <common.h>
8 #include <log.h>
9 #include <asm/io.h>
10 #include <asm/arch/clock.h>
11 #include <asm/arch/clk.h>
12 #include <asm/arch/periph.h>
13 
14 #define PLL_DIV_1024	1024
15 #define PLL_DIV_65535	65535
16 #define PLL_DIV_65536	65536
17 /* *
18  * This structure is to store the src bit, div bit and prediv bit
19  * positions of the peripheral clocks of the src and div registers
20  */
21 struct clk_bit_info {
22 	enum periph_id id;
23 	int32_t src_mask;
24 	int32_t div_mask;
25 	int32_t prediv_mask;
26 	int8_t src_bit;
27 	int8_t div_bit;
28 	int8_t prediv_bit;
29 };
30 
31 static struct clk_bit_info exynos5_bit_info[] = {
32 	/* periph id		s_mask	d_mask	p_mask	s_bit	d_bit	p_bit */
33 	{PERIPH_ID_UART0,	0xf,	0xf,	-1,	0,	0,	-1},
34 	{PERIPH_ID_UART1,	0xf,	0xf,	-1,	4,	4,	-1},
35 	{PERIPH_ID_UART2,	0xf,	0xf,	-1,	8,	8,	-1},
36 	{PERIPH_ID_UART3,	0xf,	0xf,	-1,	12,	12,	-1},
37 	{PERIPH_ID_I2C0,	-1,	0x7,	0x7,	-1,	24,	0},
38 	{PERIPH_ID_I2C1,	-1,	0x7,	0x7,	-1,	24,	0},
39 	{PERIPH_ID_I2C2,	-1,	0x7,	0x7,	-1,	24,	0},
40 	{PERIPH_ID_I2C3,	-1,	0x7,	0x7,	-1,	24,	0},
41 	{PERIPH_ID_I2C4,	-1,	0x7,	0x7,	-1,	24,	0},
42 	{PERIPH_ID_I2C5,	-1,	0x7,	0x7,	-1,	24,	0},
43 	{PERIPH_ID_I2C6,	-1,	0x7,	0x7,	-1,	24,	0},
44 	{PERIPH_ID_I2C7,	-1,	0x7,	0x7,	-1,	24,	0},
45 	{PERIPH_ID_SPI0,	0xf,	0xf,	0xff,	16,	0,	8},
46 	{PERIPH_ID_SPI1,	0xf,	0xf,	0xff,	20,	16,	24},
47 	{PERIPH_ID_SPI2,	0xf,	0xf,	0xff,	24,	0,	8},
48 	{PERIPH_ID_SDMMC0,	0xf,	0xf,	0xff,	0,	0,	8},
49 	{PERIPH_ID_SDMMC1,	0xf,	0xf,	0xff,	4,	16,	24},
50 	{PERIPH_ID_SDMMC2,	0xf,	0xf,	0xff,	8,	0,	8},
51 	{PERIPH_ID_SDMMC3,	0xf,	0xf,	0xff,	12,	16,	24},
52 	{PERIPH_ID_I2S0,	0xf,	0xf,	0xff,	0,	0,	4},
53 	{PERIPH_ID_I2S1,	0xf,	0xf,	0xff,	4,	12,	16},
54 	{PERIPH_ID_SPI3,	0xf,	0xf,	0xff,	0,	0,	4},
55 	{PERIPH_ID_SPI4,	0xf,	0xf,	0xff,	4,	12,	16},
56 	{PERIPH_ID_SDMMC4,	0xf,	0xf,	0xff,	16,	0,	8},
57 	{PERIPH_ID_PWM0,	0xf,	0xf,	-1,	24,	0,	-1},
58 	{PERIPH_ID_PWM1,	0xf,	0xf,	-1,	24,	0,	-1},
59 	{PERIPH_ID_PWM2,	0xf,	0xf,	-1,	24,	0,	-1},
60 	{PERIPH_ID_PWM3,	0xf,	0xf,	-1,	24,	0,	-1},
61 	{PERIPH_ID_PWM4,	0xf,	0xf,	-1,	24,	0,	-1},
62 
63 	{PERIPH_ID_NONE,	-1,	-1,	-1,	-1,	-1,	-1},
64 };
65 
66 static struct clk_bit_info exynos542x_bit_info[] = {
67 	/* periph id		s_mask	d_mask	p_mask	s_bit	d_bit	p_bit */
68 	{PERIPH_ID_UART0,	0xf,	0xf,	-1,	4,	8,	-1},
69 	{PERIPH_ID_UART1,	0xf,	0xf,	-1,	8,	12,	-1},
70 	{PERIPH_ID_UART2,	0xf,	0xf,	-1,	12,	16,	-1},
71 	{PERIPH_ID_UART3,	0xf,	0xf,	-1,	16,	20,	-1},
72 	{PERIPH_ID_I2C0,	-1,	0x3f,	-1,	-1,	8,	-1},
73 	{PERIPH_ID_I2C1,	-1,	0x3f,	-1,	-1,	8,	-1},
74 	{PERIPH_ID_I2C2,	-1,	0x3f,	-1,	-1,	8,	-1},
75 	{PERIPH_ID_I2C3,	-1,	0x3f,	-1,	-1,	8,	-1},
76 	{PERIPH_ID_I2C4,	-1,	0x3f,	-1,	-1,	8,	-1},
77 	{PERIPH_ID_I2C5,	-1,	0x3f,	-1,	-1,	8,	-1},
78 	{PERIPH_ID_I2C6,	-1,	0x3f,	-1,	-1,	8,	-1},
79 	{PERIPH_ID_I2C7,	-1,	0x3f,	-1,	-1,	8,	-1},
80 	{PERIPH_ID_SPI0,	0xf,	0xf,	0xff,	20,	20,	8},
81 	{PERIPH_ID_SPI1,	0xf,	0xf,	0xff,	24,	24,	16},
82 	{PERIPH_ID_SPI2,	0xf,	0xf,	0xff,	28,	28,	24},
83 	{PERIPH_ID_SDMMC0,	0x7,	0x3ff,	-1,	8,	0,	-1},
84 	{PERIPH_ID_SDMMC1,	0x7,	0x3ff,	-1,	12,	10,	-1},
85 	{PERIPH_ID_SDMMC2,	0x7,	0x3ff,	-1,	16,	20,	-1},
86 	{PERIPH_ID_I2C8,	-1,	0x3f,	-1,	-1,	8,	-1},
87 	{PERIPH_ID_I2C9,	-1,	0x3f,	-1,	-1,	8,	-1},
88 	{PERIPH_ID_I2S0,	0xf,	0xf,	0xff,	0,	0,	4},
89 	{PERIPH_ID_I2S1,	0xf,	0xf,	0xff,	4,	12,	16},
90 	{PERIPH_ID_SPI3,	0xf,	0xf,	0xff,	12,	16,	0},
91 	{PERIPH_ID_SPI4,	0xf,	0xf,	0xff,	16,	20,	8},
92 	{PERIPH_ID_PWM0,	0xf,	0xf,	-1,	24,	28,	-1},
93 	{PERIPH_ID_PWM1,	0xf,	0xf,	-1,	24,	28,	-1},
94 	{PERIPH_ID_PWM2,	0xf,	0xf,	-1,	24,	28,	-1},
95 	{PERIPH_ID_PWM3,	0xf,	0xf,	-1,	24,	28,	-1},
96 	{PERIPH_ID_PWM4,	0xf,	0xf,	-1,	24,	28,	-1},
97 	{PERIPH_ID_I2C10,	-1,	0x3f,	-1,	-1,	8,	-1},
98 
99 	{PERIPH_ID_NONE,	-1,	-1,	-1,	-1,	-1,	-1},
100 };
101 
102 /* Epll Clock division values to achive different frequency output */
103 static struct set_epll_con_val exynos5_epll_div[] = {
104 	{ 192000000, 0, 48, 3, 1, 0 },
105 	{ 180000000, 0, 45, 3, 1, 0 },
106 	{  73728000, 1, 73, 3, 3, 47710 },
107 	{  67737600, 1, 90, 4, 3, 20762 },
108 	{  49152000, 0, 49, 3, 3, 9961 },
109 	{  45158400, 0, 45, 3, 3, 10381 },
110 	{ 180633600, 0, 45, 3, 1, 10381 }
111 };
112 
113 /* exynos: return pll clock frequency */
exynos_get_pll_clk(int pllreg,unsigned int r,unsigned int k)114 static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
115 {
116 	unsigned long m, p, s = 0, mask, fout;
117 	unsigned int div;
118 	unsigned int freq;
119 	/*
120 	 * APLL_CON: MIDV [25:16]
121 	 * MPLL_CON: MIDV [25:16]
122 	 * EPLL_CON: MIDV [24:16]
123 	 * VPLL_CON: MIDV [24:16]
124 	 * BPLL_CON: MIDV [25:16]: Exynos5
125 	 */
126 	if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL ||
127 	    pllreg == SPLL)
128 		mask = 0x3ff;
129 	else
130 		mask = 0x1ff;
131 
132 	m = (r >> 16) & mask;
133 
134 	/* PDIV [13:8] */
135 	p = (r >> 8) & 0x3f;
136 	/* SDIV [2:0] */
137 	s = r & 0x7;
138 
139 	freq = CONFIG_SYS_CLK_FREQ;
140 
141 	if (pllreg == EPLL || pllreg == RPLL) {
142 		k = k & 0xffff;
143 		/* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
144 		fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s)));
145 	} else if (pllreg == VPLL) {
146 		k = k & 0xfff;
147 
148 		/*
149 		 * Exynos4210
150 		 * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV)
151 		 *
152 		 * Exynos4412
153 		 * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV)
154 		 *
155 		 * Exynos5250
156 		 * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV)
157 		 */
158 		if (proid_is_exynos4210())
159 			div = PLL_DIV_1024;
160 		else if (proid_is_exynos4412())
161 			div = PLL_DIV_65535;
162 		else if (proid_is_exynos5250() || proid_is_exynos5420() ||
163 			 proid_is_exynos5422())
164 			div = PLL_DIV_65536;
165 		else
166 			return 0;
167 
168 		fout = (m + k / div) * (freq / (p * (1 << s)));
169 	} else {
170 		/*
171 		 * Exynos4412 / Exynos5250
172 		 * FOUT = MDIV * FIN / (PDIV * 2^SDIV)
173 		 *
174 		 * Exynos4210
175 		 * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1))
176 		 */
177 		if (proid_is_exynos4210())
178 			fout = m * (freq / (p * (1 << (s - 1))));
179 		else
180 			fout = m * (freq / (p * (1 << s)));
181 	}
182 	return fout;
183 }
184 
185 /* exynos4: return pll clock frequency */
exynos4_get_pll_clk(int pllreg)186 static unsigned long exynos4_get_pll_clk(int pllreg)
187 {
188 	struct exynos4_clock *clk =
189 		(struct exynos4_clock *)samsung_get_base_clock();
190 	unsigned long r, k = 0;
191 
192 	switch (pllreg) {
193 	case APLL:
194 		r = readl(&clk->apll_con0);
195 		break;
196 	case MPLL:
197 		r = readl(&clk->mpll_con0);
198 		break;
199 	case EPLL:
200 		r = readl(&clk->epll_con0);
201 		k = readl(&clk->epll_con1);
202 		break;
203 	case VPLL:
204 		r = readl(&clk->vpll_con0);
205 		k = readl(&clk->vpll_con1);
206 		break;
207 	default:
208 		printf("Unsupported PLL (%d)\n", pllreg);
209 		return 0;
210 	}
211 
212 	return exynos_get_pll_clk(pllreg, r, k);
213 }
214 
215 /* exynos4x12: return pll clock frequency */
exynos4x12_get_pll_clk(int pllreg)216 static unsigned long exynos4x12_get_pll_clk(int pllreg)
217 {
218 	struct exynos4x12_clock *clk =
219 		(struct exynos4x12_clock *)samsung_get_base_clock();
220 	unsigned long r, k = 0;
221 
222 	switch (pllreg) {
223 	case APLL:
224 		r = readl(&clk->apll_con0);
225 		break;
226 	case MPLL:
227 		r = readl(&clk->mpll_con0);
228 		break;
229 	case EPLL:
230 		r = readl(&clk->epll_con0);
231 		k = readl(&clk->epll_con1);
232 		break;
233 	case VPLL:
234 		r = readl(&clk->vpll_con0);
235 		k = readl(&clk->vpll_con1);
236 		break;
237 	default:
238 		printf("Unsupported PLL (%d)\n", pllreg);
239 		return 0;
240 	}
241 
242 	return exynos_get_pll_clk(pllreg, r, k);
243 }
244 
245 /* exynos5: return pll clock frequency */
exynos5_get_pll_clk(int pllreg)246 static unsigned long exynos5_get_pll_clk(int pllreg)
247 {
248 	struct exynos5_clock *clk =
249 		(struct exynos5_clock *)samsung_get_base_clock();
250 	unsigned long r, k = 0, fout;
251 	unsigned int pll_div2_sel, fout_sel;
252 
253 	switch (pllreg) {
254 	case APLL:
255 		r = readl(&clk->apll_con0);
256 		break;
257 	case MPLL:
258 		r = readl(&clk->mpll_con0);
259 		break;
260 	case EPLL:
261 		r = readl(&clk->epll_con0);
262 		k = readl(&clk->epll_con1);
263 		break;
264 	case VPLL:
265 		r = readl(&clk->vpll_con0);
266 		k = readl(&clk->vpll_con1);
267 		break;
268 	case BPLL:
269 		r = readl(&clk->bpll_con0);
270 		break;
271 	default:
272 		printf("Unsupported PLL (%d)\n", pllreg);
273 		return 0;
274 	}
275 
276 	fout = exynos_get_pll_clk(pllreg, r, k);
277 
278 	/* According to the user manual, in EVT1 MPLL and BPLL always gives
279 	 * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
280 	if (pllreg == MPLL || pllreg == BPLL) {
281 		pll_div2_sel = readl(&clk->pll_div2_sel);
282 
283 		switch (pllreg) {
284 		case MPLL:
285 			fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
286 					& MPLL_FOUT_SEL_MASK;
287 			break;
288 		case BPLL:
289 			fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
290 					& BPLL_FOUT_SEL_MASK;
291 			break;
292 		default:
293 			fout_sel = -1;
294 			break;
295 		}
296 
297 		if (fout_sel == 0)
298 			fout /= 2;
299 	}
300 
301 	return fout;
302 }
303 
304 /* exynos542x: return pll clock frequency */
exynos542x_get_pll_clk(int pllreg)305 static unsigned long exynos542x_get_pll_clk(int pllreg)
306 {
307 	struct exynos5420_clock *clk =
308 		(struct exynos5420_clock *)samsung_get_base_clock();
309 	unsigned long r, k = 0;
310 
311 	switch (pllreg) {
312 	case APLL:
313 		r = readl(&clk->apll_con0);
314 		break;
315 	case MPLL:
316 		r = readl(&clk->mpll_con0);
317 		break;
318 	case EPLL:
319 		r = readl(&clk->epll_con0);
320 		k = readl(&clk->epll_con1);
321 		break;
322 	case VPLL:
323 		r = readl(&clk->vpll_con0);
324 		k = readl(&clk->vpll_con1);
325 		break;
326 	case BPLL:
327 		r = readl(&clk->bpll_con0);
328 		break;
329 	case RPLL:
330 		r = readl(&clk->rpll_con0);
331 		k = readl(&clk->rpll_con1);
332 		break;
333 	case SPLL:
334 		r = readl(&clk->spll_con0);
335 		break;
336 	default:
337 		printf("Unsupported PLL (%d)\n", pllreg);
338 		return 0;
339 	}
340 
341 	return exynos_get_pll_clk(pllreg, r, k);
342 }
343 
get_clk_bit_info(int peripheral)344 static struct clk_bit_info *get_clk_bit_info(int peripheral)
345 {
346 	int i;
347 	struct clk_bit_info *info;
348 
349 	if (proid_is_exynos542x())
350 		info = exynos542x_bit_info;
351 	else
352 		info = exynos5_bit_info;
353 
354 	for (i = 0; info[i].id != PERIPH_ID_NONE; i++) {
355 		if (info[i].id == peripheral)
356 			break;
357 	}
358 
359 	if (info[i].id == PERIPH_ID_NONE)
360 		debug("ERROR: Peripheral ID %d not found\n", peripheral);
361 
362 	return &info[i];
363 }
364 
exynos5_get_periph_rate(int peripheral)365 static unsigned long exynos5_get_periph_rate(int peripheral)
366 {
367 	struct clk_bit_info *bit_info = get_clk_bit_info(peripheral);
368 	unsigned long sclk = 0;
369 	unsigned int src = 0, div = 0, sub_div = 0;
370 	struct exynos5_clock *clk =
371 			(struct exynos5_clock *)samsung_get_base_clock();
372 
373 	switch (peripheral) {
374 	case PERIPH_ID_UART0:
375 	case PERIPH_ID_UART1:
376 	case PERIPH_ID_UART2:
377 	case PERIPH_ID_UART3:
378 		src = readl(&clk->src_peric0);
379 		div = readl(&clk->div_peric0);
380 		break;
381 	case PERIPH_ID_PWM0:
382 	case PERIPH_ID_PWM1:
383 	case PERIPH_ID_PWM2:
384 	case PERIPH_ID_PWM3:
385 	case PERIPH_ID_PWM4:
386 		src = readl(&clk->src_peric0);
387 		div = readl(&clk->div_peric3);
388 		break;
389 	case PERIPH_ID_I2S0:
390 		src = readl(&clk->src_mau);
391 		div = sub_div = readl(&clk->div_mau);
392 	case PERIPH_ID_SPI0:
393 	case PERIPH_ID_SPI1:
394 		src = readl(&clk->src_peric1);
395 		div = sub_div = readl(&clk->div_peric1);
396 		break;
397 	case PERIPH_ID_SPI2:
398 		src = readl(&clk->src_peric1);
399 		div = sub_div = readl(&clk->div_peric2);
400 		break;
401 	case PERIPH_ID_SPI3:
402 	case PERIPH_ID_SPI4:
403 		src = readl(&clk->sclk_src_isp);
404 		div = sub_div = readl(&clk->sclk_div_isp);
405 		break;
406 	case PERIPH_ID_SDMMC0:
407 	case PERIPH_ID_SDMMC1:
408 		src = readl(&clk->src_fsys);
409 		div = sub_div = readl(&clk->div_fsys1);
410 		break;
411 	case PERIPH_ID_SDMMC2:
412 	case PERIPH_ID_SDMMC3:
413 		src = readl(&clk->src_fsys);
414 		div = sub_div = readl(&clk->div_fsys2);
415 		break;
416 	case PERIPH_ID_I2C0:
417 	case PERIPH_ID_I2C1:
418 	case PERIPH_ID_I2C2:
419 	case PERIPH_ID_I2C3:
420 	case PERIPH_ID_I2C4:
421 	case PERIPH_ID_I2C5:
422 	case PERIPH_ID_I2C6:
423 	case PERIPH_ID_I2C7:
424 		src = EXYNOS_SRC_MPLL;
425 		div = readl(&clk->div_top1);
426 		sub_div = readl(&clk->div_top0);
427 		break;
428 	default:
429 		debug("%s: invalid peripheral %d", __func__, peripheral);
430 		return -1;
431 	};
432 
433 	if (bit_info->src_bit >= 0)
434 		src = (src >> bit_info->src_bit) & bit_info->src_mask;
435 
436 	switch (src) {
437 	case EXYNOS_SRC_MPLL:
438 		sclk = exynos5_get_pll_clk(MPLL);
439 		break;
440 	case EXYNOS_SRC_EPLL:
441 		sclk = exynos5_get_pll_clk(EPLL);
442 		break;
443 	case EXYNOS_SRC_VPLL:
444 		sclk = exynos5_get_pll_clk(VPLL);
445 		break;
446 	default:
447 		debug("%s: EXYNOS_SRC %d not supported\n", __func__, src);
448 		return 0;
449 	}
450 
451 	/* Clock divider ratio for this peripheral */
452 	if (bit_info->div_bit >= 0)
453 		div = (div >> bit_info->div_bit) & bit_info->div_mask;
454 
455 	/* Clock pre-divider ratio for this peripheral */
456 	if (bit_info->prediv_bit >= 0)
457 		sub_div = (sub_div >> bit_info->prediv_bit)
458 			  & bit_info->prediv_mask;
459 
460 	/* Calculate and return required clock rate */
461 	return (sclk / (div + 1)) / (sub_div + 1);
462 }
463 
exynos542x_get_periph_rate(int peripheral)464 static unsigned long exynos542x_get_periph_rate(int peripheral)
465 {
466 	struct clk_bit_info *bit_info = get_clk_bit_info(peripheral);
467 	unsigned long sclk = 0;
468 	unsigned int src = 0, div = 0, sub_div = 0;
469 	struct exynos5420_clock *clk =
470 			(struct exynos5420_clock *)samsung_get_base_clock();
471 
472 	switch (peripheral) {
473 	case PERIPH_ID_UART0:
474 	case PERIPH_ID_UART1:
475 	case PERIPH_ID_UART2:
476 	case PERIPH_ID_UART3:
477 	case PERIPH_ID_PWM0:
478 	case PERIPH_ID_PWM1:
479 	case PERIPH_ID_PWM2:
480 	case PERIPH_ID_PWM3:
481 	case PERIPH_ID_PWM4:
482 		src = readl(&clk->src_peric0);
483 		div = readl(&clk->div_peric0);
484 		break;
485 	case PERIPH_ID_SPI0:
486 	case PERIPH_ID_SPI1:
487 	case PERIPH_ID_SPI2:
488 		src = readl(&clk->src_peric1);
489 		div = readl(&clk->div_peric1);
490 		sub_div = readl(&clk->div_peric4);
491 		break;
492 	case PERIPH_ID_SPI3:
493 	case PERIPH_ID_SPI4:
494 		src = readl(&clk->src_isp);
495 		div = readl(&clk->div_isp1);
496 		sub_div = readl(&clk->div_isp1);
497 		break;
498 	case PERIPH_ID_SDMMC0:
499 	case PERIPH_ID_SDMMC1:
500 	case PERIPH_ID_SDMMC2:
501 	case PERIPH_ID_SDMMC3:
502 		src = readl(&clk->src_fsys);
503 		div = readl(&clk->div_fsys1);
504 		break;
505 	case PERIPH_ID_I2C0:
506 	case PERIPH_ID_I2C1:
507 	case PERIPH_ID_I2C2:
508 	case PERIPH_ID_I2C3:
509 	case PERIPH_ID_I2C4:
510 	case PERIPH_ID_I2C5:
511 	case PERIPH_ID_I2C6:
512 	case PERIPH_ID_I2C7:
513 	case PERIPH_ID_I2C8:
514 	case PERIPH_ID_I2C9:
515 	case PERIPH_ID_I2C10:
516 		src = EXYNOS542X_SRC_MPLL;
517 		div = readl(&clk->div_top1);
518 		break;
519 	default:
520 		debug("%s: invalid peripheral %d", __func__, peripheral);
521 		return -1;
522 	};
523 
524 	if (bit_info->src_bit >= 0)
525 		src = (src >> bit_info->src_bit) & bit_info->src_mask;
526 
527 	switch (src) {
528 	case EXYNOS542X_SRC_MPLL:
529 		sclk = exynos542x_get_pll_clk(MPLL);
530 		break;
531 	case EXYNOS542X_SRC_SPLL:
532 		sclk = exynos542x_get_pll_clk(SPLL);
533 		break;
534 	case EXYNOS542X_SRC_EPLL:
535 		sclk = exynos542x_get_pll_clk(EPLL);
536 		break;
537 	case EXYNOS542X_SRC_RPLL:
538 		sclk = exynos542x_get_pll_clk(RPLL);
539 		break;
540 	default:
541 		debug("%s: EXYNOS542X_SRC %d not supported", __func__, src);
542 		return 0;
543 	}
544 
545 	/* Clock divider ratio for this peripheral */
546 	if (bit_info->div_bit >= 0)
547 		div = (div >> bit_info->div_bit) & bit_info->div_mask;
548 
549 	/* Clock pre-divider ratio for this peripheral */
550 	if (bit_info->prediv_bit >= 0)
551 		sub_div = (sub_div >> bit_info->prediv_bit)
552 			  & bit_info->prediv_mask;
553 
554 	/* Calculate and return required clock rate */
555 	return (sclk / (div + 1)) / (sub_div + 1);
556 }
557 
clock_get_periph_rate(int peripheral)558 unsigned long clock_get_periph_rate(int peripheral)
559 {
560 	if (cpu_is_exynos5()) {
561 		if (proid_is_exynos542x())
562 			return exynos542x_get_periph_rate(peripheral);
563 		return exynos5_get_periph_rate(peripheral);
564 	} else {
565 		return 0;
566 	}
567 }
568 
569 /* exynos4: return ARM clock frequency */
exynos4_get_arm_clk(void)570 static unsigned long exynos4_get_arm_clk(void)
571 {
572 	struct exynos4_clock *clk =
573 		(struct exynos4_clock *)samsung_get_base_clock();
574 	unsigned long div;
575 	unsigned long armclk;
576 	unsigned int core_ratio;
577 	unsigned int core2_ratio;
578 
579 	div = readl(&clk->div_cpu0);
580 
581 	/* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
582 	core_ratio = (div >> 0) & 0x7;
583 	core2_ratio = (div >> 28) & 0x7;
584 
585 	armclk = get_pll_clk(APLL) / (core_ratio + 1);
586 	armclk /= (core2_ratio + 1);
587 
588 	return armclk;
589 }
590 
591 /* exynos4x12: return ARM clock frequency */
exynos4x12_get_arm_clk(void)592 static unsigned long exynos4x12_get_arm_clk(void)
593 {
594 	struct exynos4x12_clock *clk =
595 		(struct exynos4x12_clock *)samsung_get_base_clock();
596 	unsigned long div;
597 	unsigned long armclk;
598 	unsigned int core_ratio;
599 	unsigned int core2_ratio;
600 
601 	div = readl(&clk->div_cpu0);
602 
603 	/* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
604 	core_ratio = (div >> 0) & 0x7;
605 	core2_ratio = (div >> 28) & 0x7;
606 
607 	armclk = get_pll_clk(APLL) / (core_ratio + 1);
608 	armclk /= (core2_ratio + 1);
609 
610 	return armclk;
611 }
612 
613 /* exynos5: return ARM clock frequency */
exynos5_get_arm_clk(void)614 static unsigned long exynos5_get_arm_clk(void)
615 {
616 	struct exynos5_clock *clk =
617 		(struct exynos5_clock *)samsung_get_base_clock();
618 	unsigned long div;
619 	unsigned long armclk;
620 	unsigned int arm_ratio;
621 	unsigned int arm2_ratio;
622 
623 	div = readl(&clk->div_cpu0);
624 
625 	/* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
626 	arm_ratio = (div >> 0) & 0x7;
627 	arm2_ratio = (div >> 28) & 0x7;
628 
629 	armclk = get_pll_clk(APLL) / (arm_ratio + 1);
630 	armclk /= (arm2_ratio + 1);
631 
632 	return armclk;
633 }
634 
635 /* exynos4: return pwm clock frequency */
exynos4_get_pwm_clk(void)636 static unsigned long exynos4_get_pwm_clk(void)
637 {
638 	struct exynos4_clock *clk =
639 		(struct exynos4_clock *)samsung_get_base_clock();
640 	unsigned long pclk, sclk;
641 	unsigned int sel;
642 	unsigned int ratio;
643 
644 	if (s5p_get_cpu_rev() == 0) {
645 		/*
646 		 * CLK_SRC_PERIL0
647 		 * PWM_SEL [27:24]
648 		 */
649 		sel = readl(&clk->src_peril0);
650 		sel = (sel >> 24) & 0xf;
651 
652 		if (sel == 0x6)
653 			sclk = get_pll_clk(MPLL);
654 		else if (sel == 0x7)
655 			sclk = get_pll_clk(EPLL);
656 		else if (sel == 0x8)
657 			sclk = get_pll_clk(VPLL);
658 		else
659 			return 0;
660 
661 		/*
662 		 * CLK_DIV_PERIL3
663 		 * PWM_RATIO [3:0]
664 		 */
665 		ratio = readl(&clk->div_peril3);
666 		ratio = ratio & 0xf;
667 	} else if (s5p_get_cpu_rev() == 1) {
668 		sclk = get_pll_clk(MPLL);
669 		ratio = 8;
670 	} else
671 		return 0;
672 
673 	pclk = sclk / (ratio + 1);
674 
675 	return pclk;
676 }
677 
678 /* exynos4x12: return pwm clock frequency */
exynos4x12_get_pwm_clk(void)679 static unsigned long exynos4x12_get_pwm_clk(void)
680 {
681 	unsigned long pclk, sclk;
682 	unsigned int ratio;
683 
684 	sclk = get_pll_clk(MPLL);
685 	ratio = 8;
686 
687 	pclk = sclk / (ratio + 1);
688 
689 	return pclk;
690 }
691 
692 /* exynos4: return uart clock frequency */
exynos4_get_uart_clk(int dev_index)693 static unsigned long exynos4_get_uart_clk(int dev_index)
694 {
695 	struct exynos4_clock *clk =
696 		(struct exynos4_clock *)samsung_get_base_clock();
697 	unsigned long uclk, sclk;
698 	unsigned int sel;
699 	unsigned int ratio;
700 
701 	/*
702 	 * CLK_SRC_PERIL0
703 	 * UART0_SEL [3:0]
704 	 * UART1_SEL [7:4]
705 	 * UART2_SEL [8:11]
706 	 * UART3_SEL [12:15]
707 	 * UART4_SEL [16:19]
708 	 * UART5_SEL [23:20]
709 	 */
710 	sel = readl(&clk->src_peril0);
711 	sel = (sel >> (dev_index << 2)) & 0xf;
712 
713 	if (sel == 0x6)
714 		sclk = get_pll_clk(MPLL);
715 	else if (sel == 0x7)
716 		sclk = get_pll_clk(EPLL);
717 	else if (sel == 0x8)
718 		sclk = get_pll_clk(VPLL);
719 	else
720 		return 0;
721 
722 	/*
723 	 * CLK_DIV_PERIL0
724 	 * UART0_RATIO [3:0]
725 	 * UART1_RATIO [7:4]
726 	 * UART2_RATIO [8:11]
727 	 * UART3_RATIO [12:15]
728 	 * UART4_RATIO [16:19]
729 	 * UART5_RATIO [23:20]
730 	 */
731 	ratio = readl(&clk->div_peril0);
732 	ratio = (ratio >> (dev_index << 2)) & 0xf;
733 
734 	uclk = sclk / (ratio + 1);
735 
736 	return uclk;
737 }
738 
739 /* exynos4x12: return uart clock frequency */
exynos4x12_get_uart_clk(int dev_index)740 static unsigned long exynos4x12_get_uart_clk(int dev_index)
741 {
742 	struct exynos4x12_clock *clk =
743 		(struct exynos4x12_clock *)samsung_get_base_clock();
744 	unsigned long uclk, sclk;
745 	unsigned int sel;
746 	unsigned int ratio;
747 
748 	/*
749 	 * CLK_SRC_PERIL0
750 	 * UART0_SEL [3:0]
751 	 * UART1_SEL [7:4]
752 	 * UART2_SEL [8:11]
753 	 * UART3_SEL [12:15]
754 	 * UART4_SEL [16:19]
755 	 */
756 	sel = readl(&clk->src_peril0);
757 	sel = (sel >> (dev_index << 2)) & 0xf;
758 
759 	if (sel == 0x6)
760 		sclk = get_pll_clk(MPLL);
761 	else if (sel == 0x7)
762 		sclk = get_pll_clk(EPLL);
763 	else if (sel == 0x8)
764 		sclk = get_pll_clk(VPLL);
765 	else
766 		return 0;
767 
768 	/*
769 	 * CLK_DIV_PERIL0
770 	 * UART0_RATIO [3:0]
771 	 * UART1_RATIO [7:4]
772 	 * UART2_RATIO [8:11]
773 	 * UART3_RATIO [12:15]
774 	 * UART4_RATIO [16:19]
775 	 */
776 	ratio = readl(&clk->div_peril0);
777 	ratio = (ratio >> (dev_index << 2)) & 0xf;
778 
779 	uclk = sclk / (ratio + 1);
780 
781 	return uclk;
782 }
783 
exynos4_get_mmc_clk(int dev_index)784 static unsigned long exynos4_get_mmc_clk(int dev_index)
785 {
786 	struct exynos4_clock *clk =
787 		(struct exynos4_clock *)samsung_get_base_clock();
788 	unsigned long uclk, sclk;
789 	unsigned int sel, ratio, pre_ratio;
790 	int shift = 0;
791 
792 	sel = readl(&clk->src_fsys);
793 	sel = (sel >> (dev_index << 2)) & 0xf;
794 
795 	if (sel == 0x6)
796 		sclk = get_pll_clk(MPLL);
797 	else if (sel == 0x7)
798 		sclk = get_pll_clk(EPLL);
799 	else if (sel == 0x8)
800 		sclk = get_pll_clk(VPLL);
801 	else
802 		return 0;
803 
804 	switch (dev_index) {
805 	case 0:
806 	case 1:
807 		ratio = readl(&clk->div_fsys1);
808 		pre_ratio = readl(&clk->div_fsys1);
809 		break;
810 	case 2:
811 	case 3:
812 		ratio = readl(&clk->div_fsys2);
813 		pre_ratio = readl(&clk->div_fsys2);
814 		break;
815 	case 4:
816 		ratio = readl(&clk->div_fsys3);
817 		pre_ratio = readl(&clk->div_fsys3);
818 		break;
819 	default:
820 		return 0;
821 	}
822 
823 	if (dev_index == 1 || dev_index == 3)
824 		shift = 16;
825 
826 	ratio = (ratio >> shift) & 0xf;
827 	pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
828 	uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
829 
830 	return uclk;
831 }
832 
833 /* exynos4: set the mmc clock */
exynos4_set_mmc_clk(int dev_index,unsigned int div)834 static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
835 {
836 	struct exynos4_clock *clk =
837 		(struct exynos4_clock *)samsung_get_base_clock();
838 	unsigned int addr, clear_bit, set_bit;
839 
840 	/*
841 	 * CLK_DIV_FSYS1
842 	 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
843 	 * CLK_DIV_FSYS2
844 	 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
845 	 * CLK_DIV_FSYS3
846 	 * MMC4_RATIO [3:0]
847 	 */
848 	if (dev_index < 2) {
849 		addr = (unsigned int)&clk->div_fsys1;
850 		clear_bit = MASK_PRE_RATIO(dev_index);
851 		set_bit = SET_PRE_RATIO(dev_index, div);
852 	} else if (dev_index == 4) {
853 		addr = (unsigned int)&clk->div_fsys3;
854 		dev_index -= 4;
855 		/* MMC4 is controlled with the MMC4_RATIO value */
856 		clear_bit = MASK_RATIO(dev_index);
857 		set_bit = SET_RATIO(dev_index, div);
858 	} else {
859 		addr = (unsigned int)&clk->div_fsys2;
860 		dev_index -= 2;
861 		clear_bit = MASK_PRE_RATIO(dev_index);
862 		set_bit = SET_PRE_RATIO(dev_index, div);
863 	}
864 
865 	clrsetbits_le32(addr, clear_bit, set_bit);
866 }
867 
868 /* exynos5: set the mmc clock */
exynos5_set_mmc_clk(int dev_index,unsigned int div)869 static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
870 {
871 	struct exynos5_clock *clk =
872 		(struct exynos5_clock *)samsung_get_base_clock();
873 	unsigned int addr;
874 
875 	/*
876 	 * CLK_DIV_FSYS1
877 	 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
878 	 * CLK_DIV_FSYS2
879 	 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
880 	 */
881 	if (dev_index < 2) {
882 		addr = (unsigned int)&clk->div_fsys1;
883 	} else {
884 		addr = (unsigned int)&clk->div_fsys2;
885 		dev_index -= 2;
886 	}
887 
888 	clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8),
889 			(div & 0xff) << ((dev_index << 4) + 8));
890 }
891 
892 /* exynos5: set the mmc clock */
exynos5420_set_mmc_clk(int dev_index,unsigned int div)893 static void exynos5420_set_mmc_clk(int dev_index, unsigned int div)
894 {
895 	struct exynos5420_clock *clk =
896 		(struct exynos5420_clock *)samsung_get_base_clock();
897 	unsigned int addr;
898 	unsigned int shift;
899 
900 	/*
901 	 * CLK_DIV_FSYS1
902 	 * MMC0_RATIO [9:0]
903 	 * MMC1_RATIO [19:10]
904 	 * MMC2_RATIO [29:20]
905 	 */
906 	addr = (unsigned int)&clk->div_fsys1;
907 	shift = dev_index * 10;
908 
909 	clrsetbits_le32(addr, 0x3ff << shift, (div & 0x3ff) << shift);
910 }
911 
912 /* get_lcd_clk: return lcd clock frequency */
exynos4_get_lcd_clk(void)913 static unsigned long exynos4_get_lcd_clk(void)
914 {
915 	struct exynos4_clock *clk =
916 		(struct exynos4_clock *)samsung_get_base_clock();
917 	unsigned long pclk, sclk;
918 	unsigned int sel;
919 	unsigned int ratio;
920 
921 	/*
922 	 * CLK_SRC_LCD0
923 	 * FIMD0_SEL [3:0]
924 	 */
925 	sel = readl(&clk->src_lcd0);
926 	sel = sel & 0xf;
927 
928 	/*
929 	 * 0x6: SCLK_MPLL
930 	 * 0x7: SCLK_EPLL
931 	 * 0x8: SCLK_VPLL
932 	 */
933 	if (sel == 0x6)
934 		sclk = get_pll_clk(MPLL);
935 	else if (sel == 0x7)
936 		sclk = get_pll_clk(EPLL);
937 	else if (sel == 0x8)
938 		sclk = get_pll_clk(VPLL);
939 	else
940 		return 0;
941 
942 	/*
943 	 * CLK_DIV_LCD0
944 	 * FIMD0_RATIO [3:0]
945 	 */
946 	ratio = readl(&clk->div_lcd0);
947 	ratio = ratio & 0xf;
948 
949 	pclk = sclk / (ratio + 1);
950 
951 	return pclk;
952 }
953 
954 /* get_lcd_clk: return lcd clock frequency */
exynos5_get_lcd_clk(void)955 static unsigned long exynos5_get_lcd_clk(void)
956 {
957 	struct exynos5_clock *clk =
958 		(struct exynos5_clock *)samsung_get_base_clock();
959 	unsigned long pclk, sclk;
960 	unsigned int sel;
961 	unsigned int ratio;
962 
963 	/*
964 	 * CLK_SRC_LCD0
965 	 * FIMD0_SEL [3:0]
966 	 */
967 	sel = readl(&clk->src_disp1_0);
968 	sel = sel & 0xf;
969 
970 	/*
971 	 * 0x6: SCLK_MPLL
972 	 * 0x7: SCLK_EPLL
973 	 * 0x8: SCLK_VPLL
974 	 */
975 	if (sel == 0x6)
976 		sclk = get_pll_clk(MPLL);
977 	else if (sel == 0x7)
978 		sclk = get_pll_clk(EPLL);
979 	else if (sel == 0x8)
980 		sclk = get_pll_clk(VPLL);
981 	else
982 		return 0;
983 
984 	/*
985 	 * CLK_DIV_LCD0
986 	 * FIMD0_RATIO [3:0]
987 	 */
988 	ratio = readl(&clk->div_disp1_0);
989 	ratio = ratio & 0xf;
990 
991 	pclk = sclk / (ratio + 1);
992 
993 	return pclk;
994 }
995 
exynos5420_get_lcd_clk(void)996 static unsigned long exynos5420_get_lcd_clk(void)
997 {
998 	struct exynos5420_clock *clk =
999 		(struct exynos5420_clock *)samsung_get_base_clock();
1000 	unsigned long pclk, sclk;
1001 	unsigned int sel;
1002 	unsigned int ratio;
1003 
1004 	/*
1005 	 * CLK_SRC_DISP10
1006 	 * FIMD1_SEL [4]
1007 	 * 0: SCLK_RPLL
1008 	 * 1: SCLK_SPLL
1009 	 */
1010 	sel = readl(&clk->src_disp10);
1011 	sel &= (1 << 4);
1012 
1013 	if (sel)
1014 		sclk = get_pll_clk(SPLL);
1015 	else
1016 		sclk = get_pll_clk(RPLL);
1017 
1018 	/*
1019 	 * CLK_DIV_DISP10
1020 	 * FIMD1_RATIO [3:0]
1021 	 */
1022 	ratio = readl(&clk->div_disp10);
1023 	ratio = ratio & 0xf;
1024 
1025 	pclk = sclk / (ratio + 1);
1026 
1027 	return pclk;
1028 }
1029 
exynos5800_get_lcd_clk(void)1030 static unsigned long exynos5800_get_lcd_clk(void)
1031 {
1032 	struct exynos5420_clock *clk =
1033 		(struct exynos5420_clock *)samsung_get_base_clock();
1034 	unsigned long sclk;
1035 	unsigned int sel;
1036 	unsigned int ratio;
1037 
1038 	/*
1039 	 * CLK_SRC_DISP10
1040 	 * CLKMUX_FIMD1 [6:4]
1041 	 */
1042 	sel = (readl(&clk->src_disp10) >> 4) & 0x7;
1043 
1044 	if (sel) {
1045 		/*
1046 		 * Mapping of CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4] values into
1047 		 * PLLs. The first element is a placeholder to bypass the
1048 		 * default settig.
1049 		 */
1050 		const int reg_map[] = {0, CPLL, DPLL, MPLL, SPLL, IPLL, EPLL,
1051 									RPLL};
1052 		sclk = get_pll_clk(reg_map[sel]);
1053 	} else
1054 		sclk = CONFIG_SYS_CLK_FREQ;
1055 	/*
1056 	 * CLK_DIV_DISP10
1057 	 * FIMD1_RATIO [3:0]
1058 	 */
1059 	ratio = readl(&clk->div_disp10) & 0xf;
1060 
1061 	return sclk / (ratio + 1);
1062 }
1063 
exynos4_set_lcd_clk(void)1064 void exynos4_set_lcd_clk(void)
1065 {
1066 	struct exynos4_clock *clk =
1067 	    (struct exynos4_clock *)samsung_get_base_clock();
1068 
1069 	/*
1070 	 * CLK_GATE_BLOCK
1071 	 * CLK_CAM	[0]
1072 	 * CLK_TV	[1]
1073 	 * CLK_MFC	[2]
1074 	 * CLK_G3D	[3]
1075 	 * CLK_LCD0	[4]
1076 	 * CLK_LCD1	[5]
1077 	 * CLK_GPS	[7]
1078 	 */
1079 	setbits_le32(&clk->gate_block, 1 << 4);
1080 
1081 	/*
1082 	 * CLK_SRC_LCD0
1083 	 * FIMD0_SEL		[3:0]
1084 	 * MDNIE0_SEL		[7:4]
1085 	 * MDNIE_PWM0_SEL	[8:11]
1086 	 * MIPI0_SEL		[12:15]
1087 	 * set lcd0 src clock 0x6: SCLK_MPLL
1088 	 */
1089 	clrsetbits_le32(&clk->src_lcd0, 0xf, 0x6);
1090 
1091 	/*
1092 	 * CLK_GATE_IP_LCD0
1093 	 * CLK_FIMD0		[0]
1094 	 * CLK_MIE0		[1]
1095 	 * CLK_MDNIE0		[2]
1096 	 * CLK_DSIM0		[3]
1097 	 * CLK_SMMUFIMD0	[4]
1098 	 * CLK_PPMULCD0		[5]
1099 	 * Gating all clocks for FIMD0
1100 	 */
1101 	setbits_le32(&clk->gate_ip_lcd0, 1 << 0);
1102 
1103 	/*
1104 	 * CLK_DIV_LCD0
1105 	 * FIMD0_RATIO		[3:0]
1106 	 * MDNIE0_RATIO		[7:4]
1107 	 * MDNIE_PWM0_RATIO	[11:8]
1108 	 * MDNIE_PWM_PRE_RATIO	[15:12]
1109 	 * MIPI0_RATIO		[19:16]
1110 	 * MIPI0_PRE_RATIO	[23:20]
1111 	 * set fimd ratio
1112 	 */
1113 	clrsetbits_le32(&clk->div_lcd0, 0xf, 0x1);
1114 }
1115 
exynos5_set_lcd_clk(void)1116 void exynos5_set_lcd_clk(void)
1117 {
1118 	struct exynos5_clock *clk =
1119 	    (struct exynos5_clock *)samsung_get_base_clock();
1120 
1121 	/*
1122 	 * CLK_GATE_BLOCK
1123 	 * CLK_CAM	[0]
1124 	 * CLK_TV	[1]
1125 	 * CLK_MFC	[2]
1126 	 * CLK_G3D	[3]
1127 	 * CLK_LCD0	[4]
1128 	 * CLK_LCD1	[5]
1129 	 * CLK_GPS	[7]
1130 	 */
1131 	setbits_le32(&clk->gate_block, 1 << 4);
1132 
1133 	/*
1134 	 * CLK_SRC_LCD0
1135 	 * FIMD0_SEL		[3:0]
1136 	 * MDNIE0_SEL		[7:4]
1137 	 * MDNIE_PWM0_SEL	[8:11]
1138 	 * MIPI0_SEL		[12:15]
1139 	 * set lcd0 src clock 0x6: SCLK_MPLL
1140 	 */
1141 	clrsetbits_le32(&clk->src_disp1_0, 0xf, 0x6);
1142 
1143 	/*
1144 	 * CLK_GATE_IP_LCD0
1145 	 * CLK_FIMD0		[0]
1146 	 * CLK_MIE0		[1]
1147 	 * CLK_MDNIE0		[2]
1148 	 * CLK_DSIM0		[3]
1149 	 * CLK_SMMUFIMD0	[4]
1150 	 * CLK_PPMULCD0		[5]
1151 	 * Gating all clocks for FIMD0
1152 	 */
1153 	setbits_le32(&clk->gate_ip_disp1, 1 << 0);
1154 
1155 	/*
1156 	 * CLK_DIV_LCD0
1157 	 * FIMD0_RATIO		[3:0]
1158 	 * MDNIE0_RATIO		[7:4]
1159 	 * MDNIE_PWM0_RATIO	[11:8]
1160 	 * MDNIE_PWM_PRE_RATIO	[15:12]
1161 	 * MIPI0_RATIO		[19:16]
1162 	 * MIPI0_PRE_RATIO	[23:20]
1163 	 * set fimd ratio
1164 	 */
1165 	clrsetbits_le32(&clk->div_disp1_0, 0xf, 0x0);
1166 }
1167 
exynos5420_set_lcd_clk(void)1168 void exynos5420_set_lcd_clk(void)
1169 {
1170 	struct exynos5420_clock *clk =
1171 		(struct exynos5420_clock *)samsung_get_base_clock();
1172 	unsigned int cfg;
1173 
1174 	/*
1175 	 * CLK_SRC_DISP10
1176 	 * FIMD1_SEL [4]
1177 	 * 0: SCLK_RPLL
1178 	 * 1: SCLK_SPLL
1179 	 */
1180 	cfg = readl(&clk->src_disp10);
1181 	cfg &= ~(0x1 << 4);
1182 	cfg |= (0 << 4);
1183 	writel(cfg, &clk->src_disp10);
1184 
1185 	/*
1186 	 * CLK_DIV_DISP10
1187 	 * FIMD1_RATIO		[3:0]
1188 	 */
1189 	cfg = readl(&clk->div_disp10);
1190 	cfg &= ~(0xf << 0);
1191 	cfg |= (0 << 0);
1192 	writel(cfg, &clk->div_disp10);
1193 }
1194 
exynos5800_set_lcd_clk(void)1195 void exynos5800_set_lcd_clk(void)
1196 {
1197 	struct exynos5420_clock *clk =
1198 		(struct exynos5420_clock *)samsung_get_base_clock();
1199 	unsigned int cfg;
1200 
1201 	/*
1202 	 * Use RPLL for pixel clock
1203 	 * CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4]
1204 	 * ==================
1205 	 * 111: SCLK_RPLL
1206 	 */
1207 	cfg = readl(&clk->src_disp10) | (0x7 << 4);
1208 	writel(cfg, &clk->src_disp10);
1209 
1210 	/*
1211 	 * CLK_DIV_DISP10
1212 	 * FIMD1_RATIO		[3:0]
1213 	 */
1214 	clrsetbits_le32(&clk->div_disp10, 0xf << 0, 0x0 << 0);
1215 }
1216 
exynos4_set_mipi_clk(void)1217 void exynos4_set_mipi_clk(void)
1218 {
1219 	struct exynos4_clock *clk =
1220 	    (struct exynos4_clock *)samsung_get_base_clock();
1221 
1222 	/*
1223 	 * CLK_SRC_LCD0
1224 	 * FIMD0_SEL		[3:0]
1225 	 * MDNIE0_SEL		[7:4]
1226 	 * MDNIE_PWM0_SEL	[8:11]
1227 	 * MIPI0_SEL		[12:15]
1228 	 * set mipi0 src clock 0x6: SCLK_MPLL
1229 	 */
1230 	clrsetbits_le32(&clk->src_lcd0, 0xf << 12, 0x6 << 12);
1231 
1232 	/*
1233 	 * CLK_SRC_MASK_LCD0
1234 	 * FIMD0_MASK		[0]
1235 	 * MDNIE0_MASK		[4]
1236 	 * MDNIE_PWM0_MASK	[8]
1237 	 * MIPI0_MASK		[12]
1238 	 * set src mask mipi0 0x1: Unmask
1239 	 */
1240 	setbits_le32(&clk->src_mask_lcd0, 0x1 << 12);
1241 
1242 	/*
1243 	 * CLK_GATE_IP_LCD0
1244 	 * CLK_FIMD0		[0]
1245 	 * CLK_MIE0		[1]
1246 	 * CLK_MDNIE0		[2]
1247 	 * CLK_DSIM0		[3]
1248 	 * CLK_SMMUFIMD0	[4]
1249 	 * CLK_PPMULCD0		[5]
1250 	 * Gating all clocks for MIPI0
1251 	 */
1252 	setbits_le32(&clk->gate_ip_lcd0, 1 << 3);
1253 
1254 	/*
1255 	 * CLK_DIV_LCD0
1256 	 * FIMD0_RATIO		[3:0]
1257 	 * MDNIE0_RATIO		[7:4]
1258 	 * MDNIE_PWM0_RATIO	[11:8]
1259 	 * MDNIE_PWM_PRE_RATIO	[15:12]
1260 	 * MIPI0_RATIO		[19:16]
1261 	 * MIPI0_PRE_RATIO	[23:20]
1262 	 * set mipi ratio
1263 	 */
1264 	clrsetbits_le32(&clk->div_lcd0, 0xf << 16, 0x1 << 16);
1265 }
1266 
exynos5_set_epll_clk(unsigned long rate)1267 int exynos5_set_epll_clk(unsigned long rate)
1268 {
1269 	unsigned int epll_con, epll_con_k;
1270 	unsigned int i;
1271 	unsigned int lockcnt;
1272 	unsigned int start;
1273 	struct exynos5_clock *clk =
1274 		(struct exynos5_clock *)samsung_get_base_clock();
1275 
1276 	epll_con = readl(&clk->epll_con0);
1277 	epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
1278 			EPLL_CON0_LOCK_DET_EN_SHIFT) |
1279 		EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
1280 		EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
1281 		EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
1282 
1283 	for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
1284 		if (exynos5_epll_div[i].freq_out == rate)
1285 			break;
1286 	}
1287 
1288 	if (i == ARRAY_SIZE(exynos5_epll_div))
1289 		return -1;
1290 
1291 	epll_con_k = exynos5_epll_div[i].k_dsm << 0;
1292 	epll_con |= exynos5_epll_div[i].en_lock_det <<
1293 				EPLL_CON0_LOCK_DET_EN_SHIFT;
1294 	epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
1295 	epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
1296 	epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
1297 
1298 	/*
1299 	 * Required period ( in cycles) to genarate a stable clock output.
1300 	 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
1301 	 * frequency input (as per spec)
1302 	 */
1303 	lockcnt = 3000 * exynos5_epll_div[i].p_div;
1304 
1305 	writel(lockcnt, &clk->epll_lock);
1306 	writel(epll_con, &clk->epll_con0);
1307 	writel(epll_con_k, &clk->epll_con1);
1308 
1309 	start = get_timer(0);
1310 
1311 	 while (!(readl(&clk->epll_con0) &
1312 			(0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
1313 		if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
1314 			debug("%s: Timeout waiting for EPLL lock\n", __func__);
1315 			return -1;
1316 		}
1317 	}
1318 	return 0;
1319 }
1320 
exynos5420_set_i2s_clk_source(void)1321 static int exynos5420_set_i2s_clk_source(void)
1322 {
1323 	struct exynos5420_clock *clk =
1324 		(struct exynos5420_clock *)samsung_get_base_clock();
1325 
1326 	setbits_le32(&clk->src_top6, EXYNOS5420_CLK_SRC_MOUT_EPLL);
1327 	clrsetbits_le32(&clk->src_mau, EXYNOS5420_AUDIO0_SEL_MASK,
1328 			(EXYNOS5420_CLK_SRC_SCLK_EPLL));
1329 	setbits_le32(EXYNOS5_AUDIOSS_BASE, 1 << 0);
1330 
1331 	return 0;
1332 }
1333 
exynos5_set_i2s_clk_source(unsigned int i2s_id)1334 int exynos5_set_i2s_clk_source(unsigned int i2s_id)
1335 {
1336 	struct exynos5_clock *clk =
1337 		(struct exynos5_clock *)samsung_get_base_clock();
1338 	unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
1339 
1340 	if (i2s_id == 0) {
1341 		setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
1342 		clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
1343 				(CLK_SRC_SCLK_EPLL));
1344 		setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
1345 	} else if (i2s_id == 1) {
1346 		clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
1347 				(CLK_SRC_SCLK_EPLL));
1348 	} else {
1349 		return -1;
1350 	}
1351 	return 0;
1352 }
1353 
exynos5_set_i2s_clk_prescaler(unsigned int src_frq,unsigned int dst_frq,unsigned int i2s_id)1354 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
1355 				  unsigned int dst_frq,
1356 				  unsigned int i2s_id)
1357 {
1358 	struct exynos5_clock *clk =
1359 		(struct exynos5_clock *)samsung_get_base_clock();
1360 	unsigned int div;
1361 
1362 	if ((dst_frq == 0) || (src_frq == 0)) {
1363 		debug("%s: Invalid requency input for prescaler\n", __func__);
1364 		debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1365 		return -1;
1366 	}
1367 
1368 	div = (src_frq / dst_frq);
1369 	if (i2s_id == 0) {
1370 		if (div > AUDIO_0_RATIO_MASK) {
1371 			debug("%s: Frequency ratio is out of range\n",
1372 			      __func__);
1373 			debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1374 			return -1;
1375 		}
1376 		clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK,
1377 				(div & AUDIO_0_RATIO_MASK));
1378 	} else if (i2s_id == 1) {
1379 		if (div > AUDIO_1_RATIO_MASK) {
1380 			debug("%s: Frequency ratio is out of range\n",
1381 			      __func__);
1382 			debug("src frq = %d des frq = %d ", src_frq, dst_frq);
1383 			return -1;
1384 		}
1385 		clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
1386 				(div & AUDIO_1_RATIO_MASK));
1387 	} else {
1388 		return -1;
1389 	}
1390 	return 0;
1391 }
1392 
1393 /**
1394  * Linearly searches for the most accurate main and fine stage clock scalars
1395  * (divisors) for a specified target frequency and scalar bit sizes by checking
1396  * all multiples of main_scalar_bits values. Will always return scalars up to or
1397  * slower than target.
1398  *
1399  * @param main_scalar_bits	Number of main scalar bits, must be > 0 and < 32
1400  * @param fine_scalar_bits	Number of fine scalar bits, must be > 0 and < 32
1401  * @param input_freq		Clock frequency to be scaled in Hz
1402  * @param target_freq		Desired clock frequency in Hz
1403  * @param best_fine_scalar	Pointer to store the fine stage divisor
1404  *
1405  * @return best_main_scalar	Main scalar for desired frequency or -1 if none
1406  * found
1407  */
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)1408 static int clock_calc_best_scalar(unsigned int main_scaler_bits,
1409 	unsigned int fine_scalar_bits, unsigned int input_rate,
1410 	unsigned int target_rate, unsigned int *best_fine_scalar)
1411 {
1412 	int i;
1413 	int best_main_scalar = -1;
1414 	unsigned int best_error = target_rate;
1415 	const unsigned int cap = (1 << fine_scalar_bits) - 1;
1416 	const unsigned int loops = 1 << main_scaler_bits;
1417 
1418 	debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
1419 			target_rate, cap);
1420 
1421 	assert(best_fine_scalar != NULL);
1422 	assert(main_scaler_bits <= fine_scalar_bits);
1423 
1424 	*best_fine_scalar = 1;
1425 
1426 	if (input_rate == 0 || target_rate == 0)
1427 		return -1;
1428 
1429 	if (target_rate >= input_rate)
1430 		return 1;
1431 
1432 	for (i = 1; i <= loops; i++) {
1433 		const unsigned int effective_div =
1434 			max(min(input_rate / i / target_rate, cap), 1U);
1435 		const unsigned int effective_rate = input_rate / i /
1436 							effective_div;
1437 		const int error = target_rate - effective_rate;
1438 
1439 		debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
1440 				effective_rate, error);
1441 
1442 		if (error >= 0 && error <= best_error) {
1443 			best_error = error;
1444 			best_main_scalar = i;
1445 			*best_fine_scalar = effective_div;
1446 		}
1447 	}
1448 
1449 	return best_main_scalar;
1450 }
1451 
exynos5_set_spi_clk(enum periph_id periph_id,unsigned int rate)1452 static int exynos5_set_spi_clk(enum periph_id periph_id,
1453 					unsigned int rate)
1454 {
1455 	struct exynos5_clock *clk =
1456 		(struct exynos5_clock *)samsung_get_base_clock();
1457 	int main;
1458 	unsigned int fine;
1459 	unsigned shift, pre_shift;
1460 	unsigned mask = 0xff;
1461 	u32 *reg;
1462 
1463 	main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1464 	if (main < 0) {
1465 		debug("%s: Cannot set clock rate for periph %d",
1466 				__func__, periph_id);
1467 		return -1;
1468 	}
1469 	main = main - 1;
1470 	fine = fine - 1;
1471 
1472 	switch (periph_id) {
1473 	case PERIPH_ID_SPI0:
1474 		reg = &clk->div_peric1;
1475 		shift = 0;
1476 		pre_shift = 8;
1477 		break;
1478 	case PERIPH_ID_SPI1:
1479 		reg = &clk->div_peric1;
1480 		shift = 16;
1481 		pre_shift = 24;
1482 		break;
1483 	case PERIPH_ID_SPI2:
1484 		reg = &clk->div_peric2;
1485 		shift = 0;
1486 		pre_shift = 8;
1487 		break;
1488 	case PERIPH_ID_SPI3:
1489 		reg = &clk->sclk_div_isp;
1490 		shift = 0;
1491 		pre_shift = 4;
1492 		break;
1493 	case PERIPH_ID_SPI4:
1494 		reg = &clk->sclk_div_isp;
1495 		shift = 12;
1496 		pre_shift = 16;
1497 		break;
1498 	default:
1499 		debug("%s: Unsupported peripheral ID %d\n", __func__,
1500 		      periph_id);
1501 		return -1;
1502 	}
1503 	clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
1504 	clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
1505 
1506 	return 0;
1507 }
1508 
exynos5420_set_spi_clk(enum periph_id periph_id,unsigned int rate)1509 static int exynos5420_set_spi_clk(enum periph_id periph_id,
1510 					unsigned int rate)
1511 {
1512 	struct exynos5420_clock *clk =
1513 		(struct exynos5420_clock *)samsung_get_base_clock();
1514 	int main;
1515 	unsigned int fine;
1516 	unsigned shift, pre_shift;
1517 	unsigned div_mask = 0xf, pre_div_mask = 0xff;
1518 	u32 *reg;
1519 	u32 *pre_reg;
1520 
1521 	main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
1522 	if (main < 0) {
1523 		debug("%s: Cannot set clock rate for periph %d",
1524 		      __func__, periph_id);
1525 		return -1;
1526 	}
1527 	main = main - 1;
1528 	fine = fine - 1;
1529 
1530 	switch (periph_id) {
1531 	case PERIPH_ID_SPI0:
1532 		reg = &clk->div_peric1;
1533 		shift = 20;
1534 		pre_reg = &clk->div_peric4;
1535 		pre_shift = 8;
1536 		break;
1537 	case PERIPH_ID_SPI1:
1538 		reg = &clk->div_peric1;
1539 		shift = 24;
1540 		pre_reg = &clk->div_peric4;
1541 		pre_shift = 16;
1542 		break;
1543 	case PERIPH_ID_SPI2:
1544 		reg = &clk->div_peric1;
1545 		shift = 28;
1546 		pre_reg = &clk->div_peric4;
1547 		pre_shift = 24;
1548 		break;
1549 	case PERIPH_ID_SPI3:
1550 		reg = &clk->div_isp1;
1551 		shift = 16;
1552 		pre_reg = &clk->div_isp1;
1553 		pre_shift = 0;
1554 		break;
1555 	case PERIPH_ID_SPI4:
1556 		reg = &clk->div_isp1;
1557 		shift = 20;
1558 		pre_reg = &clk->div_isp1;
1559 		pre_shift = 8;
1560 		break;
1561 	default:
1562 		debug("%s: Unsupported peripheral ID %d\n", __func__,
1563 		      periph_id);
1564 		return -1;
1565 	}
1566 
1567 	clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift);
1568 	clrsetbits_le32(pre_reg, pre_div_mask << pre_shift,
1569 			(fine & pre_div_mask) << pre_shift);
1570 
1571 	return 0;
1572 }
1573 
exynos4_get_i2c_clk(void)1574 static unsigned long exynos4_get_i2c_clk(void)
1575 {
1576 	struct exynos4_clock *clk =
1577 		(struct exynos4_clock *)samsung_get_base_clock();
1578 	unsigned long sclk, aclk_100;
1579 	unsigned int ratio;
1580 
1581 	sclk = get_pll_clk(APLL);
1582 
1583 	ratio = (readl(&clk->div_top)) >> 4;
1584 	ratio &= 0xf;
1585 	aclk_100 = sclk / (ratio + 1);
1586 	return aclk_100;
1587 }
1588 
get_pll_clk(int pllreg)1589 unsigned long get_pll_clk(int pllreg)
1590 {
1591 	if (cpu_is_exynos5()) {
1592 		if (proid_is_exynos542x())
1593 			return exynos542x_get_pll_clk(pllreg);
1594 		return exynos5_get_pll_clk(pllreg);
1595 	} else if (cpu_is_exynos4()) {
1596 		if (proid_is_exynos4412())
1597 			return exynos4x12_get_pll_clk(pllreg);
1598 		return exynos4_get_pll_clk(pllreg);
1599 	}
1600 
1601 	return 0;
1602 }
1603 
get_arm_clk(void)1604 unsigned long get_arm_clk(void)
1605 {
1606 	if (cpu_is_exynos5()) {
1607 		return exynos5_get_arm_clk();
1608 	} else if (cpu_is_exynos4()) {
1609 		if (proid_is_exynos4412())
1610 			return exynos4x12_get_arm_clk();
1611 		return exynos4_get_arm_clk();
1612 	}
1613 
1614 	return 0;
1615 }
1616 
get_i2c_clk(void)1617 unsigned long get_i2c_clk(void)
1618 {
1619 	if (cpu_is_exynos5())
1620 		return clock_get_periph_rate(PERIPH_ID_I2C0);
1621 	else if (cpu_is_exynos4())
1622 		return exynos4_get_i2c_clk();
1623 
1624 	return 0;
1625 }
1626 
get_pwm_clk(void)1627 unsigned long get_pwm_clk(void)
1628 {
1629 	if (cpu_is_exynos5()) {
1630 		return clock_get_periph_rate(PERIPH_ID_PWM0);
1631 	} else if (cpu_is_exynos4()) {
1632 		if (proid_is_exynos4412())
1633 			return exynos4x12_get_pwm_clk();
1634 		return exynos4_get_pwm_clk();
1635 	}
1636 
1637 	return 0;
1638 }
1639 
get_uart_clk(int dev_index)1640 unsigned long get_uart_clk(int dev_index)
1641 {
1642 	enum periph_id id;
1643 
1644 	switch (dev_index) {
1645 	case 0:
1646 		id = PERIPH_ID_UART0;
1647 		break;
1648 	case 1:
1649 		id = PERIPH_ID_UART1;
1650 		break;
1651 	case 2:
1652 		id = PERIPH_ID_UART2;
1653 		break;
1654 	case 3:
1655 		id = PERIPH_ID_UART3;
1656 		break;
1657 	default:
1658 		debug("%s: invalid UART index %d", __func__, dev_index);
1659 		return -1;
1660 	}
1661 
1662 	if (cpu_is_exynos5()) {
1663 		return clock_get_periph_rate(id);
1664 	} else if (cpu_is_exynos4()) {
1665 		if (proid_is_exynos4412())
1666 			return exynos4x12_get_uart_clk(dev_index);
1667 		return exynos4_get_uart_clk(dev_index);
1668 	}
1669 
1670 	return 0;
1671 }
1672 
get_mmc_clk(int dev_index)1673 unsigned long get_mmc_clk(int dev_index)
1674 {
1675 	enum periph_id id;
1676 
1677 	if (cpu_is_exynos4())
1678 		return exynos4_get_mmc_clk(dev_index);
1679 
1680 	switch (dev_index) {
1681 	case 0:
1682 		id = PERIPH_ID_SDMMC0;
1683 		break;
1684 	case 1:
1685 		id = PERIPH_ID_SDMMC1;
1686 		break;
1687 	case 2:
1688 		id = PERIPH_ID_SDMMC2;
1689 		break;
1690 	case 3:
1691 		id = PERIPH_ID_SDMMC3;
1692 		break;
1693 	default:
1694 		debug("%s: invalid MMC index %d", __func__, dev_index);
1695 		return -1;
1696 	}
1697 
1698 	return clock_get_periph_rate(id);
1699 }
1700 
set_mmc_clk(int dev_index,unsigned int div)1701 void set_mmc_clk(int dev_index, unsigned int div)
1702 {
1703 	/* If want to set correct value, it needs to substract one from div.*/
1704 	if (div > 0)
1705 		div -= 1;
1706 
1707 	if (cpu_is_exynos5()) {
1708 		if (proid_is_exynos542x())
1709 			exynos5420_set_mmc_clk(dev_index, div);
1710 		else
1711 			exynos5_set_mmc_clk(dev_index, div);
1712 	} else if (cpu_is_exynos4()) {
1713 		exynos4_set_mmc_clk(dev_index, div);
1714 	}
1715 }
1716 
get_lcd_clk(void)1717 unsigned long get_lcd_clk(void)
1718 {
1719 	if (cpu_is_exynos4()) {
1720 		return exynos4_get_lcd_clk();
1721 	} else if (cpu_is_exynos5()) {
1722 		if (proid_is_exynos5420())
1723 			return exynos5420_get_lcd_clk();
1724 		else if (proid_is_exynos5422())
1725 			return exynos5800_get_lcd_clk();
1726 		else
1727 			return exynos5_get_lcd_clk();
1728 	}
1729 
1730 	return 0;
1731 }
1732 
set_lcd_clk(void)1733 void set_lcd_clk(void)
1734 {
1735 	if (cpu_is_exynos4()) {
1736 		exynos4_set_lcd_clk();
1737 	} else if (cpu_is_exynos5()) {
1738 		if (proid_is_exynos5250())
1739 			exynos5_set_lcd_clk();
1740 		else if (proid_is_exynos5420())
1741 			exynos5420_set_lcd_clk();
1742 		else
1743 			exynos5800_set_lcd_clk();
1744 	}
1745 }
1746 
set_mipi_clk(void)1747 void set_mipi_clk(void)
1748 {
1749 	if (cpu_is_exynos4())
1750 		exynos4_set_mipi_clk();
1751 }
1752 
set_spi_clk(int periph_id,unsigned int rate)1753 int set_spi_clk(int periph_id, unsigned int rate)
1754 {
1755 	if (cpu_is_exynos5()) {
1756 		if (proid_is_exynos542x())
1757 			return exynos5420_set_spi_clk(periph_id, rate);
1758 		return exynos5_set_spi_clk(periph_id, rate);
1759 	}
1760 
1761 	return 0;
1762 }
1763 
set_i2s_clk_prescaler(unsigned int src_frq,unsigned int dst_frq,unsigned int i2s_id)1764 int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
1765 			  unsigned int i2s_id)
1766 {
1767 	if (cpu_is_exynos5())
1768 		return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
1769 
1770 	return 0;
1771 }
1772 
set_i2s_clk_source(unsigned int i2s_id)1773 int set_i2s_clk_source(unsigned int i2s_id)
1774 {
1775 	if (cpu_is_exynos5()) {
1776 		if (proid_is_exynos542x())
1777 			return exynos5420_set_i2s_clk_source();
1778 		else
1779 			return exynos5_set_i2s_clk_source(i2s_id);
1780 	}
1781 
1782 	return 0;
1783 }
1784 
set_epll_clk(unsigned long rate)1785 int set_epll_clk(unsigned long rate)
1786 {
1787 	if (cpu_is_exynos5())
1788 		return exynos5_set_epll_clk(rate);
1789 
1790 	return 0;
1791 }
1792