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, ¶ms)) {
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