• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2015 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include <assert.h>
25 #include <inttypes.h>
26 #include <limits.h>
27 #include <stdio.h>
28 #include <stdbool.h>
29 #include <stdint.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include "igt_stats.h"
34 
35 #define U64_MAX         ((uint64_t)~0ULL)
36 #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
37 
38 #define WARN(cond, msg)	printf(msg)
39 
40 #define KHz(x) (1000 * (x))
41 #define MHz(x) KHz(1000 * (x))
42 
43 #define abs_diff(a, b) ({			\
44 	typeof(a) __a = (a);			\
45 	typeof(b) __b = (b);			\
46 	(void) (&__a == &__b);			\
47 	__a > __b ? (__a - __b) : (__b - __a); })
48 
div64_u64(uint64_t dividend,uint64_t divisor)49 static inline uint64_t div64_u64(uint64_t dividend, uint64_t divisor)
50 {
51 	return dividend / divisor;
52 }
53 
div_u64(uint64_t dividend,uint32_t divisor)54 static inline uint64_t div_u64(uint64_t dividend, uint32_t divisor)
55 {
56 	return dividend / divisor;
57 }
58 
59 struct skl_wrpll_params {
60 	uint32_t        dco_fraction;
61 	uint32_t        dco_integer;
62 	uint32_t        qdiv_ratio;
63 	uint32_t        qdiv_mode;
64 	uint32_t        kdiv;
65 	uint32_t        pdiv;
66 	uint32_t        central_freq;
67 
68 	/* for this test code only */
69 	uint64_t central_freq_hz;
70 	unsigned int p0, p1, p2;
71 };
72 
73 static bool
skl_ddi_calculate_wrpll1(int clock,struct skl_wrpll_params * wrpll_params)74 skl_ddi_calculate_wrpll1(int clock /* in Hz */,
75 			 struct skl_wrpll_params *wrpll_params)
76 {
77 	uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
78 	uint64_t dco_central_freq[3] = {8400000000ULL,
79 					9000000000ULL,
80 					9600000000ULL};
81 	uint32_t min_dco_pdeviation = 100; /* DCO freq must be within +1%/-6% */
82 	uint32_t min_dco_ndeviation = 600; /* of the DCO central freq */
83 	uint32_t min_dco_index = 3;
84 	uint32_t P0[4] = {1, 2, 3, 7};
85 	uint32_t P2[4] = {1, 2, 3, 5};
86 	bool found = false;
87 	uint32_t candidate_p = 0;
88 	uint32_t candidate_p0[3] = {0}, candidate_p1[3] = {0};
89 	uint32_t candidate_p2[3] = {0};
90 	uint32_t dco_central_freq_deviation[3];
91 	uint32_t i, P1, k, dco_count;
92 	bool retry_with_odd = false;
93 
94 	/* Determine P0, P1 or P2 */
95 	for (dco_count = 0; dco_count < 3; dco_count++) {
96 		found = false;
97 		candidate_p =
98 			div64_u64(dco_central_freq[dco_count], afe_clock);
99 		if (retry_with_odd == false)
100 			candidate_p = (candidate_p % 2 == 0 ?
101 				candidate_p : candidate_p + 1);
102 
103 		for (P1 = 1; P1 < candidate_p; P1++) {
104 			for (i = 0; i < 4; i++) {
105 				if (!(P0[i] != 1 || P1 == 1))
106 					continue;
107 
108 				for (k = 0; k < 4; k++) {
109 					if (P1 != 1 && P2[k] != 2)
110 						continue;
111 
112 					if (candidate_p == P0[i] * P1 * P2[k]) {
113 						/* Found possible P0, P1, P2 */
114 						found = true;
115 						candidate_p0[dco_count] = P0[i];
116 						candidate_p1[dco_count] = P1;
117 						candidate_p2[dco_count] = P2[k];
118 						goto found;
119 					}
120 
121 				}
122 			}
123 		}
124 
125 found:
126 		if (found) {
127 			uint64_t dco_freq = candidate_p * afe_clock;
128 
129 #if 0
130 			printf("Trying with (%d,%d,%d)\n",
131 			       candidate_p0[dco_count],
132 			       candidate_p1[dco_count],
133 			       candidate_p2[dco_count]);
134 #endif
135 
136 			dco_central_freq_deviation[dco_count] =
137 				div64_u64(10000 *
138 					  abs_diff(dco_freq,
139 						   dco_central_freq[dco_count]),
140 					  dco_central_freq[dco_count]);
141 
142 #if 0
143 			printf("Deviation %d\n",
144 			       dco_central_freq_deviation[dco_count]);
145 
146 			printf("dco_freq: %"PRIu64", "
147 			       "dco_central_freq %"PRIu64"\n",
148 			       dco_freq, dco_central_freq[dco_count]);
149 #endif
150 
151 			/* positive deviation */
152 			if (dco_freq > dco_central_freq[dco_count]) {
153 				if (dco_central_freq_deviation[dco_count] <
154 				    min_dco_pdeviation) {
155 					min_dco_pdeviation =
156 						dco_central_freq_deviation[dco_count];
157 					min_dco_index = dco_count;
158 				}
159 			/* negative deviation */
160 			} else if (dco_central_freq_deviation[dco_count] <
161 				   min_dco_ndeviation) {
162 				min_dco_ndeviation =
163 					dco_central_freq_deviation[dco_count];
164 				min_dco_index = dco_count;
165 			}
166 		}
167 
168 		if (min_dco_index > 2 && dco_count == 2) {
169 			/* oh well, we tried... */
170 			if (retry_with_odd)
171 				break;
172 
173 			retry_with_odd = true;
174 			dco_count = 0;
175 		}
176 	}
177 
178 	if (min_dco_index > 2) {
179 		WARN(1, "No valid values found for the given pixel clock\n");
180 		return false;
181 	} else {
182 		uint64_t dco_freq;
183 
184 		wrpll_params->central_freq = dco_central_freq[min_dco_index];
185 
186 		switch (dco_central_freq[min_dco_index]) {
187 		case 9600000000ULL:
188 			wrpll_params->central_freq = 0;
189 			break;
190 		case 9000000000ULL:
191 			wrpll_params->central_freq = 1;
192 			break;
193 		case 8400000000ULL:
194 			wrpll_params->central_freq = 3;
195 		}
196 
197 		switch (candidate_p0[min_dco_index]) {
198 		case 1:
199 			wrpll_params->pdiv = 0;
200 			break;
201 		case 2:
202 			wrpll_params->pdiv = 1;
203 			break;
204 		case 3:
205 			wrpll_params->pdiv = 2;
206 			break;
207 		case 7:
208 			wrpll_params->pdiv = 4;
209 			break;
210 		default:
211 			WARN(1, "Incorrect PDiv\n");
212 		}
213 
214 		switch (candidate_p2[min_dco_index]) {
215 		case 5:
216 			wrpll_params->kdiv = 0;
217 			break;
218 		case 2:
219 			wrpll_params->kdiv = 1;
220 			break;
221 		case 3:
222 			wrpll_params->kdiv = 2;
223 			break;
224 		case 1:
225 			wrpll_params->kdiv = 3;
226 			break;
227 		default:
228 			WARN(1, "Incorrect KDiv\n");
229 		}
230 
231 		wrpll_params->qdiv_ratio = candidate_p1[min_dco_index];
232 		wrpll_params->qdiv_mode =
233 			(wrpll_params->qdiv_ratio == 1) ? 0 : 1;
234 
235 		dco_freq = candidate_p0[min_dco_index] *
236 			candidate_p1[min_dco_index] *
237 			candidate_p2[min_dco_index] * afe_clock;
238 
239 		/*
240 		 * Intermediate values are in Hz.
241 		 * Divide by MHz to match bsepc
242 		 */
243 		wrpll_params->dco_integer = div_u64(dco_freq, (24 * MHz(1)));
244 		wrpll_params->dco_fraction =
245 			div_u64(((div_u64(dco_freq, 24) -
246 				  wrpll_params->dco_integer * MHz(1)) * 0x8000), MHz(1));
247 
248 	}
249 
250 	/* for this unit test only */
251 	wrpll_params->central_freq_hz = dco_central_freq[min_dco_index];
252 	wrpll_params->p0 = candidate_p0[min_dco_index];
253 	wrpll_params->p1 = candidate_p1[min_dco_index];
254 	wrpll_params->p2 = candidate_p2[min_dco_index];
255 
256 	return true;
257 }
258 
259 struct skl_wrpll_context {
260 	uint64_t min_deviation;		/* current minimal deviation */
261 	uint64_t central_freq;		/* chosen central freq */
262 	uint64_t dco_freq;		/* chosen dco freq */
263 	unsigned int p;			/* chosen divider */
264 };
265 
skl_wrpll_context_init(struct skl_wrpll_context * ctx)266 static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
267 {
268 	memset(ctx, 0, sizeof(*ctx));
269 
270 	ctx->min_deviation = U64_MAX;
271 }
272 
273 /* DCO freq must be within +1%/-6%  of the DCO central freq */
274 #define SKL_MAX_PDEVIATION	100
275 #define SKL_MAX_NDEVIATION	600
276 
277 
278 /*
279  * Returns true if we're sure to have found the definitive divider (ie
280  * deviation == 0).
281  */
skl_wrpll_try_divider(struct skl_wrpll_context * ctx,uint64_t central_freq,uint64_t dco_freq,unsigned int divider)282 static bool skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
283 				  uint64_t central_freq,
284 				  uint64_t dco_freq,
285 				  unsigned int divider)
286 {
287 	uint64_t deviation;
288 	bool found = false;
289 
290 	deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
291 			      central_freq);
292 
293 	/* positive deviation */
294 	if (dco_freq >= central_freq) {
295 		if (deviation < SKL_MAX_PDEVIATION &&
296 		    deviation < ctx->min_deviation) {
297 			ctx->min_deviation = deviation;
298 			ctx->central_freq = central_freq;
299 			ctx->dco_freq = dco_freq;
300 			ctx->p = divider;
301 #if 0
302 			found = true;
303 #endif
304 		}
305 
306 		/* we can't improve a 0 deviation */
307 		if (deviation == 0)
308 			return true;
309 	/* negative deviation */
310 	} else if (deviation < SKL_MAX_NDEVIATION &&
311 		   deviation < ctx->min_deviation) {
312 		ctx->min_deviation = deviation;
313 		ctx->central_freq = central_freq;
314 		ctx->dco_freq = dco_freq;
315 		ctx->p = divider;
316 #if 0
317 		found = true;
318 #endif
319 	}
320 
321 	if (found) {
322 		printf("Divider %d\n", divider);
323 		printf("Deviation %"PRIu64"\n", deviation);
324 		printf("dco_freq: %"PRIu64", dco_central_freq %"PRIu64"\n",
325 		       dco_freq, central_freq);
326 	}
327 
328 	return false;
329 }
330 
skl_wrpll_get_multipliers(unsigned int p,unsigned int * p0,unsigned int * p1,unsigned int * p2)331 static void skl_wrpll_get_multipliers(unsigned int p,
332 				      unsigned int *p0 /* out */,
333 				      unsigned int *p1 /* out */,
334 				      unsigned int *p2 /* out */)
335 {
336 	/* even dividers */
337 	if (p % 2 == 0) {
338 		unsigned int half = p / 2;
339 
340 		if (half == 1 || half == 2 || half == 3 || half == 5) {
341 			*p0 = 2;
342 			*p1 = 1;
343 			*p2 = half;
344 		} else if (half % 2 == 0) {
345 			*p0 = 2;
346 			*p1 = half / 2;
347 			*p2 = 2;
348 		} else if (half % 3 == 0) {
349 			*p0 = 3;
350 			*p1 = half / 3;
351 			*p2 = 2;
352 		} else if (half % 7 == 0) {
353 			*p0 = 7;
354 			*p1 = half / 7;
355 			*p2 = 2;
356 		}
357 	} else if (p == 3 || p == 9) {  /* 3, 5, 7, 9, 15, 21, 35 */
358 		*p0 = 3;
359 		*p1 = 1;
360 		*p2 = p / 3;
361 	} else if (p == 5 || p == 7) {
362 		*p0 = p;
363 		*p1 = 1;
364 		*p2 = 1;
365 	} else if (p == 15) {
366 		*p0 = 3;
367 		*p1 = 1;
368 		*p2 = 5;
369 	} else if (p == 21) {
370 		*p0 = 7;
371 		*p1 = 1;
372 		*p2 = 3;
373 	} else if (p == 35) {
374 		*p0 = 7;
375 		*p1 = 1;
376 		*p2 = 5;
377 	}
378 }
379 
test_multipliers(void)380 static void test_multipliers(void)
381 {
382 	static const int even_dividers[] = {  4,  6,  8, 10, 12, 14, 16, 18, 20,
383 					     24, 28, 30, 32, 36, 40, 42, 44,
384 					     48, 52, 54, 56, 60, 64, 66, 68,
385 					     70, 72, 76, 78, 80, 84, 88, 90,
386 					     92, 96, 98 };
387 	static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
388 	static const struct {
389 		const int *list;
390 		int n_dividers;
391 	} dividers[] = {
392 		{ even_dividers, ARRAY_SIZE(even_dividers) },
393 		{ odd_dividers, ARRAY_SIZE(odd_dividers) },
394 	};
395 	unsigned int d, i;
396 
397 	for (d = 0; d < ARRAY_SIZE(dividers); d++) {
398 		for (i = 0; i < dividers[d].n_dividers; i++) {
399 			unsigned int p = dividers[d].list[i];
400 			unsigned p0, p1, p2;
401 
402 			p0 = p1 = p2 = 0;
403 
404 			skl_wrpll_get_multipliers(p, &p0, &p1, &p2);
405 
406 			assert(p0);
407 			assert(p1);
408 			assert(p2);
409 			assert(p == p0 * p1 * p2);
410 		}
411 	}
412 }
413 
414 static bool
skl_ddi_calculate_wrpll2(int clock,struct skl_wrpll_params * wrpll_params)415 skl_ddi_calculate_wrpll2(int clock /* in Hz */,
416 			 struct skl_wrpll_params *wrpll_params)
417 {
418 	uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
419 	uint64_t dco_central_freq[3] = {8400000000ULL,
420 					9000000000ULL,
421 					9600000000ULL};
422 	static const int even_dividers[] = {  4,  6,  8, 10, 12, 14, 16, 18, 20,
423 					     24, 28, 30, 32, 36, 40, 42, 44,
424 					     48, 52, 54, 56, 60, 64, 66, 68,
425 					     70, 72, 76, 78, 80, 84, 88, 90,
426 					     92, 96, 98 };
427 	static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
428 	static const struct {
429 		const int *list;
430 		int n_dividers;
431 	} dividers[] = {
432 		{ even_dividers, ARRAY_SIZE(even_dividers) },
433 		{ odd_dividers, ARRAY_SIZE(odd_dividers) },
434 	};
435 	struct skl_wrpll_context ctx;
436 	unsigned int dco, d, i;
437 	unsigned int p0, p1, p2;
438 
439 	skl_wrpll_context_init(&ctx);
440 
441 	for (d = 0; d < ARRAY_SIZE(dividers); d++) {
442 		for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
443 			for (i = 0; i < dividers[d].n_dividers; i++) {
444 				unsigned int p = dividers[d].list[i];
445 				uint64_t dco_freq = p * afe_clock;
446 
447 				if (skl_wrpll_try_divider(&ctx,
448 							  dco_central_freq[dco],
449 							  dco_freq,
450 							  p))
451 					goto skip_remaining_dividers;
452 			}
453 		}
454 
455 skip_remaining_dividers:
456 		/*
457 		 * If a solution is found with an even divider, prefer
458 		 * this one.
459 		 */
460 		if (d == 0 && ctx.p)
461 			break;
462 	}
463 
464 	if (!ctx.p)
465 		return false;
466 
467 	skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
468 
469 	/* for this unit test only */
470 	wrpll_params->central_freq_hz = ctx.central_freq;
471 	wrpll_params->p0 = p0;
472 	wrpll_params->p1 = p1;
473 	wrpll_params->p2 = p2;
474 
475 	return true;
476 }
477 
478 static const struct {
479 	uint32_t clock; /* in Hz */
480 } modes[] = {
481 	{ 19750000 },
482 	{ 20000000 },
483 	{ 21000000 },
484 	{ 21912000 },
485 	{ 22000000 },
486 	{ 23000000 },
487 	{ 23500000 },
488 	{ 23750000 },
489 	{ 24000000 },
490 	{ 25000000 },
491 	{ 25175000 },
492 	{ 25200000 },
493 	{ 26000000 },
494 	{ 27000000 },
495 	{ 27027000 },
496 	{ 27500000 },
497 	{ 28000000 },
498 	{ 28320000 },
499 	{ 28322000 },
500 	{ 28750000 },
501 	{ 29000000 },
502 	{ 29750000 },
503 	{ 30000000 },
504 	{ 30750000 },
505 	{ 31000000 },
506 	{ 31500000 },
507 	{ 32000000 },
508 	{ 32500000 },
509 	{ 33000000 },
510 	{ 34000000 },
511 	{ 35000000 },
512 	{ 35500000 },
513 	{ 36000000 },
514 	{ 36750000 },
515 	{ 37000000 },
516 	{ 37762500 },
517 	{ 37800000 },
518 	{ 38000000 },
519 	{ 38250000 },
520 	{ 39000000 },
521 	{ 40000000 },
522 	{ 40500000 },
523 	{ 40541000 },
524 	{ 40750000 },
525 	{ 41000000 },
526 	{ 41500000 },
527 	{ 41540000 },
528 	{ 42000000 },
529 	{ 42500000 },
530 	{ 43000000 },
531 	{ 43163000 },
532 	{ 44000000 },
533 	{ 44900000 },
534 	{ 45000000 },
535 	{ 45250000 },
536 	{ 46000000 },
537 	{ 46750000 },
538 	{ 47000000 },
539 	{ 48000000 },
540 	{ 49000000 },
541 	{ 49500000 },
542 	{ 50000000 },
543 	{ 50500000 },
544 	{ 51000000 },
545 	{ 52000000 },
546 	{ 52406000 },
547 	{ 53000000 },
548 	{ 54000000 },
549 	{ 54054000 },
550 	{ 54500000 },
551 	{ 55000000 },
552 	{ 56000000 },
553 	{ 56250000 },
554 	{ 56750000 },
555 	{ 57000000 },
556 	{ 58000000 },
557 	{ 58250000 },
558 	{ 58750000 },
559 	{ 59000000 },
560 	{ 59341000 },
561 	{ 59400000 },
562 	{ 60000000 },
563 	{ 60500000 },
564 	{ 61000000 },
565 	{ 62000000 },
566 	{ 62250000 },
567 	{ 63000000 },
568 	{ 63500000 },
569 	{ 64000000 },
570 	{ 65000000 },
571 	{ 65250000 },
572 	{ 65500000 },
573 	{ 66000000 },
574 	{ 66667000 },
575 	{ 66750000 },
576 	{ 67000000 },
577 	{ 67750000 },
578 	{ 68000000 },
579 	{ 68179000 },
580 	{ 68250000 },
581 	{ 69000000 },
582 	{ 70000000 },
583 	{ 71000000 },
584 	{ 72000000 },
585 	{ 73000000 },
586 	{ 74000000 },
587 	{ 74176000 },
588 	{ 74250000 },
589 	{ 74481000 },
590 	{ 74500000 },
591 	{ 75000000 },
592 	{ 75250000 },
593 	{ 76000000 },
594 	{ 77000000 },
595 	{ 78000000 },
596 	{ 78750000 },
597 	{ 79000000 },
598 	{ 79500000 },
599 	{ 80000000 },
600 	{ 81000000 },
601 	{ 81081000 },
602 	{ 81624000 },
603 	{ 82000000 },
604 	{ 83000000 },
605 	{ 83950000 },
606 	{ 84000000 },
607 	{ 84750000 },
608 	{ 85000000 },
609 	{ 85250000 },
610 	{ 85750000 },
611 	{ 86000000 },
612 	{ 87000000 },
613 	{ 88000000 },
614 	{ 88500000 },
615 	{ 89000000 },
616 	{ 89012000 },
617 	{ 89100000 },
618 	{ 90000000 },
619 	{ 91000000 },
620 	{ 92000000 },
621 	{ 93000000 },
622 	{ 94000000 },
623 	{ 94500000 },
624 	{ 95000000 },
625 	{ 95654000 },
626 	{ 95750000 },
627 	{ 96000000 },
628 	{ 97000000 },
629 	{ 97750000 },
630 	{ 98000000 },
631 	{ 99000000 },
632 	{ 99750000 },
633 	{ 100000000 },
634 	{ 100500000 },
635 	{ 101000000 },
636 	{ 101250000 },
637 	{ 102000000 },
638 	{ 102250000 },
639 	{ 103000000 },
640 	{ 104000000 },
641 	{ 105000000 },
642 	{ 106000000 },
643 	{ 107000000 },
644 	{ 107214000 },
645 	{ 108000000 },
646 	{ 108108000 },
647 	{ 109000000 },
648 	{ 110000000 },
649 	{ 110013000 },
650 	{ 110250000 },
651 	{ 110500000 },
652 	{ 111000000 },
653 	{ 111264000 },
654 	{ 111375000 },
655 	{ 112000000 },
656 	{ 112500000 },
657 	{ 113100000 },
658 	{ 113309000 },
659 	{ 114000000 },
660 	{ 115000000 },
661 	{ 116000000 },
662 	{ 117000000 },
663 	{ 117500000 },
664 	{ 118000000 },
665 	{ 119000000 },
666 	{ 119500000 },
667 	{ 119651000 },
668 	{ 120000000 },
669 	{ 121000000 },
670 	{ 121250000 },
671 	{ 121750000 },
672 	{ 122000000 },
673 	{ 122614000 },
674 	{ 123000000 },
675 	{ 123379000 },
676 	{ 124000000 },
677 	{ 125000000 },
678 	{ 125250000 },
679 	{ 125750000 },
680 	{ 126000000 },
681 	{ 127000000 },
682 	{ 127250000 },
683 	{ 128000000 },
684 	{ 129000000 },
685 	{ 129859000 },
686 	{ 130000000 },
687 	{ 130250000 },
688 	{ 131000000 },
689 	{ 131500000 },
690 	{ 131850000 },
691 	{ 132000000 },
692 	{ 132750000 },
693 	{ 133000000 },
694 	{ 133330000 },
695 	{ 134000000 },
696 	{ 135000000 },
697 	{ 135250000 },
698 	{ 136000000 },
699 	{ 137000000 },
700 	{ 138000000 },
701 	{ 138500000 },
702 	{ 138750000 },
703 	{ 139000000 },
704 	{ 139050000 },
705 	{ 139054000 },
706 	{ 140000000 },
707 	{ 141000000 },
708 	{ 141500000 },
709 	{ 142000000 },
710 	{ 143000000 },
711 	{ 143472000 },
712 	{ 144000000 },
713 	{ 145000000 },
714 	{ 146000000 },
715 	{ 146250000 },
716 	{ 147000000 },
717 	{ 147891000 },
718 	{ 148000000 },
719 	{ 148250000 },
720 	{ 148352000 },
721 	{ 148500000 },
722 	{ 149000000 },
723 	{ 150000000 },
724 	{ 151000000 },
725 	{ 152000000 },
726 	{ 152280000 },
727 	{ 153000000 },
728 	{ 154000000 },
729 	{ 155000000 },
730 	{ 155250000 },
731 	{ 155750000 },
732 	{ 156000000 },
733 	{ 157000000 },
734 	{ 157500000 },
735 	{ 158000000 },
736 	{ 158250000 },
737 	{ 159000000 },
738 	{ 159500000 },
739 	{ 160000000 },
740 	{ 161000000 },
741 	{ 162000000 },
742 	{ 162162000 },
743 	{ 162500000 },
744 	{ 163000000 },
745 	{ 164000000 },
746 	{ 165000000 },
747 	{ 166000000 },
748 	{ 167000000 },
749 	{ 168000000 },
750 	{ 169000000 },
751 	{ 169128000 },
752 	{ 169500000 },
753 	{ 170000000 },
754 	{ 171000000 },
755 	{ 172000000 },
756 	{ 172750000 },
757 	{ 172800000 },
758 	{ 173000000 },
759 	{ 174000000 },
760 	{ 174787000 },
761 	{ 175000000 },
762 	{ 176000000 },
763 	{ 177000000 },
764 	{ 178000000 },
765 	{ 178500000 },
766 	{ 179000000 },
767 	{ 179500000 },
768 	{ 180000000 },
769 	{ 181000000 },
770 	{ 182000000 },
771 	{ 183000000 },
772 	{ 184000000 },
773 	{ 184750000 },
774 	{ 185000000 },
775 	{ 186000000 },
776 	{ 187000000 },
777 	{ 188000000 },
778 	{ 189000000 },
779 	{ 190000000 },
780 	{ 190960000 },
781 	{ 191000000 },
782 	{ 192000000 },
783 	{ 192250000 },
784 	{ 193000000 },
785 	{ 193250000 },
786 	{ 194000000 },
787 	{ 194208000 },
788 	{ 195000000 },
789 	{ 196000000 },
790 	{ 197000000 },
791 	{ 197750000 },
792 	{ 198000000 },
793 	{ 198500000 },
794 	{ 199000000 },
795 	{ 200000000 },
796 	{ 201000000 },
797 	{ 202000000 },
798 	{ 202500000 },
799 	{ 203000000 },
800 	{ 204000000 },
801 	{ 204750000 },
802 	{ 205000000 },
803 	{ 206000000 },
804 	{ 207000000 },
805 	{ 207500000 },
806 	{ 208000000 },
807 	{ 208900000 },
808 	{ 209000000 },
809 	{ 209250000 },
810 	{ 210000000 },
811 	{ 211000000 },
812 	{ 212000000 },
813 	{ 213000000 },
814 	{ 213750000 },
815 	{ 214000000 },
816 	{ 214750000 },
817 	{ 215000000 },
818 	{ 216000000 },
819 	{ 217000000 },
820 	{ 218000000 },
821 	{ 218250000 },
822 	{ 218750000 },
823 	{ 219000000 },
824 	{ 220000000 },
825 	{ 220640000 },
826 	{ 220750000 },
827 	{ 221000000 },
828 	{ 222000000 },
829 	{ 222525000 },
830 	{ 222750000 },
831 	{ 227000000 },
832 	{ 230250000 },
833 	{ 233500000 },
834 	{ 235000000 },
835 	{ 238000000 },
836 	{ 241500000 },
837 	{ 245250000 },
838 	{ 247750000 },
839 	{ 253250000 },
840 	{ 256250000 },
841 	{ 262500000 },
842 	{ 267250000 },
843 	{ 268500000 },
844 	{ 270000000 },
845 	{ 272500000 },
846 	{ 273750000 },
847 	{ 280750000 },
848 	{ 281250000 },
849 	{ 286000000 },
850 	{ 291750000 },
851 	{ 296703000 },
852 	{ 297000000 },
853 	{ 298000000 },
854 };
855 
856 struct test_ops {
857 	bool (*compute)(int clock, struct skl_wrpll_params *params);
858 } tests[] = {
859 	{ .compute = skl_ddi_calculate_wrpll1 },
860 	{ .compute = skl_ddi_calculate_wrpll2 },
861 };
862 
test_run(struct test_ops * test)863 static void test_run(struct test_ops *test)
864 {
865 	unsigned int m;
866 	unsigned p_odd_even[2] = { 0, 0 };
867 	igt_stats_t stats;
868 
869 	igt_stats_init_with_size(&stats, ARRAY_SIZE(modes));
870 	igt_stats_set_population(&stats, true);
871 
872 	for (m = 0; m < ARRAY_SIZE(modes); m++) {
873 		struct skl_wrpll_params params = {};
874 		int clock = modes[m].clock;
875 		unsigned int p;
876 
877 		if (!test->compute(clock, &params)) {
878 			fprintf(stderr, "Couldn't compute divider for %dHz\n",
879 				clock);
880 			continue;
881 		}
882 
883 		p = params.p0 * params.p1 * params.p2;
884 
885 		/*
886 		 * make sure we respect the +1%/-6% contraint around the
887 		 * central frequency
888 		 */
889 		{
890 			uint64_t dco_freq = (uint64_t)p * clock * 5;
891 			uint64_t central_freq = params.central_freq_hz;
892 			uint64_t deviation;
893 			uint64_t diff;
894 
895 			diff = abs_diff(dco_freq, central_freq);
896 			deviation = div64_u64(10000 * diff, central_freq);
897 
898 			igt_stats_push(&stats, deviation);
899 
900 			if (dco_freq > central_freq) {
901 				if (deviation > 100)
902 					printf("failed constraint for %dHz "
903 					       "deviation=%"PRIu64"\n", clock,
904 					       deviation);
905 			} else if (deviation > 600)
906 				printf("failed constraint for %dHz "
907 				       "deviation=%"PRIu64"\n", clock,
908 				       deviation);
909 		}
910 
911 		/*
912 		 * count how many even/odd dividers we have through the whole
913 		 * list of tested frequencies
914 		 */
915 		{
916 			p_odd_even[p % 2]++;
917 		}
918 	}
919 
920 	printf("even/odd dividers: %d/%d\n", p_odd_even[0], p_odd_even[1]);
921 	printf("mean central freq deviation: %.2lf\n",
922 	       igt_stats_get_mean(&stats));
923 
924 	igt_stats_fini(&stats);
925 }
926 
main(int argc,char ** argv)927 int main(int argc, char **argv)
928 {
929 	unsigned int t;
930 
931 	test_multipliers();
932 
933 	for (t = 0; t < ARRAY_SIZE(tests); t++) {
934 		printf("=== Testing algorithm #%d\n", t + 1);
935 		test_run(&tests[t]);
936 	}
937 
938 
939 	return 0;
940 }
941