1/* program the MAVEN in monitor mode */
2
3/* Authors:
4   Mark Watson 6/2000,
5   Rudolf Cornelissen 1/2003-5/2006
6
7   Thanx to Petr Vandrovec for writing matroxfb.
8*/
9
10#define MODULE_BIT 0x00001000
11
12#include "mga_std.h"
13
14status_t g450_g550_maven_set_vid_pll(display_mode target);
15status_t g100_g400max_maven_set_vid_pll(display_mode target);
16
17/* This routine blanks the first 'line' below the screen used if there's memory left
18 * to place it in. This will prevent overscanning rubbish on the MAVEN DAC, but only
19 * if no screen using virtual height is setup.
20 * In the rare event the mode and overlay use up so much RAM there's not enough room
21 * left for one blank line, you will get overscanning rubbish from the overlay as it
22 * will overwrite the blank line placed here.
23 * This 'rectangle fill' is done in software because not all modes are supported by
24 * the acc engine.
25 * This function exists to partly overcome a G400 MAVEN hardware design fault, which
26 * influences output in both monitor and TVout modes. The fault is that the MAVEN
27 * keeps repeatedly displaying the last 8 pixels fetched from memory until fetching
28 * restarts after a vertical retrace.
29 * In order to let the maven fetch black pixels, an extra line has to be added to its
30 * CRTC timing. This line needs to be entirely filled black, so with zeros. This line
31 * will be displayed as last visible line, and the last 8 pixels of it will be
32 * repeated during vertical retrace.
33 * Note that the overscanning rubbish can be suppressed in TVout modes by extending
34 * the vertical sync pulse all the way 'to the end'. */
35status_t gx00_maven_clrline()
36{
37	uint32 x, screensize, pointer_reservation;
38	uint8* adr;
39
40	/* this function is nolonger needed on G450/G550 cards */
41	if (si->ps.card_type > G400MAX) return B_OK;
42
43	/* checkout space needed for hardcursor (if any) */
44	pointer_reservation = 0;
45	/* MIL 1/2 cards have a seperate buffer for the cursorbitmap inside the DAC */
46	if ((si->ps.card_type >= G100) && si->settings.hardcursor) pointer_reservation = 1024;
47
48	/* calculate actual screensize */
49	screensize = si->fbc.bytes_per_row * si->dm.virtual_height;
50
51	/* check if there's room left for a full blank line following the actual screen */
52	if ((screensize + si->fbc.bytes_per_row + pointer_reservation) <=
53		(si->ps.memory_size * 1024 * 1024))
54	{
55		LOG(4,("MAVEN: clearing line directly below screen\n"));
56
57		/* calculate first adress beyond actual screen */
58		adr = (uint8*)si->fbc.frame_buffer;
59		adr += screensize;
60		/* clear the line */
61		for (x = 0; x < si->fbc.bytes_per_row; x++)
62		{
63			*(adr + x) = 0x00;
64		}
65	}
66	else
67		LOG(4,("MAVEN: not clearing line directly below screen: no memory left\n"));
68
69	return B_OK;
70}
71
72status_t gx00_maven_dpms(bool display, bool h, bool v)
73{
74	/* this function is nolonger needed on G450/G550 cards */
75	if (si->ps.card_type > G400MAX) return B_OK;
76
77	if (display && h && v)
78	{
79		/* turn on screen */
80		if (!(si->dm.flags & TV_BITS))
81		{
82			/* monitor mode */
83			MAVW(MONEN, 0xb2);
84			MAVW(MONSET, 0x20);		/* must be set to this in monitor mode */
85			MAVW(OUTMODE, 0x03);	/* output: monitor mode */
86			MAVW(STABLE, 0x22);		/* makes picture stable? */
87			MAVW(TEST, 0x00);		/* turn off test signal */
88		}
89		else
90		{
91			/* TVout mode */
92			MAVW(MONEN, 0xb3);
93			MAVW(MONSET, 0x20);
94			MAVW(OUTMODE, 0x08);	/* output: SVideo/Composite */
95			MAVW(STABLE, 0x02);		/* makes picture stable? */
96			//fixme? linux uses 0x14...
97			MAVW(TEST, (MAVR(TEST) & 0x10));
98		}
99	}
100	else
101	{
102		/* turn off screen using a few methods! */
103		MAVW(STABLE, 0x6a);
104		MAVW(OUTMODE, 0x00);
105	}
106
107	return B_OK;
108}
109
110/*set a mode line - inputs are in pixels/scanlines*/
111status_t gx00_maven_set_timing(display_mode target)
112{
113	uint8 temp, cnt, offset, loop;
114
115	/* this function is nolonger needed on G450/G550 cards */
116	if (si->ps.card_type > G400MAX) return B_OK;
117
118	LOG(4,("MAVEN: setting timing\n"));
119
120	/*check horizontal timing parameters are to nearest 8 pixels*/
121	if ((target.timing.h_display & 0x07)	|
122		(target.timing.h_sync_start & 0x07)	|
123		(target.timing.h_sync_end & 0x07)	|
124		(target.timing.h_total & 0x07))
125	{
126		LOG(8,("MAVEN: Horizontal timing is not multiples of 8 pixels\n"));
127		return B_ERROR;
128	}
129
130	/*program the MAVEN*/
131	MAVWW(LASTLINEL, target.timing.h_total);
132	MAVWW(HSYNCLENL, (target.timing.h_sync_end - target.timing.h_sync_start));
133	MAVWW(HSYNCSTRL, (target.timing.h_total - target.timing.h_sync_start));
134	MAVWW(HDISPLAYL, ((target.timing.h_total - target.timing.h_sync_start) +
135					   target.timing.h_display));
136	MAVWW(HTOTALL, (target.timing.h_total + 1));
137
138	MAVWW(VSYNCLENL, (target.timing.v_sync_end - target.timing.v_sync_start - 1));
139	MAVWW(VSYNCSTRL, (target.timing.v_total - target.timing.v_sync_start));
140	MAVWW(VDISPLAYL, (target.timing.v_total - 1));
141	MAVWW(VTOTALL, (target.timing.v_total - 1));
142
143	MAVWW(HVIDRSTL, (target.timing.h_total - si->crtc_delay));
144	MAVWW(VVIDRSTL, (target.timing.v_total - 2));
145
146	/* setup HSYNC & VSYNC polarity */
147	LOG(2,("MAVEN: sync polarity: "));
148	temp = MAVR(LUMA);
149
150	/* find out which offset from the 'reset position' we need */
151	switch (((target.timing.flags & B_POSITIVE_HSYNC) >> (29 - 0)) |
152			((target.timing.flags & B_POSITIVE_VSYNC) >> (30 - 1)))
153	{
154	case 0:
155		/* H neg, V neg */
156		LOG(2,("H:neg V:neg\n"));
157		offset = 2;
158		break;
159	case 1:
160		/* H pos, V neg */
161		LOG(2,("H:pos V:neg\n"));
162		offset = 3;
163		break;
164	case 2:
165		/* H neg, V pos */
166		LOG(2,("H:neg V:pos\n"));
167		offset = 1;
168		break;
169	case 3:
170	default:
171		/* H pos, V pos */
172		LOG(2,("H:pos V:pos\n"));
173		offset = 0;
174		break;
175	}
176	/* calculate the number of steps we need to make from the current 'position' */
177	cnt = 0;
178	if ((offset - ((int)si->maven_syncpol_offset)) < 0) cnt = 4;
179	cnt += offset - si->maven_syncpol_offset;
180	/* note the offset from 'reset position' we will have now */
181	si->maven_syncpol_offset = offset;
182
183	/* program the maven: */
184	/* make sure pulse bit is reset */
185	temp &= ~0x20;
186	MAVW(LUMA, temp);
187	snooze(5);
188	/* enable maven sync polarity programming */
189	temp |= 0x10;
190	MAVW(LUMA, temp);
191	snooze(5);
192	/* pulse sync programming bit until we have the polarities we want */
193	for (loop = 0; loop < cnt; loop++)
194	{
195		MAVW(LUMA, (temp | 0x20));
196		snooze(5);
197		MAVW(LUMA, (temp & ~0x20));
198		snooze(5);
199	}
200	/* disable maven sync polarity programming and reset pulse bit */
201	MAVW(LUMA, (temp & ~0x30));
202
203	return B_OK;
204}
205
206/*set the mode, brightness is a value from 0->2 (where 1 is equivalent to direct)*/
207status_t gx00_maven_mode(int mode,float brightness)
208{
209	uint8 luma;
210
211	/* this function is nolonger needed on G450/G550 cards */
212	if (si->ps.card_type > G400MAX) return B_OK;
213
214	/* set luma to a suitable value for brightness */
215	/* assuming 0x0a is a sensible value */
216	/* fixme:
217	 * it looks like b6 and/or b7 determine the luma: just two values possible. */
218	/* NOTE: b4 and b5 have another function, don't set! (sync polarity programming) */
219	luma = (uint8)(0x0a * brightness);
220	if (luma > 0x0f) luma = 0x0f;
221
222	MAVW(LUMA, luma);
223	LOG(4,("MAVEN: LUMA setting - %x\n", luma));
224
225	return B_OK;
226}
227
228void gx00_maven_shutoff()
229{
230	switch (si->ps.card_type)
231	{
232		case G100:
233		case G200:
234		//fixme: see if this works on G400 too:
235		//case G400:
236		//case G400MAX:
237			/* prevents distortions on CRTC1... */
238			MAVW(TEST, 0x03);
239			MAVW(MONEN, 0x00);
240			MAVW(MONSET, 0x00);
241			break;
242		default:
243			break;
244	}
245}
246
247status_t gx00_maven_set_vid_pll(display_mode target)
248{
249	switch (si->ps.card_type)
250	{
251		case G450:
252		case G550:
253			return g450_g550_maven_set_vid_pll(target);
254			break;
255		default:
256			return g100_g400max_maven_set_vid_pll(target);
257			break;
258	}
259	return B_ERROR;
260}
261
262status_t g450_g550_maven_set_vid_pll(display_mode target)
263{
264	uint8 m=0,n=0,p=0;
265	uint time = 0;
266
267	float pix_setting, req_pclk;
268	status_t result;
269
270	req_pclk = (target.timing.pixel_clock)/1000.0;
271	LOG(4,("MAVEN: Setting VID PLL for pixelclock %f\n", req_pclk));
272
273	result = g450_g550_maven_vid_pll_find(target,&pix_setting,&m,&n,&p, 1);
274	if (result != B_OK)
275	{
276		return result;
277	}
278
279	/*reprogram (disable,select,wait for stability,enable)*/
280	CR2W(CTL, (CR2R(CTL) | 0x08)); 					/* disable the VIDPLL */
281	CR2W(CTL, (CR2R(CTL) | 0x06)); 					/* select the VIDPLL */
282	DXIW(VIDPLLM,(m));								/* set m value */
283	DXIW(VIDPLLN,(n));								/* set n value */
284	DXIW(VIDPLLP,(p));								/* set p value */
285
286	/* Wait for the VIDPLL frequency to lock until timeout occurs */
287	while((!(DXIR(VIDPLLSTAT) & 0x40)) & (time <= 2000))
288	{
289		time++;
290		snooze(1);
291	}
292
293	if (time > 2000)
294		LOG(2,("MAVEN: VID PLL frequency not locked!\n"));
295	else
296		LOG(2,("MAVEN: VID PLL frequency locked\n"));
297	CR2W(CTL, (CR2R(CTL) & ~0x08)); 				/* enable the VIDPLL */
298
299	return B_OK;
300}
301
302/* program the video PLL in the MAVEN */
303status_t g100_g400max_maven_set_vid_pll(display_mode target)
304{
305	uint8 m=0,n=0,p=0;
306
307	float pix_setting, req_pclk;
308	status_t result;
309
310	req_pclk = (target.timing.pixel_clock)/1000.0;
311	LOG(4,("MAVEN: Setting VID PLL for pixelclock %f\n", req_pclk));
312
313	result = g100_g400max_maven_vid_pll_find(target,&pix_setting,&m,&n,&p);
314	if (result != B_OK)
315	{
316		return result;
317	}
318
319	/*reprogram (select,wait for stability)*/
320	MAVW(PIXPLLM,(m));								/* set m value */
321	MAVW(PIXPLLN,(n));								/* set n value */
322	MAVW(PIXPLLP,(p | 0x80));						/* set p value enabling PLL */
323
324	/* Wait for the VIDPLL frequency to lock: detection is not possible it seems */
325	snooze(2000);
326
327	LOG(2,("MAVEN: VID PLL frequency should be locked now...\n"));
328
329	return B_OK;
330}
331
332/* find nearest valid video PLL setting */
333status_t g100_g400max_maven_vid_pll_find(
334	display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result)
335{
336	int m = 0, n = 0, p = 0, m_max;
337	float error, error_best = 999999999;
338	int best[3];
339	float f_vco, max_pclk;
340	float req_pclk = target.timing.pixel_clock/1000.0;
341
342	/* determine the max. reference-frequency postscaler setting for the current card */
343	//fixme: check G100 and G200 m_max if possible...
344	switch(si->ps.card_type)
345	{
346	case G100:
347		LOG(4,("MAVEN: G100 restrictions apply\n"));
348		m_max = 32;
349		break;
350	case G200:
351		LOG(4,("MAVEN: G200 restrictions apply\n"));
352		m_max = 32;
353		break;
354	default:
355		LOG(4,("MAVEN: G400/G400MAX restrictions apply\n"));
356		m_max = 32;
357		break;
358	}
359
360	/* determine the max. pixelclock for the current videomode */
361	switch (target.space)
362	{
363		case B_RGB16_LITTLE:
364			max_pclk = si->ps.max_dac2_clock_16;
365			break;
366		case B_RGB32_LITTLE:
367			max_pclk = si->ps.max_dac2_clock_32;
368			break;
369		default:
370			/* use fail-safe value */
371			max_pclk = si->ps.max_dac2_clock_32;
372			break;
373	}
374	/* if some dualhead mode is active, an extra restriction might apply */
375	if ((target.flags & DUALHEAD_BITS) && (target.space == B_RGB32_LITTLE))
376		max_pclk = si->ps.max_dac2_clock_32dh;
377
378	/* Make sure the requested pixelclock is within the PLL's operational limits */
379	/* lower limit is min_video_vco divided by highest postscaler-factor */
380	if (req_pclk < (si->ps.min_video_vco / 8.0))
381	{
382		LOG(4,("MAVEN: clamping vidclock: requested %fMHz, set to %fMHz\n",
383										req_pclk, (float)(si->ps.min_video_vco / 8.0)));
384		req_pclk = (si->ps.min_video_vco / 8.0);
385	}
386	/* upper limit is given by pins in combination with current active mode */
387	if (req_pclk > max_pclk)
388	{
389		LOG(4,("MAVEN: clamping vidclock: requested %fMHz, set to %fMHz\n",
390														req_pclk, (float)max_pclk));
391		req_pclk = max_pclk;
392	}
393
394	/* iterate through all valid PLL postscaler settings */
395	for (p=0x01; p < 0x10; p = p<<1)
396	{
397		/* calculate the needed VCO frequency for this postscaler setting */
398		f_vco = req_pclk * p;
399
400		/* check if this is within range of the VCO specs */
401		if ((f_vco >= si->ps.min_video_vco) && (f_vco <= si->ps.max_video_vco))
402		{
403			/* iterate trough all valid reference-frequency postscaler settings */
404			for (m = 2; m <= m_max; m++)
405			{
406				/* calculate VCO postscaler setting for current setup.. */
407				n = (int)(((f_vco * m) / si->ps.f_ref) + 0.5);
408				/* ..and check for validity */
409				if ((n < 8) || (n > 128))	continue;
410
411				/* find error in frequency this setting gives */
412				error = fabs(req_pclk - (((si->ps.f_ref / m) * n) / p));
413
414				/* note the setting if best yet */
415				if (error < error_best)
416				{
417					error_best = error;
418					best[0]=m;
419					best[1]=n;
420					best[2]=p;
421				}
422			}
423		}
424	}
425
426	/* setup the scalers programming values for found optimum setting */
427	m=best[0] - 1;
428	n=best[1] - 1;
429	p=best[2] - 1;
430
431	/* calc the needed PLL loopbackfilter setting belonging to current VCO speed */
432	f_vco = (si->ps.f_ref / (m + 1)) * (n + 1);
433	LOG(2,("MAVEN: vid VCO frequency found %fMhz\n", f_vco));
434
435	switch(si->ps.card_type)
436	{
437	case G100:
438	case G200:
439		for(;;)
440		{
441			if (f_vco >= 180) {p |= (0x03 << 3); break;};
442			if (f_vco >= 140) {p |= (0x02 << 3); break;};
443			if (f_vco >= 100) {p |= (0x01 << 3); break;};
444			break;
445		}
446		break;
447	default:
448		for(;;)
449		{
450			if (f_vco >= 240) {p |= (0x03 << 3); break;};
451			if (f_vco >= 170) {p |= (0x02 << 3); break;};
452			if (f_vco >= 110) {p |= (0x01 << 3); break;};
453			break;
454		}
455		break;
456	}
457
458	/* return the results */
459	*calc_pclk = f_vco / ((p & 0x07) + 1);
460	*m_result = m;
461	*n_result = n;
462	*p_result = p;
463
464	/* display the found pixelclock values */
465	LOG(2,("MAVEN: vid PLL check: req. %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n",
466		req_pclk, *calc_pclk, *m_result, *n_result, *p_result));
467
468	return B_OK;
469}
470
471static status_t gx50_maven_check_vid_pll(uint8 m, uint8 n, uint8 p)
472{
473	uint time = 0, count = 0;
474
475	/* reprogram (disable,select,wait for stability,enable) */
476	CR2W(CTL, (CR2R(CTL) | 0x06)); 					/* select the VIDPLL */
477	DXIW(VIDPLLM,(m));								/* set m value */
478	DXIW(VIDPLLN,(n));								/* set n value */
479	DXIW(VIDPLLP,(p));								/* set p value */
480
481	/* give the PLL 1mS at least to get a lock */
482	time = 0;
483	while((!(DXIR(VIDPLLSTAT) & 0x40)) & (time <= 1000))
484	{
485		time++;
486		snooze(1);
487	}
488
489	/* no lock aquired, not useable */
490	if (time > 1000) return B_ERROR;
491
492	/* check if lock holds for at least 90% of the time */
493	for (time = 0, count = 0; time <= 1000; time++)
494	{
495		if(DXIR(VIDPLLSTAT) & 0x40) count++;
496		snooze(1);
497	}
498	/* we have a winner */
499	if (count >= 900) return B_OK;
500
501	/* nogo, the PLL does not stabilize */
502	return B_ERROR;
503}
504
505static status_t gx50_maven_check_vid_pll_range(uint8 m, uint8 n, uint8 *p, uint8 *q)
506{
507	uint8 s=0, p_backup = *p;
508
509	/* preset no candidate, non working setting */
510	*q = 0;
511	/* preset lowest range filter */
512	*p &= 0x47;
513
514	/* iterate through all possible filtersettings */
515	CR2W(CTL, (CR2R(CTL) | 0x08)); /* disable the VIDPLL */
516
517	for (s = 0; s < 8 ;s++)
518	{
519		if (gx50_maven_check_vid_pll(m, n, *p)== B_OK)
520		{
521			/* now check 3 closest lower and higher settings */
522			if ((gx50_maven_check_vid_pll(m, n - 3, *p)== B_OK) &&
523				(gx50_maven_check_vid_pll(m, n - 2, *p)== B_OK) &&
524				(gx50_maven_check_vid_pll(m, n - 1, *p)== B_OK) &&
525				(gx50_maven_check_vid_pll(m, n + 1, *p)== B_OK) &&
526				(gx50_maven_check_vid_pll(m, n + 2, *p)== B_OK) &&
527				(gx50_maven_check_vid_pll(m, n + 3, *p)== B_OK))
528			{
529				LOG(2,("MAVEN: found optimal working VCO filter: #%d\n",s));
530				/* preset first choice setting found */
531				*q = 1;
532				/* we are done */
533				CR2W(CTL, (CR2R(CTL) & ~0x08)); /* enable the VIDPLL */
534				return B_OK;
535			}
536			else
537			{
538				LOG(2,("MAVEN: found critical but working VCO filter: #%d\n",s));
539				/* preset backup setting found */
540				*q = 2;
541				/* remember this setting */
542				p_backup = *p;
543				/* let's continue to see if a better filter exists */
544			}
545		}
546	/* new filtersetting to try */
547	*p += (1 << 3);
548	}
549
550	/* return the (last found) backup result, or the original p value */
551	*p = p_backup;
552	CR2W(CTL, (CR2R(CTL) & ~0x08)); /* enable the VIDPLL */
553	/* we found only a non-optimal value */
554	if (*q == 2) return B_OK;
555
556	/* nothing worked at all */
557	LOG(2,("MAVEN: no working VCO filter found!\n"));
558	return B_ERROR;
559}
560
561/* find nearest valid video PLL setting */
562status_t g450_g550_maven_vid_pll_find
563	(display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result, uint8 test)
564{
565	int m = 0, n = 0;
566	uint8 p = 0, q = 0;
567	float error, error_best = 999999999;
568	int best[3];
569	float f_vco, max_pclk;
570	float req_pclk = target.timing.pixel_clock/1000.0;
571
572	LOG(4,("MAVEN: G450/G550 restrictions apply\n"));
573
574	/* determine the max. pixelclock for the current videomode */
575	switch (target.space)
576	{
577		case B_RGB16_LITTLE:
578			max_pclk = si->ps.max_dac2_clock_16;
579			break;
580		case B_RGB32_LITTLE:
581			max_pclk = si->ps.max_dac2_clock_32;
582			break;
583		default:
584			/* use fail-safe value */
585			max_pclk = si->ps.max_dac2_clock_32;
586			break;
587	}
588	/* if some dualhead mode is active, an extra restriction might apply */
589	if ((target.flags & DUALHEAD_BITS) && (target.space == B_RGB32_LITTLE))
590		max_pclk = si->ps.max_dac2_clock_32dh;
591
592	/* Make sure the requested pixelclock is within the PLL's operational limits */
593	/* lower limit is min_pixel_vco divided by highest postscaler-factor */
594	if (req_pclk < (si->ps.min_video_vco / 16.0))
595	{
596		LOG(4,("MAVEN: clamping vidclock: requested %fMHz, set to %fMHz\n",
597										req_pclk, (float)(si->ps.min_video_vco / 16.0)));
598		req_pclk = (si->ps.min_video_vco / 16.0);
599	}
600	/* upper limit is given by pins in combination with current active mode */
601	if (req_pclk > max_pclk)
602	{
603		LOG(4,("MAVEN: clamping vidclock: requested %fMHz, set to %fMHz\n",
604														req_pclk, (float)max_pclk));
605		req_pclk = max_pclk;
606	}
607
608	/* iterate through all valid PLL postscaler settings */
609	for (p=0x01; p < 0x20; p = p<<1)
610	{
611		/* calculate the needed VCO frequency for this postscaler setting */
612		f_vco = req_pclk * p;
613
614		/* check if this is within range of the VCO specs */
615		if ((f_vco >= si->ps.min_video_vco) && (f_vco <= si->ps.max_video_vco))
616		{
617			/* iterate trough all valid reference-frequency postscaler settings */
618			for (m = 2; m <= 32; m++)
619			{
620				/* calculate VCO postscaler setting for current setup.. */
621				n = (int)(((f_vco * m) / (si->ps.f_ref * 2)) + 0.5);
622				/* ..and check for validity, BUT:
623				 * Keep in mind that we need to be able to test n-3 ... n+3! */
624				if ((n < (8 + 3)) || (n > (128 - 3)))	continue;
625
626				/* find error in frequency this setting gives */
627				error = fabs(req_pclk - ((((si->ps.f_ref * 2)/ m) * n) / p));
628
629				/* note the setting if best yet */
630				if (error < error_best)
631				{
632					error_best = error;
633					best[0]=m;
634					best[1]=n;
635					best[2]=p;
636				}
637			}
638		}
639	}
640
641	/* setup the scalers programming values for found optimum setting */
642	m=best[0] - 1;
643	n=best[1] - 2;
644	switch(best[2])
645	{
646	case 1:
647		p = 0x40;
648		break;
649	case 2:
650		p = 0x00;
651		break;
652	case 4:
653		p = 0x01;
654		break;
655	case 8:
656		p = 0x02;
657		break;
658	case 16:
659		p = 0x03;
660		break;
661	}
662
663	/* log the closest VCO speed found */
664	f_vco = ((si->ps.f_ref * 2) / (m + 1)) * (n + 2);
665	LOG(2,("MAVEN: vid VCO frequency found %fMhz\n", f_vco));
666
667	/* now find the filtersetting that matches best with this frequency by testing.
668	 * for now we assume this routine succeeds to get us a stable setting */
669	if (test)
670		gx50_maven_check_vid_pll_range(m, n, &p, &q);
671	else
672		LOG(2,("MAVEN: Not testing G450/G550 VCO feedback filters\n"));
673
674	/* return the results */
675	*calc_pclk = f_vco / best[2];
676	*m_result = m;
677	*n_result = n;
678	*p_result = p;
679
680	/* display the found pixelclock values */
681	LOG(2,("MAVEN: vid PLL check: req. %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n",
682		req_pclk, *calc_pclk, *m_result, *n_result, *p_result));
683
684	return B_OK;
685}
686