xref: /openbsd-src/sys/dev/pci/drm/amd/amdgpu/amdgpu_pll.c (revision 1bb76ff151c0aba8e3312a604e4cd2e5195cf4b7)
1fb4d8502Sjsg /*
2fb4d8502Sjsg  * Copyright 2014 Advanced Micro Devices, Inc.
3fb4d8502Sjsg  *
4fb4d8502Sjsg  * Permission is hereby granted, free of charge, to any person obtaining a
5fb4d8502Sjsg  * copy of this software and associated documentation files (the "Software"),
6fb4d8502Sjsg  * to deal in the Software without restriction, including without limitation
7fb4d8502Sjsg  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8fb4d8502Sjsg  * and/or sell copies of the Software, and to permit persons to whom the
9fb4d8502Sjsg  * Software is furnished to do so, subject to the following conditions:
10fb4d8502Sjsg  *
11fb4d8502Sjsg  * The above copyright notice and this permission notice shall be included in
12fb4d8502Sjsg  * all copies or substantial portions of the Software.
13fb4d8502Sjsg  *
14fb4d8502Sjsg  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15fb4d8502Sjsg  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16fb4d8502Sjsg  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17fb4d8502Sjsg  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18fb4d8502Sjsg  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19fb4d8502Sjsg  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20fb4d8502Sjsg  * OTHER DEALINGS IN THE SOFTWARE.
21fb4d8502Sjsg  *
22fb4d8502Sjsg  */
23c349dbc7Sjsg 
24fb4d8502Sjsg #include <drm/amdgpu_drm.h>
25fb4d8502Sjsg #include "amdgpu.h"
26fb4d8502Sjsg #include "atom.h"
27fb4d8502Sjsg #include "atombios_encoders.h"
28fb4d8502Sjsg #include "amdgpu_pll.h"
29fb4d8502Sjsg #include <asm/div64.h>
30fb4d8502Sjsg #include <linux/gcd.h>
31fb4d8502Sjsg 
32fb4d8502Sjsg /**
33fb4d8502Sjsg  * amdgpu_pll_reduce_ratio - fractional number reduction
34fb4d8502Sjsg  *
35fb4d8502Sjsg  * @nom: nominator
36fb4d8502Sjsg  * @den: denominator
37fb4d8502Sjsg  * @nom_min: minimum value for nominator
38fb4d8502Sjsg  * @den_min: minimum value for denominator
39fb4d8502Sjsg  *
40fb4d8502Sjsg  * Find the greatest common divisor and apply it on both nominator and
41fb4d8502Sjsg  * denominator, but make nominator and denominator are at least as large
42fb4d8502Sjsg  * as their minimum values.
43fb4d8502Sjsg  */
amdgpu_pll_reduce_ratio(unsigned * nom,unsigned * den,unsigned nom_min,unsigned den_min)44fb4d8502Sjsg static void amdgpu_pll_reduce_ratio(unsigned *nom, unsigned *den,
45fb4d8502Sjsg 				    unsigned nom_min, unsigned den_min)
46fb4d8502Sjsg {
47fb4d8502Sjsg 	unsigned tmp;
48fb4d8502Sjsg 
49fb4d8502Sjsg 	/* reduce the numbers to a simpler ratio */
50fb4d8502Sjsg 	tmp = gcd(*nom, *den);
51fb4d8502Sjsg 	*nom /= tmp;
52fb4d8502Sjsg 	*den /= tmp;
53fb4d8502Sjsg 
54fb4d8502Sjsg 	/* make sure nominator is large enough */
55fb4d8502Sjsg 	if (*nom < nom_min) {
56fb4d8502Sjsg 		tmp = DIV_ROUND_UP(nom_min, *nom);
57fb4d8502Sjsg 		*nom *= tmp;
58fb4d8502Sjsg 		*den *= tmp;
59fb4d8502Sjsg 	}
60fb4d8502Sjsg 
61fb4d8502Sjsg 	/* make sure the denominator is large enough */
62fb4d8502Sjsg 	if (*den < den_min) {
63fb4d8502Sjsg 		tmp = DIV_ROUND_UP(den_min, *den);
64fb4d8502Sjsg 		*nom *= tmp;
65fb4d8502Sjsg 		*den *= tmp;
66fb4d8502Sjsg 	}
67fb4d8502Sjsg }
68fb4d8502Sjsg 
69fb4d8502Sjsg /**
70fb4d8502Sjsg  * amdgpu_pll_get_fb_ref_div - feedback and ref divider calculation
71fb4d8502Sjsg  *
72*1bb76ff1Sjsg  * @adev: amdgpu_device pointer
73fb4d8502Sjsg  * @nom: nominator
74fb4d8502Sjsg  * @den: denominator
75fb4d8502Sjsg  * @post_div: post divider
76fb4d8502Sjsg  * @fb_div_max: feedback divider maximum
77fb4d8502Sjsg  * @ref_div_max: reference divider maximum
78fb4d8502Sjsg  * @fb_div: resulting feedback divider
79fb4d8502Sjsg  * @ref_div: resulting reference divider
80fb4d8502Sjsg  *
81fb4d8502Sjsg  * Calculate feedback and reference divider for a given post divider. Makes
82fb4d8502Sjsg  * sure we stay within the limits.
83fb4d8502Sjsg  */
amdgpu_pll_get_fb_ref_div(struct amdgpu_device * adev,unsigned int nom,unsigned int den,unsigned int post_div,unsigned int fb_div_max,unsigned int ref_div_max,unsigned int * fb_div,unsigned int * ref_div)845ca02815Sjsg static void amdgpu_pll_get_fb_ref_div(struct amdgpu_device *adev, unsigned int nom,
855ca02815Sjsg 				      unsigned int den, unsigned int post_div,
865ca02815Sjsg 				      unsigned int fb_div_max, unsigned int ref_div_max,
875ca02815Sjsg 				      unsigned int *fb_div, unsigned int *ref_div)
88fb4d8502Sjsg {
895ca02815Sjsg 
90fb4d8502Sjsg 	/* limit reference * post divider to a maximum */
915ca02815Sjsg 	if (adev->family == AMDGPU_FAMILY_SI)
925ca02815Sjsg 		ref_div_max = min(100 / post_div, ref_div_max);
935ca02815Sjsg 	else
94fb4d8502Sjsg 		ref_div_max = min(128 / post_div, ref_div_max);
95fb4d8502Sjsg 
96fb4d8502Sjsg 	/* get matching reference and feedback divider */
97fb4d8502Sjsg 	*ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max);
98fb4d8502Sjsg 	*fb_div = DIV_ROUND_CLOSEST(nom * *ref_div * post_div, den);
99fb4d8502Sjsg 
100fb4d8502Sjsg 	/* limit fb divider to its maximum */
101fb4d8502Sjsg 	if (*fb_div > fb_div_max) {
102fb4d8502Sjsg 		*ref_div = DIV_ROUND_CLOSEST(*ref_div * fb_div_max, *fb_div);
103fb4d8502Sjsg 		*fb_div = fb_div_max;
104fb4d8502Sjsg 	}
105fb4d8502Sjsg }
106fb4d8502Sjsg 
107fb4d8502Sjsg /**
108fb4d8502Sjsg  * amdgpu_pll_compute - compute PLL paramaters
109fb4d8502Sjsg  *
110*1bb76ff1Sjsg  * @adev: amdgpu_device pointer
111fb4d8502Sjsg  * @pll: information about the PLL
1125ca02815Sjsg  * @freq: requested frequency
113fb4d8502Sjsg  * @dot_clock_p: resulting pixel clock
1145ca02815Sjsg  * @fb_div_p: resulting feedback divider
1155ca02815Sjsg  * @frac_fb_div_p: fractional part of the feedback divider
1165ca02815Sjsg  * @ref_div_p: resulting reference divider
1175ca02815Sjsg  * @post_div_p: resulting reference divider
118fb4d8502Sjsg  *
119fb4d8502Sjsg  * Try to calculate the PLL parameters to generate the given frequency:
120fb4d8502Sjsg  * dot_clock = (ref_freq * feedback_div) / (ref_div * post_div)
121fb4d8502Sjsg  */
amdgpu_pll_compute(struct amdgpu_device * adev,struct amdgpu_pll * pll,u32 freq,u32 * dot_clock_p,u32 * fb_div_p,u32 * frac_fb_div_p,u32 * ref_div_p,u32 * post_div_p)1225ca02815Sjsg void amdgpu_pll_compute(struct amdgpu_device *adev,
1235ca02815Sjsg 			struct amdgpu_pll *pll,
124fb4d8502Sjsg 			u32 freq,
125fb4d8502Sjsg 			u32 *dot_clock_p,
126fb4d8502Sjsg 			u32 *fb_div_p,
127fb4d8502Sjsg 			u32 *frac_fb_div_p,
128fb4d8502Sjsg 			u32 *ref_div_p,
129fb4d8502Sjsg 			u32 *post_div_p)
130fb4d8502Sjsg {
131fb4d8502Sjsg 	unsigned target_clock = pll->flags & AMDGPU_PLL_USE_FRAC_FB_DIV ?
132fb4d8502Sjsg 		freq : freq / 10;
133fb4d8502Sjsg 
134fb4d8502Sjsg 	unsigned fb_div_min, fb_div_max, fb_div;
135fb4d8502Sjsg 	unsigned post_div_min, post_div_max, post_div;
136fb4d8502Sjsg 	unsigned ref_div_min, ref_div_max, ref_div;
137fb4d8502Sjsg 	unsigned post_div_best, diff_best;
138fb4d8502Sjsg 	unsigned nom, den;
139fb4d8502Sjsg 
140fb4d8502Sjsg 	/* determine allowed feedback divider range */
141fb4d8502Sjsg 	fb_div_min = pll->min_feedback_div;
142fb4d8502Sjsg 	fb_div_max = pll->max_feedback_div;
143fb4d8502Sjsg 
144fb4d8502Sjsg 	if (pll->flags & AMDGPU_PLL_USE_FRAC_FB_DIV) {
145fb4d8502Sjsg 		fb_div_min *= 10;
146fb4d8502Sjsg 		fb_div_max *= 10;
147fb4d8502Sjsg 	}
148fb4d8502Sjsg 
149fb4d8502Sjsg 	/* determine allowed ref divider range */
150fb4d8502Sjsg 	if (pll->flags & AMDGPU_PLL_USE_REF_DIV)
151fb4d8502Sjsg 		ref_div_min = pll->reference_div;
152fb4d8502Sjsg 	else
153fb4d8502Sjsg 		ref_div_min = pll->min_ref_div;
154fb4d8502Sjsg 
155fb4d8502Sjsg 	if (pll->flags & AMDGPU_PLL_USE_FRAC_FB_DIV &&
156fb4d8502Sjsg 	    pll->flags & AMDGPU_PLL_USE_REF_DIV)
157fb4d8502Sjsg 		ref_div_max = pll->reference_div;
158fb4d8502Sjsg 	else
159fb4d8502Sjsg 		ref_div_max = pll->max_ref_div;
160fb4d8502Sjsg 
161fb4d8502Sjsg 	/* determine allowed post divider range */
162fb4d8502Sjsg 	if (pll->flags & AMDGPU_PLL_USE_POST_DIV) {
163fb4d8502Sjsg 		post_div_min = pll->post_div;
164fb4d8502Sjsg 		post_div_max = pll->post_div;
165fb4d8502Sjsg 	} else {
166fb4d8502Sjsg 		unsigned vco_min, vco_max;
167fb4d8502Sjsg 
168fb4d8502Sjsg 		if (pll->flags & AMDGPU_PLL_IS_LCD) {
169fb4d8502Sjsg 			vco_min = pll->lcd_pll_out_min;
170fb4d8502Sjsg 			vco_max = pll->lcd_pll_out_max;
171fb4d8502Sjsg 		} else {
172fb4d8502Sjsg 			vco_min = pll->pll_out_min;
173fb4d8502Sjsg 			vco_max = pll->pll_out_max;
174fb4d8502Sjsg 		}
175fb4d8502Sjsg 
176fb4d8502Sjsg 		if (pll->flags & AMDGPU_PLL_USE_FRAC_FB_DIV) {
177fb4d8502Sjsg 			vco_min *= 10;
178fb4d8502Sjsg 			vco_max *= 10;
179fb4d8502Sjsg 		}
180fb4d8502Sjsg 
181fb4d8502Sjsg 		post_div_min = vco_min / target_clock;
182fb4d8502Sjsg 		if ((target_clock * post_div_min) < vco_min)
183fb4d8502Sjsg 			++post_div_min;
184fb4d8502Sjsg 		if (post_div_min < pll->min_post_div)
185fb4d8502Sjsg 			post_div_min = pll->min_post_div;
186fb4d8502Sjsg 
187fb4d8502Sjsg 		post_div_max = vco_max / target_clock;
188fb4d8502Sjsg 		if ((target_clock * post_div_max) > vco_max)
189fb4d8502Sjsg 			--post_div_max;
190fb4d8502Sjsg 		if (post_div_max > pll->max_post_div)
191fb4d8502Sjsg 			post_div_max = pll->max_post_div;
192fb4d8502Sjsg 	}
193fb4d8502Sjsg 
194fb4d8502Sjsg 	/* represent the searched ratio as fractional number */
195fb4d8502Sjsg 	nom = target_clock;
196fb4d8502Sjsg 	den = pll->reference_freq;
197fb4d8502Sjsg 
198fb4d8502Sjsg 	/* reduce the numbers to a simpler ratio */
199fb4d8502Sjsg 	amdgpu_pll_reduce_ratio(&nom, &den, fb_div_min, post_div_min);
200fb4d8502Sjsg 
201fb4d8502Sjsg 	/* now search for a post divider */
202fb4d8502Sjsg 	if (pll->flags & AMDGPU_PLL_PREFER_MINM_OVER_MAXP)
203fb4d8502Sjsg 		post_div_best = post_div_min;
204fb4d8502Sjsg 	else
205fb4d8502Sjsg 		post_div_best = post_div_max;
206fb4d8502Sjsg 	diff_best = ~0;
207fb4d8502Sjsg 
208fb4d8502Sjsg 	for (post_div = post_div_min; post_div <= post_div_max; ++post_div) {
209fb4d8502Sjsg 		unsigned diff;
2105ca02815Sjsg 		amdgpu_pll_get_fb_ref_div(adev, nom, den, post_div, fb_div_max,
211fb4d8502Sjsg 					  ref_div_max, &fb_div, &ref_div);
212fb4d8502Sjsg 		diff = abs(target_clock - (pll->reference_freq * fb_div) /
213fb4d8502Sjsg 			(ref_div * post_div));
214fb4d8502Sjsg 
215fb4d8502Sjsg 		if (diff < diff_best || (diff == diff_best &&
216fb4d8502Sjsg 		    !(pll->flags & AMDGPU_PLL_PREFER_MINM_OVER_MAXP))) {
217fb4d8502Sjsg 
218fb4d8502Sjsg 			post_div_best = post_div;
219fb4d8502Sjsg 			diff_best = diff;
220fb4d8502Sjsg 		}
221fb4d8502Sjsg 	}
222fb4d8502Sjsg 	post_div = post_div_best;
223fb4d8502Sjsg 
224fb4d8502Sjsg 	/* get the feedback and reference divider for the optimal value */
2255ca02815Sjsg 	amdgpu_pll_get_fb_ref_div(adev, nom, den, post_div, fb_div_max, ref_div_max,
226fb4d8502Sjsg 				  &fb_div, &ref_div);
227fb4d8502Sjsg 
228fb4d8502Sjsg 	/* reduce the numbers to a simpler ratio once more */
229fb4d8502Sjsg 	/* this also makes sure that the reference divider is large enough */
230fb4d8502Sjsg 	amdgpu_pll_reduce_ratio(&fb_div, &ref_div, fb_div_min, ref_div_min);
231fb4d8502Sjsg 
232fb4d8502Sjsg 	/* avoid high jitter with small fractional dividers */
233fb4d8502Sjsg 	if (pll->flags & AMDGPU_PLL_USE_FRAC_FB_DIV && (fb_div % 10)) {
234fb4d8502Sjsg 		fb_div_min = max(fb_div_min, (9 - (fb_div % 10)) * 20 + 60);
235fb4d8502Sjsg 		if (fb_div < fb_div_min) {
236fb4d8502Sjsg 			unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div);
237fb4d8502Sjsg 			fb_div *= tmp;
238fb4d8502Sjsg 			ref_div *= tmp;
239fb4d8502Sjsg 		}
240fb4d8502Sjsg 	}
241fb4d8502Sjsg 
242fb4d8502Sjsg 	/* and finally save the result */
243fb4d8502Sjsg 	if (pll->flags & AMDGPU_PLL_USE_FRAC_FB_DIV) {
244fb4d8502Sjsg 		*fb_div_p = fb_div / 10;
245fb4d8502Sjsg 		*frac_fb_div_p = fb_div % 10;
246fb4d8502Sjsg 	} else {
247fb4d8502Sjsg 		*fb_div_p = fb_div;
248fb4d8502Sjsg 		*frac_fb_div_p = 0;
249fb4d8502Sjsg 	}
250fb4d8502Sjsg 
251fb4d8502Sjsg 	*dot_clock_p = ((pll->reference_freq * *fb_div_p * 10) +
252fb4d8502Sjsg 			(pll->reference_freq * *frac_fb_div_p)) /
253fb4d8502Sjsg 		       (ref_div * post_div * 10);
254fb4d8502Sjsg 	*ref_div_p = ref_div;
255fb4d8502Sjsg 	*post_div_p = post_div;
256fb4d8502Sjsg 
257fb4d8502Sjsg 	DRM_DEBUG_KMS("%d - %d, pll dividers - fb: %d.%d ref: %d, post %d\n",
258fb4d8502Sjsg 		      freq, *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p,
259fb4d8502Sjsg 		      ref_div, post_div);
260fb4d8502Sjsg }
261fb4d8502Sjsg 
262fb4d8502Sjsg /**
263fb4d8502Sjsg  * amdgpu_pll_get_use_mask - look up a mask of which pplls are in use
264fb4d8502Sjsg  *
265fb4d8502Sjsg  * @crtc: drm crtc
266fb4d8502Sjsg  *
267fb4d8502Sjsg  * Returns the mask of which PPLLs (Pixel PLLs) are in use.
268fb4d8502Sjsg  */
amdgpu_pll_get_use_mask(struct drm_crtc * crtc)269fb4d8502Sjsg u32 amdgpu_pll_get_use_mask(struct drm_crtc *crtc)
270fb4d8502Sjsg {
271fb4d8502Sjsg 	struct drm_device *dev = crtc->dev;
272fb4d8502Sjsg 	struct drm_crtc *test_crtc;
273fb4d8502Sjsg 	struct amdgpu_crtc *test_amdgpu_crtc;
274fb4d8502Sjsg 	u32 pll_in_use = 0;
275fb4d8502Sjsg 
276fb4d8502Sjsg 	list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
277fb4d8502Sjsg 		if (crtc == test_crtc)
278fb4d8502Sjsg 			continue;
279fb4d8502Sjsg 
280fb4d8502Sjsg 		test_amdgpu_crtc = to_amdgpu_crtc(test_crtc);
281fb4d8502Sjsg 		if (test_amdgpu_crtc->pll_id != ATOM_PPLL_INVALID)
282fb4d8502Sjsg 			pll_in_use |= (1 << test_amdgpu_crtc->pll_id);
283fb4d8502Sjsg 	}
284fb4d8502Sjsg 	return pll_in_use;
285fb4d8502Sjsg }
286fb4d8502Sjsg 
287fb4d8502Sjsg /**
288fb4d8502Sjsg  * amdgpu_pll_get_shared_dp_ppll - return the PPLL used by another crtc for DP
289fb4d8502Sjsg  *
290fb4d8502Sjsg  * @crtc: drm crtc
291fb4d8502Sjsg  *
292fb4d8502Sjsg  * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is
293fb4d8502Sjsg  * also in DP mode.  For DP, a single PPLL can be used for all DP
294fb4d8502Sjsg  * crtcs/encoders.
295fb4d8502Sjsg  */
amdgpu_pll_get_shared_dp_ppll(struct drm_crtc * crtc)296fb4d8502Sjsg int amdgpu_pll_get_shared_dp_ppll(struct drm_crtc *crtc)
297fb4d8502Sjsg {
298fb4d8502Sjsg 	struct drm_device *dev = crtc->dev;
299fb4d8502Sjsg 	struct drm_crtc *test_crtc;
300fb4d8502Sjsg 	struct amdgpu_crtc *test_amdgpu_crtc;
301fb4d8502Sjsg 
302fb4d8502Sjsg 	list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
303fb4d8502Sjsg 		if (crtc == test_crtc)
304fb4d8502Sjsg 			continue;
305fb4d8502Sjsg 		test_amdgpu_crtc = to_amdgpu_crtc(test_crtc);
306fb4d8502Sjsg 		if (test_amdgpu_crtc->encoder &&
307fb4d8502Sjsg 		    ENCODER_MODE_IS_DP(amdgpu_atombios_encoder_get_encoder_mode(test_amdgpu_crtc->encoder))) {
308fb4d8502Sjsg 			/* for DP use the same PLL for all */
309fb4d8502Sjsg 			if (test_amdgpu_crtc->pll_id != ATOM_PPLL_INVALID)
310fb4d8502Sjsg 				return test_amdgpu_crtc->pll_id;
311fb4d8502Sjsg 		}
312fb4d8502Sjsg 	}
313fb4d8502Sjsg 	return ATOM_PPLL_INVALID;
314fb4d8502Sjsg }
315fb4d8502Sjsg 
316fb4d8502Sjsg /**
317fb4d8502Sjsg  * amdgpu_pll_get_shared_nondp_ppll - return the PPLL used by another non-DP crtc
318fb4d8502Sjsg  *
319fb4d8502Sjsg  * @crtc: drm crtc
320fb4d8502Sjsg  *
321fb4d8502Sjsg  * Returns the PPLL (Pixel PLL) used by another non-DP crtc/encoder which can
322fb4d8502Sjsg  * be shared (i.e., same clock).
323fb4d8502Sjsg  */
amdgpu_pll_get_shared_nondp_ppll(struct drm_crtc * crtc)324fb4d8502Sjsg int amdgpu_pll_get_shared_nondp_ppll(struct drm_crtc *crtc)
325fb4d8502Sjsg {
326fb4d8502Sjsg 	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
327fb4d8502Sjsg 	struct drm_device *dev = crtc->dev;
328fb4d8502Sjsg 	struct drm_crtc *test_crtc;
329fb4d8502Sjsg 	struct amdgpu_crtc *test_amdgpu_crtc;
330fb4d8502Sjsg 	u32 adjusted_clock, test_adjusted_clock;
331fb4d8502Sjsg 
332fb4d8502Sjsg 	adjusted_clock = amdgpu_crtc->adjusted_clock;
333fb4d8502Sjsg 
334fb4d8502Sjsg 	if (adjusted_clock == 0)
335fb4d8502Sjsg 		return ATOM_PPLL_INVALID;
336fb4d8502Sjsg 
337fb4d8502Sjsg 	list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
338fb4d8502Sjsg 		if (crtc == test_crtc)
339fb4d8502Sjsg 			continue;
340fb4d8502Sjsg 		test_amdgpu_crtc = to_amdgpu_crtc(test_crtc);
341fb4d8502Sjsg 		if (test_amdgpu_crtc->encoder &&
342fb4d8502Sjsg 		    !ENCODER_MODE_IS_DP(amdgpu_atombios_encoder_get_encoder_mode(test_amdgpu_crtc->encoder))) {
343fb4d8502Sjsg 			/* check if we are already driving this connector with another crtc */
344fb4d8502Sjsg 			if (test_amdgpu_crtc->connector == amdgpu_crtc->connector) {
345fb4d8502Sjsg 				/* if we are, return that pll */
346fb4d8502Sjsg 				if (test_amdgpu_crtc->pll_id != ATOM_PPLL_INVALID)
347fb4d8502Sjsg 					return test_amdgpu_crtc->pll_id;
348fb4d8502Sjsg 			}
349fb4d8502Sjsg 			/* for non-DP check the clock */
350fb4d8502Sjsg 			test_adjusted_clock = test_amdgpu_crtc->adjusted_clock;
351fb4d8502Sjsg 			if ((crtc->mode.clock == test_crtc->mode.clock) &&
352fb4d8502Sjsg 			    (adjusted_clock == test_adjusted_clock) &&
353fb4d8502Sjsg 			    (amdgpu_crtc->ss_enabled == test_amdgpu_crtc->ss_enabled) &&
354fb4d8502Sjsg 			    (test_amdgpu_crtc->pll_id != ATOM_PPLL_INVALID))
355fb4d8502Sjsg 				return test_amdgpu_crtc->pll_id;
356fb4d8502Sjsg 		}
357fb4d8502Sjsg 	}
358fb4d8502Sjsg 	return ATOM_PPLL_INVALID;
359fb4d8502Sjsg }
360