xref: /aosp_15_r20/external/igt-gpu-tools/tools/cnl_compute_wrpll.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2017 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*d83cc019SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  */
23*d83cc019SAndroid Build Coastguard Worker 
24*d83cc019SAndroid Build Coastguard Worker #include <assert.h>
25*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
26*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
27*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
28*d83cc019SAndroid Build Coastguard Worker #include <stdint.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
30*d83cc019SAndroid Build Coastguard Worker #include <string.h>
31*d83cc019SAndroid Build Coastguard Worker #include <math.h>
32*d83cc019SAndroid Build Coastguard Worker 
33*d83cc019SAndroid Build Coastguard Worker #define U32_MAX         ((uint32_t)~0ULL)
34*d83cc019SAndroid Build Coastguard Worker #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
35*d83cc019SAndroid Build Coastguard Worker 
div_u64(uint64_t dividend,uint32_t divisor)36*d83cc019SAndroid Build Coastguard Worker static inline uint64_t div_u64(uint64_t dividend, uint32_t divisor)
37*d83cc019SAndroid Build Coastguard Worker {
38*d83cc019SAndroid Build Coastguard Worker 	return dividend / divisor;
39*d83cc019SAndroid Build Coastguard Worker }
40*d83cc019SAndroid Build Coastguard Worker 
41*d83cc019SAndroid Build Coastguard Worker struct skl_wrpll_params {
42*d83cc019SAndroid Build Coastguard Worker 	uint32_t dco_fraction;
43*d83cc019SAndroid Build Coastguard Worker 	uint32_t dco_integer;
44*d83cc019SAndroid Build Coastguard Worker 	uint32_t qdiv_ratio;
45*d83cc019SAndroid Build Coastguard Worker 	uint32_t qdiv_mode;
46*d83cc019SAndroid Build Coastguard Worker 	uint32_t kdiv;
47*d83cc019SAndroid Build Coastguard Worker 	uint32_t pdiv;
48*d83cc019SAndroid Build Coastguard Worker 
49*d83cc019SAndroid Build Coastguard Worker 	/* for this test code only */
50*d83cc019SAndroid Build Coastguard Worker 	unsigned int ref_clock;
51*d83cc019SAndroid Build Coastguard Worker } __attribute__((packed));
52*d83cc019SAndroid Build Coastguard Worker 
dump_params(const char * name,struct skl_wrpll_params * params)53*d83cc019SAndroid Build Coastguard Worker static void dump_params(const char *name, struct skl_wrpll_params *params)
54*d83cc019SAndroid Build Coastguard Worker {
55*d83cc019SAndroid Build Coastguard Worker 	printf("%s:\n", name);
56*d83cc019SAndroid Build Coastguard Worker 	printf("Pdiv: %d\n", params->pdiv);
57*d83cc019SAndroid Build Coastguard Worker 	printf("Qdiv: %d\n", params->qdiv_ratio);
58*d83cc019SAndroid Build Coastguard Worker 	printf("Kdiv: %d\n", params->kdiv);
59*d83cc019SAndroid Build Coastguard Worker 	printf("qdiv mode: %d\n", params->qdiv_mode);
60*d83cc019SAndroid Build Coastguard Worker 	printf("dco integer: %d\n", params->dco_integer);
61*d83cc019SAndroid Build Coastguard Worker 	printf("dco fraction: %d\n", params->dco_fraction);
62*d83cc019SAndroid Build Coastguard Worker }
63*d83cc019SAndroid Build Coastguard Worker 
compare_params(unsigned int clock,const char * name1,struct skl_wrpll_params * p1,const char * name2,struct skl_wrpll_params * p2)64*d83cc019SAndroid Build Coastguard Worker static void compare_params(unsigned int clock,
65*d83cc019SAndroid Build Coastguard Worker 			   const char *name1, struct skl_wrpll_params *p1,
66*d83cc019SAndroid Build Coastguard Worker 			   const char *name2, struct skl_wrpll_params *p2)
67*d83cc019SAndroid Build Coastguard Worker {
68*d83cc019SAndroid Build Coastguard Worker 	if (memcmp(p1, p2, sizeof(struct skl_wrpll_params)) == 0)
69*d83cc019SAndroid Build Coastguard Worker 		return;
70*d83cc019SAndroid Build Coastguard Worker 
71*d83cc019SAndroid Build Coastguard Worker 	printf("=======================================\n");
72*d83cc019SAndroid Build Coastguard Worker 	printf("Difference with clock: %10.6f MHz\n", clock/1000000.0);
73*d83cc019SAndroid Build Coastguard Worker 	printf("Reference clock:       %10.6f MHz\n\n", p1->ref_clock/1000.0);
74*d83cc019SAndroid Build Coastguard Worker 	dump_params(name1, p1);
75*d83cc019SAndroid Build Coastguard Worker 	printf("\n");
76*d83cc019SAndroid Build Coastguard Worker 	dump_params(name2, p2);
77*d83cc019SAndroid Build Coastguard Worker 	printf("=======================================\n");
78*d83cc019SAndroid Build Coastguard Worker }
79*d83cc019SAndroid Build Coastguard Worker 
cnl_wrpll_params_populate(struct skl_wrpll_params * params,uint32_t dco_freq,uint32_t ref_freq,uint32_t pdiv,uint32_t qdiv,uint32_t kdiv)80*d83cc019SAndroid Build Coastguard Worker static void cnl_wrpll_params_populate(struct skl_wrpll_params *params,
81*d83cc019SAndroid Build Coastguard Worker 				      uint32_t dco_freq, uint32_t ref_freq,
82*d83cc019SAndroid Build Coastguard Worker 				      uint32_t pdiv, uint32_t qdiv,
83*d83cc019SAndroid Build Coastguard Worker 				      uint32_t kdiv)
84*d83cc019SAndroid Build Coastguard Worker {
85*d83cc019SAndroid Build Coastguard Worker 	uint32_t dco;
86*d83cc019SAndroid Build Coastguard Worker 
87*d83cc019SAndroid Build Coastguard Worker 	params->qdiv_ratio = qdiv;
88*d83cc019SAndroid Build Coastguard Worker 	params->qdiv_mode = (qdiv == 1) ? 0 : 1;
89*d83cc019SAndroid Build Coastguard Worker 	params->pdiv = pdiv;
90*d83cc019SAndroid Build Coastguard Worker 	params->kdiv = kdiv;
91*d83cc019SAndroid Build Coastguard Worker 
92*d83cc019SAndroid Build Coastguard Worker 	if (kdiv != 2 && qdiv != 1)
93*d83cc019SAndroid Build Coastguard Worker 		printf("kdiv != 2 and qdiv != 1\n");
94*d83cc019SAndroid Build Coastguard Worker 
95*d83cc019SAndroid Build Coastguard Worker 	dco = div_u64((uint64_t)dco_freq << 15, ref_freq);
96*d83cc019SAndroid Build Coastguard Worker 
97*d83cc019SAndroid Build Coastguard Worker 	params->dco_integer = dco >> 15;
98*d83cc019SAndroid Build Coastguard Worker 	params->dco_fraction = dco & 0x7fff;
99*d83cc019SAndroid Build Coastguard Worker }
100*d83cc019SAndroid Build Coastguard Worker 
cnl_wrpll_get_multipliers(int bestdiv,int * pdiv,int * qdiv,int * kdiv)101*d83cc019SAndroid Build Coastguard Worker static void cnl_wrpll_get_multipliers(int bestdiv,
102*d83cc019SAndroid Build Coastguard Worker 				      int *pdiv,
103*d83cc019SAndroid Build Coastguard Worker 				      int *qdiv,
104*d83cc019SAndroid Build Coastguard Worker 				      int *kdiv)
105*d83cc019SAndroid Build Coastguard Worker {
106*d83cc019SAndroid Build Coastguard Worker 	/* even dividers */
107*d83cc019SAndroid Build Coastguard Worker 	if (bestdiv % 2 == 0) {
108*d83cc019SAndroid Build Coastguard Worker 		if (bestdiv == 2) {
109*d83cc019SAndroid Build Coastguard Worker 			*pdiv = 2;
110*d83cc019SAndroid Build Coastguard Worker 			*qdiv = 1;
111*d83cc019SAndroid Build Coastguard Worker 			*kdiv = 1;
112*d83cc019SAndroid Build Coastguard Worker 		} else if (bestdiv % 4 == 0) {
113*d83cc019SAndroid Build Coastguard Worker 			*pdiv = 2;
114*d83cc019SAndroid Build Coastguard Worker 			*qdiv = bestdiv / 4;
115*d83cc019SAndroid Build Coastguard Worker 			*kdiv = 2;
116*d83cc019SAndroid Build Coastguard Worker 		} else if (bestdiv % 6 == 0) {
117*d83cc019SAndroid Build Coastguard Worker 			*pdiv = 3;
118*d83cc019SAndroid Build Coastguard Worker 			*qdiv = bestdiv / 6;
119*d83cc019SAndroid Build Coastguard Worker 			*kdiv = 2;
120*d83cc019SAndroid Build Coastguard Worker 		} else if (bestdiv % 5 == 0) {
121*d83cc019SAndroid Build Coastguard Worker 			*pdiv = 5;
122*d83cc019SAndroid Build Coastguard Worker 			*qdiv = bestdiv / 10;
123*d83cc019SAndroid Build Coastguard Worker 			*kdiv = 2;
124*d83cc019SAndroid Build Coastguard Worker 		} else if (bestdiv % 14 == 0) {
125*d83cc019SAndroid Build Coastguard Worker 			*pdiv = 7;
126*d83cc019SAndroid Build Coastguard Worker 			*qdiv = bestdiv / 14;
127*d83cc019SAndroid Build Coastguard Worker 			*kdiv = 2;
128*d83cc019SAndroid Build Coastguard Worker 		}
129*d83cc019SAndroid Build Coastguard Worker 	} else {
130*d83cc019SAndroid Build Coastguard Worker 		if (bestdiv == 3 || bestdiv == 5 || bestdiv == 7) {
131*d83cc019SAndroid Build Coastguard Worker 			*pdiv = bestdiv;
132*d83cc019SAndroid Build Coastguard Worker 			*qdiv = 1;
133*d83cc019SAndroid Build Coastguard Worker 			*kdiv = 1;
134*d83cc019SAndroid Build Coastguard Worker 		} else { /* 9, 15, 21 */
135*d83cc019SAndroid Build Coastguard Worker 			*pdiv = bestdiv / 3;
136*d83cc019SAndroid Build Coastguard Worker 			*qdiv = 1;
137*d83cc019SAndroid Build Coastguard Worker 			*kdiv = 3;
138*d83cc019SAndroid Build Coastguard Worker 		}
139*d83cc019SAndroid Build Coastguard Worker 	}
140*d83cc019SAndroid Build Coastguard Worker }
141*d83cc019SAndroid Build Coastguard Worker 
142*d83cc019SAndroid Build Coastguard Worker static bool
cnl_ddi_calculate_wrpll1(int clock,struct skl_wrpll_params * params)143*d83cc019SAndroid Build Coastguard Worker cnl_ddi_calculate_wrpll1(int clock /* in Hz */,
144*d83cc019SAndroid Build Coastguard Worker 			 struct skl_wrpll_params *params)
145*d83cc019SAndroid Build Coastguard Worker {
146*d83cc019SAndroid Build Coastguard Worker 	double afe_clock = (clock/1000000.0) * 5; /* clocks in MHz */
147*d83cc019SAndroid Build Coastguard Worker 	double dco_min = 7998;
148*d83cc019SAndroid Build Coastguard Worker 	double dco_max = 10000;
149*d83cc019SAndroid Build Coastguard Worker 	double dco_mid = (dco_min + dco_max) / 2;
150*d83cc019SAndroid Build Coastguard Worker 	static const int dividers[] = {  2,  4,  6,  8, 10, 12,  14,  16,
151*d83cc019SAndroid Build Coastguard Worker 					 18, 20, 24, 28, 30, 32,  36,  40,
152*d83cc019SAndroid Build Coastguard Worker 					 42, 44, 48, 50, 52, 54,  56,  60,
153*d83cc019SAndroid Build Coastguard Worker 					 64, 66, 68, 70, 72, 76,  78,  80,
154*d83cc019SAndroid Build Coastguard Worker 					 84, 88, 90, 92, 96, 98, 100, 102,
155*d83cc019SAndroid Build Coastguard Worker 					 3,  5,  7,  9, 15, 21 };
156*d83cc019SAndroid Build Coastguard Worker 	double dco, dco_centrality = 0;
157*d83cc019SAndroid Build Coastguard Worker 	double best_dco_centrality = 999999;
158*d83cc019SAndroid Build Coastguard Worker 	int d, best_div = 0, pdiv = 0, qdiv = 0, kdiv = 0;
159*d83cc019SAndroid Build Coastguard Worker 	double ref_clock = params->ref_clock/1000.0; /* MHz */
160*d83cc019SAndroid Build Coastguard Worker 	uint32_t dco_int, dco_frac;
161*d83cc019SAndroid Build Coastguard Worker 
162*d83cc019SAndroid Build Coastguard Worker 	for (d = 0; d < ARRAY_SIZE(dividers); d++) {
163*d83cc019SAndroid Build Coastguard Worker 		dco = afe_clock * dividers[d];
164*d83cc019SAndroid Build Coastguard Worker 
165*d83cc019SAndroid Build Coastguard Worker 		if ((dco <= dco_max) && (dco >= dco_min)) {
166*d83cc019SAndroid Build Coastguard Worker 			dco_centrality = fabs(dco - dco_mid);
167*d83cc019SAndroid Build Coastguard Worker 
168*d83cc019SAndroid Build Coastguard Worker 			if (dco_centrality < best_dco_centrality) {
169*d83cc019SAndroid Build Coastguard Worker 				best_dco_centrality = dco_centrality;
170*d83cc019SAndroid Build Coastguard Worker 				best_div = dividers[d];
171*d83cc019SAndroid Build Coastguard Worker 				dco_int = (uint32_t)(dco/ref_clock);
172*d83cc019SAndroid Build Coastguard Worker 				dco_frac = round((dco/ref_clock - dco_int) * (1<<15));
173*d83cc019SAndroid Build Coastguard Worker 			}
174*d83cc019SAndroid Build Coastguard Worker 		}
175*d83cc019SAndroid Build Coastguard Worker 	}
176*d83cc019SAndroid Build Coastguard Worker 
177*d83cc019SAndroid Build Coastguard Worker 	if (best_div != 0) {
178*d83cc019SAndroid Build Coastguard Worker 		cnl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv);
179*d83cc019SAndroid Build Coastguard Worker 
180*d83cc019SAndroid Build Coastguard Worker 		params->qdiv_ratio = qdiv;
181*d83cc019SAndroid Build Coastguard Worker 		params->qdiv_mode = (qdiv == 1) ? 0 : 1;
182*d83cc019SAndroid Build Coastguard Worker 		params->pdiv = pdiv;
183*d83cc019SAndroid Build Coastguard Worker 		params->kdiv = kdiv;
184*d83cc019SAndroid Build Coastguard Worker 		params->dco_integer = dco_int;
185*d83cc019SAndroid Build Coastguard Worker 		params->dco_fraction = dco_frac;
186*d83cc019SAndroid Build Coastguard Worker 	} else {
187*d83cc019SAndroid Build Coastguard Worker 		return false;
188*d83cc019SAndroid Build Coastguard Worker 	}
189*d83cc019SAndroid Build Coastguard Worker 
190*d83cc019SAndroid Build Coastguard Worker 	return true;
191*d83cc019SAndroid Build Coastguard Worker }
192*d83cc019SAndroid Build Coastguard Worker 
193*d83cc019SAndroid Build Coastguard Worker static bool
cnl_ddi_calculate_wrpll2(int clock,struct skl_wrpll_params * params)194*d83cc019SAndroid Build Coastguard Worker cnl_ddi_calculate_wrpll2(int clock,
195*d83cc019SAndroid Build Coastguard Worker 			 struct skl_wrpll_params *params)
196*d83cc019SAndroid Build Coastguard Worker {
197*d83cc019SAndroid Build Coastguard Worker 	uint32_t afe_clock = clock * 5 / 1000; /* clock in kHz */
198*d83cc019SAndroid Build Coastguard Worker 	uint32_t dco_min = 7998000;
199*d83cc019SAndroid Build Coastguard Worker 	uint32_t dco_max = 10000000;
200*d83cc019SAndroid Build Coastguard Worker 	uint32_t dco_mid = (dco_min + dco_max) / 2;
201*d83cc019SAndroid Build Coastguard Worker 	static const int dividers[] = {  2,  4,  6,  8, 10, 12,  14,  16,
202*d83cc019SAndroid Build Coastguard Worker 					 18, 20, 24, 28, 30, 32,  36,  40,
203*d83cc019SAndroid Build Coastguard Worker 					 42, 44, 48, 50, 52, 54,  56,  60,
204*d83cc019SAndroid Build Coastguard Worker 					 64, 66, 68, 70, 72, 76,  78,  80,
205*d83cc019SAndroid Build Coastguard Worker 					 84, 88, 90, 92, 96, 98, 100, 102,
206*d83cc019SAndroid Build Coastguard Worker 					  3,  5,  7,  9, 15, 21 };
207*d83cc019SAndroid Build Coastguard Worker 	uint32_t dco, best_dco = 0, dco_centrality = 0;
208*d83cc019SAndroid Build Coastguard Worker 	uint32_t best_dco_centrality = U32_MAX; /* Spec meaning of 999999 MHz */
209*d83cc019SAndroid Build Coastguard Worker 	int d, best_div = 0, pdiv = 0, qdiv = 0, kdiv = 0;
210*d83cc019SAndroid Build Coastguard Worker 	uint32_t ref_clock = params->ref_clock;
211*d83cc019SAndroid Build Coastguard Worker 
212*d83cc019SAndroid Build Coastguard Worker 	for (d = 0; d < ARRAY_SIZE(dividers); d++) {
213*d83cc019SAndroid Build Coastguard Worker 		dco = afe_clock * dividers[d];
214*d83cc019SAndroid Build Coastguard Worker 
215*d83cc019SAndroid Build Coastguard Worker 		if ((dco <= dco_max) && (dco >= dco_min)) {
216*d83cc019SAndroid Build Coastguard Worker 			dco_centrality = abs(dco - dco_mid);
217*d83cc019SAndroid Build Coastguard Worker 
218*d83cc019SAndroid Build Coastguard Worker 			if (dco_centrality < best_dco_centrality) {
219*d83cc019SAndroid Build Coastguard Worker 				best_dco_centrality = dco_centrality;
220*d83cc019SAndroid Build Coastguard Worker 				best_div = dividers[d];
221*d83cc019SAndroid Build Coastguard Worker 				best_dco = dco;
222*d83cc019SAndroid Build Coastguard Worker 			}
223*d83cc019SAndroid Build Coastguard Worker 		}
224*d83cc019SAndroid Build Coastguard Worker 	}
225*d83cc019SAndroid Build Coastguard Worker 
226*d83cc019SAndroid Build Coastguard Worker 	if (best_div == 0)
227*d83cc019SAndroid Build Coastguard Worker 		return false;
228*d83cc019SAndroid Build Coastguard Worker 
229*d83cc019SAndroid Build Coastguard Worker 	cnl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv);
230*d83cc019SAndroid Build Coastguard Worker 
231*d83cc019SAndroid Build Coastguard Worker 	cnl_wrpll_params_populate(params, best_dco, ref_clock,
232*d83cc019SAndroid Build Coastguard Worker 				  pdiv, qdiv, kdiv);
233*d83cc019SAndroid Build Coastguard Worker 
234*d83cc019SAndroid Build Coastguard Worker 	return true;
235*d83cc019SAndroid Build Coastguard Worker }
236*d83cc019SAndroid Build Coastguard Worker 
test_multipliers(unsigned int clock)237*d83cc019SAndroid Build Coastguard Worker static void test_multipliers(unsigned int clock)
238*d83cc019SAndroid Build Coastguard Worker {
239*d83cc019SAndroid Build Coastguard Worker 	uint64_t afe_clock = clock * 5 / 1000; /* clocks in kHz */
240*d83cc019SAndroid Build Coastguard Worker 	unsigned int dco_min = 7998000;
241*d83cc019SAndroid Build Coastguard Worker 	unsigned int dco_max = 10000000;
242*d83cc019SAndroid Build Coastguard Worker 	unsigned int dco_mid = (dco_min + dco_max) / 2;
243*d83cc019SAndroid Build Coastguard Worker 
244*d83cc019SAndroid Build Coastguard Worker 	static const int dividerlist[] = {  2,  4,  6,  8, 10, 12,  14,  16,
245*d83cc019SAndroid Build Coastguard Worker 					   18, 20, 24, 28, 30, 32,  36,  40,
246*d83cc019SAndroid Build Coastguard Worker 					   42, 44, 48, 50, 52, 54,  56,  60,
247*d83cc019SAndroid Build Coastguard Worker 					   64, 66, 68, 70, 72, 76,  78,  80,
248*d83cc019SAndroid Build Coastguard Worker 					   84, 88, 90, 92, 96, 98, 100, 102,
249*d83cc019SAndroid Build Coastguard Worker 					    3,  5,  7,  9, 15, 21 };
250*d83cc019SAndroid Build Coastguard Worker 	unsigned int dco, dco_centrality = 0;
251*d83cc019SAndroid Build Coastguard Worker 	unsigned int best_dco_centrality = U32_MAX;
252*d83cc019SAndroid Build Coastguard Worker 	int d, best_div = 0, pdiv = 0, qdiv = 0, kdiv = 0;
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker 	for (d = 0; d < ARRAY_SIZE(dividerlist); d++) {
255*d83cc019SAndroid Build Coastguard Worker 		dco = afe_clock * dividerlist[d];
256*d83cc019SAndroid Build Coastguard Worker 
257*d83cc019SAndroid Build Coastguard Worker 		if ((dco <= dco_max) && (dco >= dco_min)) {
258*d83cc019SAndroid Build Coastguard Worker 			dco_centrality = abs(dco - dco_mid);
259*d83cc019SAndroid Build Coastguard Worker 
260*d83cc019SAndroid Build Coastguard Worker 			if (dco_centrality < best_dco_centrality) {
261*d83cc019SAndroid Build Coastguard Worker 				best_dco_centrality = dco_centrality;
262*d83cc019SAndroid Build Coastguard Worker 				best_div = dividerlist[d];
263*d83cc019SAndroid Build Coastguard Worker 			}
264*d83cc019SAndroid Build Coastguard Worker 		}
265*d83cc019SAndroid Build Coastguard Worker 
266*d83cc019SAndroid Build Coastguard Worker 		if (best_div != 0) {
267*d83cc019SAndroid Build Coastguard Worker 			cnl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv);
268*d83cc019SAndroid Build Coastguard Worker 
269*d83cc019SAndroid Build Coastguard Worker 			if ((kdiv != 2) && (qdiv == 1))
270*d83cc019SAndroid Build Coastguard Worker 				continue;
271*d83cc019SAndroid Build Coastguard Worker 			else
272*d83cc019SAndroid Build Coastguard Worker 				break;
273*d83cc019SAndroid Build Coastguard Worker 		}
274*d83cc019SAndroid Build Coastguard Worker 	}
275*d83cc019SAndroid Build Coastguard Worker 
276*d83cc019SAndroid Build Coastguard Worker 	assert(pdiv);
277*d83cc019SAndroid Build Coastguard Worker 	assert(qdiv);
278*d83cc019SAndroid Build Coastguard Worker 	assert(kdiv);
279*d83cc019SAndroid Build Coastguard Worker 
280*d83cc019SAndroid Build Coastguard Worker 	if (kdiv != 2)
281*d83cc019SAndroid Build Coastguard Worker 		assert(qdiv == 1);
282*d83cc019SAndroid Build Coastguard Worker }
283*d83cc019SAndroid Build Coastguard Worker 
284*d83cc019SAndroid Build Coastguard Worker static const struct {
285*d83cc019SAndroid Build Coastguard Worker 	uint32_t clock; /* in Hz */
286*d83cc019SAndroid Build Coastguard Worker } modes[] = {
287*d83cc019SAndroid Build Coastguard Worker 	{19750000},
288*d83cc019SAndroid Build Coastguard Worker 	{23500000},
289*d83cc019SAndroid Build Coastguard Worker 	{23750000},
290*d83cc019SAndroid Build Coastguard Worker 	{25175000},
291*d83cc019SAndroid Build Coastguard Worker 	{25200000},
292*d83cc019SAndroid Build Coastguard Worker 	{26000000},
293*d83cc019SAndroid Build Coastguard Worker 	{27000000},
294*d83cc019SAndroid Build Coastguard Worker 	{27027000},
295*d83cc019SAndroid Build Coastguard Worker 	{27500000},
296*d83cc019SAndroid Build Coastguard Worker 	{28750000},
297*d83cc019SAndroid Build Coastguard Worker 	{29750000},
298*d83cc019SAndroid Build Coastguard Worker 	{30750000},
299*d83cc019SAndroid Build Coastguard Worker 	{31500000},
300*d83cc019SAndroid Build Coastguard Worker 	{35000000},
301*d83cc019SAndroid Build Coastguard Worker 	{35500000},
302*d83cc019SAndroid Build Coastguard Worker 	{36750000},
303*d83cc019SAndroid Build Coastguard Worker 	{37000000},
304*d83cc019SAndroid Build Coastguard Worker 	{37088000},
305*d83cc019SAndroid Build Coastguard Worker 	{37125000},
306*d83cc019SAndroid Build Coastguard Worker 	{37762500},
307*d83cc019SAndroid Build Coastguard Worker 	{37800000},
308*d83cc019SAndroid Build Coastguard Worker 	{38250000},
309*d83cc019SAndroid Build Coastguard Worker 	{40500000},
310*d83cc019SAndroid Build Coastguard Worker 	{40541000},
311*d83cc019SAndroid Build Coastguard Worker 	{40750000},
312*d83cc019SAndroid Build Coastguard Worker 	{41000000},
313*d83cc019SAndroid Build Coastguard Worker 	{41500000},
314*d83cc019SAndroid Build Coastguard Worker 	{42500000},
315*d83cc019SAndroid Build Coastguard Worker 	{45250000},
316*d83cc019SAndroid Build Coastguard Worker 	{46360000},
317*d83cc019SAndroid Build Coastguard Worker 	{46406000},
318*d83cc019SAndroid Build Coastguard Worker 	{46750000},
319*d83cc019SAndroid Build Coastguard Worker 	{49000000},
320*d83cc019SAndroid Build Coastguard Worker 	{50500000},
321*d83cc019SAndroid Build Coastguard Worker 	{52000000},
322*d83cc019SAndroid Build Coastguard Worker 	{54000000},
323*d83cc019SAndroid Build Coastguard Worker 	{54054000},
324*d83cc019SAndroid Build Coastguard Worker 	{54500000},
325*d83cc019SAndroid Build Coastguard Worker 	{55632000},
326*d83cc019SAndroid Build Coastguard Worker 	{55688000},
327*d83cc019SAndroid Build Coastguard Worker 	{56000000},
328*d83cc019SAndroid Build Coastguard Worker 	{56750000},
329*d83cc019SAndroid Build Coastguard Worker 	{58250000},
330*d83cc019SAndroid Build Coastguard Worker 	{58750000},
331*d83cc019SAndroid Build Coastguard Worker 	{59341000},
332*d83cc019SAndroid Build Coastguard Worker 	{59400000},
333*d83cc019SAndroid Build Coastguard Worker 	{60500000},
334*d83cc019SAndroid Build Coastguard Worker 	{62250000},
335*d83cc019SAndroid Build Coastguard Worker 	{63500000},
336*d83cc019SAndroid Build Coastguard Worker 	{64000000},
337*d83cc019SAndroid Build Coastguard Worker 	{65250000},
338*d83cc019SAndroid Build Coastguard Worker 	{65500000},
339*d83cc019SAndroid Build Coastguard Worker 	{66750000},
340*d83cc019SAndroid Build Coastguard Worker 	{67750000},
341*d83cc019SAndroid Build Coastguard Worker 	{68250000},
342*d83cc019SAndroid Build Coastguard Worker 	{69000000},
343*d83cc019SAndroid Build Coastguard Worker 	{72000000},
344*d83cc019SAndroid Build Coastguard Worker 	{74176000},
345*d83cc019SAndroid Build Coastguard Worker 	{74250000},
346*d83cc019SAndroid Build Coastguard Worker 	{74500000},
347*d83cc019SAndroid Build Coastguard Worker 	{75250000},
348*d83cc019SAndroid Build Coastguard Worker 	{76000000},
349*d83cc019SAndroid Build Coastguard Worker 	{79500000},
350*d83cc019SAndroid Build Coastguard Worker 	{81000000},
351*d83cc019SAndroid Build Coastguard Worker 	{81081000},
352*d83cc019SAndroid Build Coastguard Worker 	{82000000},
353*d83cc019SAndroid Build Coastguard Worker 	{83000000},
354*d83cc019SAndroid Build Coastguard Worker 	{84750000},
355*d83cc019SAndroid Build Coastguard Worker 	{85250000},
356*d83cc019SAndroid Build Coastguard Worker 	{85750000},
357*d83cc019SAndroid Build Coastguard Worker 	{88500000},
358*d83cc019SAndroid Build Coastguard Worker 	{89012000},
359*d83cc019SAndroid Build Coastguard Worker 	{89100000},
360*d83cc019SAndroid Build Coastguard Worker 	{91000000},
361*d83cc019SAndroid Build Coastguard Worker 	{92719800},
362*d83cc019SAndroid Build Coastguard Worker 	{92812500},
363*d83cc019SAndroid Build Coastguard Worker 	{94500000},
364*d83cc019SAndroid Build Coastguard Worker 	{95750000},
365*d83cc019SAndroid Build Coastguard Worker 	{97750000},
366*d83cc019SAndroid Build Coastguard Worker 	{99000000},
367*d83cc019SAndroid Build Coastguard Worker 	{99750000},
368*d83cc019SAndroid Build Coastguard Worker 	{100000000},
369*d83cc019SAndroid Build Coastguard Worker 	{100500000},
370*d83cc019SAndroid Build Coastguard Worker 	{101000000},
371*d83cc019SAndroid Build Coastguard Worker 	{101250000},
372*d83cc019SAndroid Build Coastguard Worker 	{102250000},
373*d83cc019SAndroid Build Coastguard Worker 	{107892000},
374*d83cc019SAndroid Build Coastguard Worker 	{108000000},
375*d83cc019SAndroid Build Coastguard Worker 	{108108000},
376*d83cc019SAndroid Build Coastguard Worker 	{109000000},
377*d83cc019SAndroid Build Coastguard Worker 	{110250000},
378*d83cc019SAndroid Build Coastguard Worker 	{110500000},
379*d83cc019SAndroid Build Coastguard Worker 	{111264000},
380*d83cc019SAndroid Build Coastguard Worker 	{111375000},
381*d83cc019SAndroid Build Coastguard Worker 	{112500000},
382*d83cc019SAndroid Build Coastguard Worker 	{117500000},
383*d83cc019SAndroid Build Coastguard Worker 	{119000000},
384*d83cc019SAndroid Build Coastguard Worker 	{119500000},
385*d83cc019SAndroid Build Coastguard Worker 	{121250000},
386*d83cc019SAndroid Build Coastguard Worker 	{121750000},
387*d83cc019SAndroid Build Coastguard Worker 	{125250000},
388*d83cc019SAndroid Build Coastguard Worker 	{125750000},
389*d83cc019SAndroid Build Coastguard Worker 	{127250000},
390*d83cc019SAndroid Build Coastguard Worker 	{130000000},
391*d83cc019SAndroid Build Coastguard Worker 	{130250000},
392*d83cc019SAndroid Build Coastguard Worker 	{131000000},
393*d83cc019SAndroid Build Coastguard Worker 	{131500000},
394*d83cc019SAndroid Build Coastguard Worker 	{132750000},
395*d83cc019SAndroid Build Coastguard Worker 	{135250000},
396*d83cc019SAndroid Build Coastguard Worker 	{138500000},
397*d83cc019SAndroid Build Coastguard Worker 	{138750000},
398*d83cc019SAndroid Build Coastguard Worker 	{141500000},
399*d83cc019SAndroid Build Coastguard Worker 	{146250000},
400*d83cc019SAndroid Build Coastguard Worker 	{148250000},
401*d83cc019SAndroid Build Coastguard Worker 	{148352000},
402*d83cc019SAndroid Build Coastguard Worker 	{148500000},
403*d83cc019SAndroid Build Coastguard Worker 	{154000000},
404*d83cc019SAndroid Build Coastguard Worker 	{155250000},
405*d83cc019SAndroid Build Coastguard Worker 	{155750000},
406*d83cc019SAndroid Build Coastguard Worker 	{156000000},
407*d83cc019SAndroid Build Coastguard Worker 	{158250000},
408*d83cc019SAndroid Build Coastguard Worker 	{159500000},
409*d83cc019SAndroid Build Coastguard Worker 	{161000000},
410*d83cc019SAndroid Build Coastguard Worker 	{162000000},
411*d83cc019SAndroid Build Coastguard Worker 	{162162000},
412*d83cc019SAndroid Build Coastguard Worker 	{162500000},
413*d83cc019SAndroid Build Coastguard Worker 	{169500000},
414*d83cc019SAndroid Build Coastguard Worker 	{172750000},
415*d83cc019SAndroid Build Coastguard Worker 	{173000000},
416*d83cc019SAndroid Build Coastguard Worker 	{175000000},
417*d83cc019SAndroid Build Coastguard Worker 	{178500000},
418*d83cc019SAndroid Build Coastguard Worker 	{179500000},
419*d83cc019SAndroid Build Coastguard Worker 	{184750000},
420*d83cc019SAndroid Build Coastguard Worker 	{185440000},
421*d83cc019SAndroid Build Coastguard Worker 	{185625000},
422*d83cc019SAndroid Build Coastguard Worker 	{187000000},
423*d83cc019SAndroid Build Coastguard Worker 	{192250000},
424*d83cc019SAndroid Build Coastguard Worker 	{193250000},
425*d83cc019SAndroid Build Coastguard Worker 	{197750000},
426*d83cc019SAndroid Build Coastguard Worker 	{198500000},
427*d83cc019SAndroid Build Coastguard Worker 	{204750000},
428*d83cc019SAndroid Build Coastguard Worker 	{207500000},
429*d83cc019SAndroid Build Coastguard Worker 	{209250000},
430*d83cc019SAndroid Build Coastguard Worker 	{213750000},
431*d83cc019SAndroid Build Coastguard Worker 	{214750000},
432*d83cc019SAndroid Build Coastguard Worker 	{216000000},
433*d83cc019SAndroid Build Coastguard Worker 	{218750000},
434*d83cc019SAndroid Build Coastguard Worker 	{219000000},
435*d83cc019SAndroid Build Coastguard Worker 	{220750000},
436*d83cc019SAndroid Build Coastguard Worker 	{222525000},
437*d83cc019SAndroid Build Coastguard Worker 	{222750000},
438*d83cc019SAndroid Build Coastguard Worker 	{227000000},
439*d83cc019SAndroid Build Coastguard Worker 	{230250000},
440*d83cc019SAndroid Build Coastguard Worker 	{233500000},
441*d83cc019SAndroid Build Coastguard Worker 	{235000000},
442*d83cc019SAndroid Build Coastguard Worker 	{238000000},
443*d83cc019SAndroid Build Coastguard Worker 	{241500000},
444*d83cc019SAndroid Build Coastguard Worker 	{243000000},
445*d83cc019SAndroid Build Coastguard Worker 	{245250000},
446*d83cc019SAndroid Build Coastguard Worker 	{247750000},
447*d83cc019SAndroid Build Coastguard Worker 	{253250000},
448*d83cc019SAndroid Build Coastguard Worker 	{256250000},
449*d83cc019SAndroid Build Coastguard Worker 	{262500000},
450*d83cc019SAndroid Build Coastguard Worker 	{267250000},
451*d83cc019SAndroid Build Coastguard Worker 	{268500000},
452*d83cc019SAndroid Build Coastguard Worker 	{270000000},
453*d83cc019SAndroid Build Coastguard Worker 	{272500000},
454*d83cc019SAndroid Build Coastguard Worker 	{273750000},
455*d83cc019SAndroid Build Coastguard Worker 	{280750000},
456*d83cc019SAndroid Build Coastguard Worker 	{281250000},
457*d83cc019SAndroid Build Coastguard Worker 	{286000000},
458*d83cc019SAndroid Build Coastguard Worker 	{291750000},
459*d83cc019SAndroid Build Coastguard Worker 	{296703000},
460*d83cc019SAndroid Build Coastguard Worker 	{297000000},
461*d83cc019SAndroid Build Coastguard Worker 	{298000000},
462*d83cc019SAndroid Build Coastguard Worker 	{303750000},
463*d83cc019SAndroid Build Coastguard Worker 	{322250000},
464*d83cc019SAndroid Build Coastguard Worker 	{324000000},
465*d83cc019SAndroid Build Coastguard Worker 	{337750000},
466*d83cc019SAndroid Build Coastguard Worker 	{370878750},
467*d83cc019SAndroid Build Coastguard Worker 	{371250000},
468*d83cc019SAndroid Build Coastguard Worker 	{373250000},
469*d83cc019SAndroid Build Coastguard Worker 	{414500000},
470*d83cc019SAndroid Build Coastguard Worker 	{432000000},
471*d83cc019SAndroid Build Coastguard Worker 	{445054500},
472*d83cc019SAndroid Build Coastguard Worker 	{445500000},
473*d83cc019SAndroid Build Coastguard Worker 	{497750000},
474*d83cc019SAndroid Build Coastguard Worker 	{533250000},
475*d83cc019SAndroid Build Coastguard Worker 	{540000000},
476*d83cc019SAndroid Build Coastguard Worker 	{592500000},
477*d83cc019SAndroid Build Coastguard Worker 	{594000000},
478*d83cc019SAndroid Build Coastguard Worker 	{648000000},
479*d83cc019SAndroid Build Coastguard Worker 	{810000000},
480*d83cc019SAndroid Build Coastguard Worker };
481*d83cc019SAndroid Build Coastguard Worker 
test_run(unsigned int ref_clock)482*d83cc019SAndroid Build Coastguard Worker static void test_run(unsigned int ref_clock)
483*d83cc019SAndroid Build Coastguard Worker {
484*d83cc019SAndroid Build Coastguard Worker 	unsigned int m;
485*d83cc019SAndroid Build Coastguard Worker 	struct skl_wrpll_params params[2];
486*d83cc019SAndroid Build Coastguard Worker 
487*d83cc019SAndroid Build Coastguard Worker 	for (m = 0; m < ARRAY_SIZE(modes); m++) {
488*d83cc019SAndroid Build Coastguard Worker 		int clock = modes[m].clock;
489*d83cc019SAndroid Build Coastguard Worker 		bool skip = false;
490*d83cc019SAndroid Build Coastguard Worker 
491*d83cc019SAndroid Build Coastguard Worker 		params[0].ref_clock = params[1].ref_clock = ref_clock;
492*d83cc019SAndroid Build Coastguard Worker 
493*d83cc019SAndroid Build Coastguard Worker 		if (!cnl_ddi_calculate_wrpll1(clock, &params[0])) {
494*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr, "Reference: Couldn't compute divider for %dHz, reference %dHz\n",
495*d83cc019SAndroid Build Coastguard Worker 				clock, params[0].ref_clock*1000);
496*d83cc019SAndroid Build Coastguard Worker 			skip = true;
497*d83cc019SAndroid Build Coastguard Worker 		}
498*d83cc019SAndroid Build Coastguard Worker 
499*d83cc019SAndroid Build Coastguard Worker 		if (!skip) {
500*d83cc019SAndroid Build Coastguard Worker 			if (!cnl_ddi_calculate_wrpll2(clock, &params[1])) {
501*d83cc019SAndroid Build Coastguard Worker 				fprintf(stderr, "i915 implementation: Couldn't compute divider for %dHz, reference %dHz\n",
502*d83cc019SAndroid Build Coastguard Worker 					clock, params[1].ref_clock*1000);
503*d83cc019SAndroid Build Coastguard Worker 			}
504*d83cc019SAndroid Build Coastguard Worker 
505*d83cc019SAndroid Build Coastguard Worker 			compare_params(clock, "Reference", &params[0],
506*d83cc019SAndroid Build Coastguard Worker 				       "i915 implementation", &params[1]);
507*d83cc019SAndroid Build Coastguard Worker 		}
508*d83cc019SAndroid Build Coastguard Worker 	}
509*d83cc019SAndroid Build Coastguard Worker }
510*d83cc019SAndroid Build Coastguard Worker 
main(int argc,char ** argv)511*d83cc019SAndroid Build Coastguard Worker int main(int argc, char **argv)
512*d83cc019SAndroid Build Coastguard Worker {
513*d83cc019SAndroid Build Coastguard Worker 	unsigned int m;
514*d83cc019SAndroid Build Coastguard Worker 	unsigned int f;
515*d83cc019SAndroid Build Coastguard Worker 	unsigned int ref_clocks[] = {19200, 24000}; /* in kHz */
516*d83cc019SAndroid Build Coastguard Worker 
517*d83cc019SAndroid Build Coastguard Worker 	for (m = 0; m < ARRAY_SIZE(modes); m++)
518*d83cc019SAndroid Build Coastguard Worker 		test_multipliers(modes[m].clock);
519*d83cc019SAndroid Build Coastguard Worker 
520*d83cc019SAndroid Build Coastguard Worker 	for (f = 0; f < ARRAY_SIZE(ref_clocks); f++) {
521*d83cc019SAndroid Build Coastguard Worker 		printf("=== Testing with ref clock %d kHz\n", ref_clocks[f]);
522*d83cc019SAndroid Build Coastguard Worker 		test_run(ref_clocks[f]);
523*d83cc019SAndroid Build Coastguard Worker 	}
524*d83cc019SAndroid Build Coastguard Worker 
525*d83cc019SAndroid Build Coastguard Worker 	return 0;
526*d83cc019SAndroid Build Coastguard Worker }
527