xref: /haiku/src/add-ons/accelerants/nvidia/engine/nv_brooktreetv.c (revision 6245f19cbe9c8e1261601233ad91c226b64c0981)
1 /*
2 	Author:
3 	Rudolf Cornelissen 4/2002-10/2005
4 */
5 
6 #define MODULE_BIT 0x00100000
7 
8 #include "nv_std.h"
9 
10 #define PRADR	0x88
11 #define SCADR	0x8a
12 #define WR		0x00
13 #define RD		0x01
14 
15 enum
16 {	// TVoutput mode to set
17 	NOT_SUPPORTED = 0,
18 	NTSC640_TST,
19 	NTSC640,
20 	NTSC800,
21 	PAL800_TST,
22 	PAL640,
23 	PAL800,
24 	NTSC720,
25 	PAL720,
26 	NTSC640_OS,
27 	PAL800_OS
28 };
29 
30 /* Dirk Thierbach's Macro setup for registers 0xda-0xfe.
31  * (also see http://sourceforge.net/projects/nv-tv-out/) */
32 static uint8 BtNtscMacro0 [] = {
33   0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09,
34   0xbd,0x67,0xb5,0x90,0xb2,0x7d,0x00,0x00};
35 static uint8 BtNtscMacro1 [] = {
36   0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09,
37   0xbd,0x67,0xb5,0x90,0xb2,0x7d,0x63,0x00};
38 static uint8 BtNtscMacro2 [] = {
39   0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09,
40   0xbd,0x6c,0x31,0x92,0x32,0xdd,0xe3,0x00};
41 static uint8 BtNtscMacro3 [] = {
42   0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09,
43   0xbd,0x66,0xb5,0x90,0xb2,0x7d,0xe3,0x00};
44 
45 static uint8 BtPalMacro0 [] = {
46   0x05,0x57,0x20,0x40,0x6e,0x7e,0xf4,0x51,0x0f,0xf1,0x05,
47   0xd3,0x78,0xa2,0x25,0x54,0xa5,0x00,0x00};
48 static uint8 BtPalMacro1 [] = {
49   0x05,0x57,0x20,0x40,0x6e,0x7e,0xf4,0x51,0x0f,0xf1,0x05,
50   0xd3,0x78,0xa2,0x25,0x54,0xa5,0x63,0x00};
51 
52 static uint8 BT_set_macro (int std, int mode)
53 {
54 	uint8 stat;
55 	uint8 buffer[21];
56 
57 	LOG(4,("Brooktree: Setting Macro:\n"));
58 
59 	if ((std < 0) | (std > 1) | (mode < 0) | (mode > 3))
60 	{
61 		LOG(4,("Brooktree: Non existing mode or standard selected, aborting.\n"));
62 		return 0x80;
63 	}
64 
65 	switch (std)
66 	{
67 	case 0:
68 		/* NTSC */
69 		switch (mode)
70 		{
71 		case 0:
72 			/* disabled */
73 			LOG(4,("Brooktree: NTSC, disabled\n"));
74 			memcpy(&buffer[2], &BtNtscMacro0, 19);
75 			break;
76 		case 1:
77 			/* enabled mode 1 */
78 			LOG(4,("Brooktree: NTSC, mode 1\n"));
79 			memcpy(&buffer[2], &BtNtscMacro1, 19);
80 			break;
81 		case 2:
82 			/* enabled mode 2 */
83 			LOG(4,("Brooktree: NTSC, mode 2\n"));
84 			memcpy(&buffer[2], &BtNtscMacro2, 19);
85 			break;
86 		case 3:
87 			/* enabled mode 3 */
88 			LOG(4,("Brooktree: NTSC, mode 3\n"));
89 			memcpy(&buffer[2], &BtNtscMacro3, 19);
90 			break;
91 		}
92 		break;
93 	case 1:
94 		/* PAL */
95 		switch (mode)
96 		{
97 		case 0:
98 			/* disabled */
99 			LOG(4,("Brooktree: PAL, disabled\n"));
100 			memcpy(&buffer[2], &BtPalMacro0, 19);
101 			break;
102 		case 1:
103 		case 2:
104 		case 3:
105 			/* enabled */
106 			LOG(4,("Brooktree: PAL, enabled\n"));
107 			memcpy(&buffer[2], &BtPalMacro1, 19);
108 			break;
109 		}
110 		break;
111 	}
112 
113 	buffer[0] = si->ps.tv_encoder.adress + WR;
114 	/* select first register to write to */
115 	buffer[1] = 0xda;
116 
117 	/* reset status */
118 	i2c_flag_error (-1);
119 
120 	i2c_bstart(si->ps.tv_encoder.bus);
121 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
122 	i2c_bstop(si->ps.tv_encoder.bus);
123 	/* log on errors */
124 	stat = i2c_flag_error(0);
125 	if (stat)
126 		LOG(4,("Brooktree: I2C errors occurred while setting Macro\n"));
127 
128 	return stat;
129 }//end BT_set_macro.
130 
131 /*
132  see if a (possible) BT/CX chip resides at the given adress.
133  Return zero if no errors occurred.
134 */
135 static uint8 BT_check (uint8 bus, uint8 adress)
136 {
137 	uint8 buffer[3];
138 
139 	buffer[0] = adress + WR;
140 	/* set ESTATUS at b'00'; and enable bt chip-outputs
141 	 * WARNING:
142 	 * If bit0 = 0 is issued below (EN_OUT = disabled), the BT will lock SDA
143 	 * after writing adress $A0 (setting EN_XCLK)!!!
144 	 * Until a reboot the corresponding I2C bus will be inacessable then!!! */
145 	buffer[1] = 0xc4;
146 	/* fixme: if testimage 'was' active txbuffer[3] should become 0x05...
147 	 * (currently this cannot be detected in a 'foolproof' way so don't touch...) */
148 	/* (ESTATUS b'0x' means: RX ID and VERSION info later..) */
149 	buffer[2] = 0x01;
150 
151 	/* reset status */
152 	i2c_flag_error (-1);
153 
154 	/* do check */
155 	i2c_bstart(bus);
156 	i2c_writebuffer(bus, buffer, sizeof(buffer));
157 	i2c_bstop(bus);
158 	return i2c_flag_error(0);
159 }
160 
161 /* identify chiptype */
162 static uint8 BT_read_type (void)
163 {
164 	uint8 id, type, stat;
165 	uint8 buffer[3];
166 
167 	/* Make sure a CX (Conexant) chip (if this turns out to be there) is set to
168 	 * BT-compatibility mode! (This command will do nothing on a BT chip...) */
169 	buffer[0] = si->ps.tv_encoder.adress + WR;
170 	/* select CX reg. for BT-compatible readback, video still off */
171 	buffer[1] = 0x6c;
172 	/* set it up */
173 	buffer[2] = 0x02;
174 
175 	/* reset status */
176 	i2c_flag_error (-1);
177 
178 	i2c_bstart(si->ps.tv_encoder.bus);
179 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
180 	i2c_bstop(si->ps.tv_encoder.bus);
181 	/* abort on errors */
182 	stat = i2c_flag_error(0);
183 	if (stat) return stat;
184 
185 	/* Do actual readtype command */
186 	i2c_bstart(si->ps.tv_encoder.bus);
187 	/* issue I2C read command */
188 	i2c_writebyte(si->ps.tv_encoder.bus, si->ps.tv_encoder.adress + RD);
189 	/* receive 1 byte;
190 	 * ACK level to TX after last byte to RX should be 1 (= NACK) (see I2C spec). */
191 	/* note:
192 	 * While the BT's don't care, CX chips will block the SDA line if
193 	 * an ACK gets sent! */
194 	id = i2c_readbyte(si->ps.tv_encoder.bus, true);
195 	i2c_bstop(si->ps.tv_encoder.bus);
196 	/* abort on errors */
197 	stat = i2c_flag_error(0);
198 	if (stat) return stat;
199 
200 	/* check type to be supported one */
201 	type = (id & 0xe0) >> 5;
202 	if (type > 3)
203 	{
204 		LOG(4,("Brooktree: Found unsupported encoder type %d, aborting.\n", type));
205 		return 0x80;
206 	}
207 
208 	/* inform driver about TV encoder found */
209 	si->ps.tvout = true;
210 	si->ps.tv_encoder.type = BT868 + type;
211 	si->ps.tv_encoder.version = id & 0x1f;
212 
213 	return stat;
214 }
215 
216 bool BT_probe()
217 {
218 	bool btfound = false;
219 
220 	LOG(4,("Brooktree: Checking I2C bus(ses) for first possible TV encoder...\n"));
221 	if (si->ps.i2c_bus0)
222 	{
223 		/* try primary adress on bus 0 */
224 		if (!BT_check(0, PRADR))
225 		{
226 			btfound = true;
227 			si->ps.tv_encoder.adress = PRADR;
228 			si->ps.tv_encoder.bus = 0;
229 		}
230 		else
231 		{
232 			/* try secondary adress on bus 0 */
233 			if (!BT_check(0, SCADR))
234 			{
235 				btfound = true;
236 				si->ps.tv_encoder.adress = SCADR;
237 				si->ps.tv_encoder.bus = 0;
238 			}
239 		}
240 	}
241 
242 	if (si->ps.i2c_bus1 && !btfound)
243 	{
244 		/* try primary adress on bus 1 */
245 		if (!BT_check(1, PRADR))
246 		{
247 			btfound = true;
248 			si->ps.tv_encoder.adress = PRADR;
249 			si->ps.tv_encoder.bus = 1;
250 		}
251 		else
252 		{
253 			/* try secondary adress on bus 1 */
254 			if (!BT_check(1, SCADR))
255 			{
256 				btfound = true;
257 				si->ps.tv_encoder.adress = SCADR;
258 				si->ps.tv_encoder.bus = 1;
259 			}
260 		}
261 	}
262 
263 	/* identify exact TV encoder type */
264 	if (btfound)
265 	{
266 		/* if errors are found, retry */
267 		/* note:
268 		 * NACK: occurs on some ASUS V7700 GeForce cards!
269 		 * (apparantly the video-in chip or another chip resides at 'BT' adresses
270 		 * there..) */
271 		uint8 stat;
272 		uint8 cnt = 0;
273 		while ((stat = BT_read_type()) && (cnt < 3))
274 		{
275 			/* don't retry on unsupported chiptype */
276 			if (stat == 0x80)
277 			{
278 				btfound = 0;
279 				break;
280 			}
281 			cnt++;
282 		}
283 		if (stat & 0x7f)
284 		{
285 			LOG(4,("Brooktree: Too much errors occurred, aborting.\n"));
286 			btfound = 0;
287 		}
288 	}
289 
290 	if (btfound)
291 		LOG(4,("Brooktree: Found TV encoder on bus %d, adress $%02x\n",
292 			si->ps.tv_encoder.bus, si->ps.tv_encoder.adress));
293 	else
294 		LOG(4,("Brooktree: No TV encoder Found\n"));
295 
296 	return btfound;
297 }
298 
299 static uint8 BT_init_PAL640()
300 {
301 	uint8 stat;
302 
303 	uint8 buffer[35];
304 
305 	LOG(4,("Brooktree: Setting PAL 640x480 desktop mode\n"));
306 
307 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
308 	buffer[1] = 0x76;			//select first bt register to write to
309 	buffer[2] = 0x60;
310 	buffer[3] = 0x80;
311 	buffer[4] = 0x8a;
312 	buffer[5] = 0xa6;
313 	buffer[6] = 0x68;
314 	buffer[7] = 0xc1;
315 	buffer[8] = 0x2e;
316 	buffer[9] = 0xf2;
317 	buffer[10] = 0x27;
318 	buffer[11] = 0x00;
319 	buffer[12] = 0xb0;
320 	buffer[13] = 0x0a;
321 	buffer[14] = 0x0b;
322 	buffer[15] = 0x71;
323 	buffer[16] = 0x5a;
324 	buffer[17] = 0xe0;
325 	buffer[18] = 0x36;
326 	buffer[19] = 0x00;
327 	buffer[20] = 0x50;
328 	buffer[21] = 0x72;
329 	buffer[22] = 0x1c;
330 	buffer[23] = 0x8d;		//chip-pin CLKI is pixel clock (only non-default here!)
331 	buffer[24] = 0x24;
332 	buffer[25] = 0xf0;
333 	buffer[26] = 0x58;
334 	buffer[27] = 0x81;
335 	buffer[28] = 0x49;
336 	buffer[29] = 0x8c;
337 	buffer[30] = 0x0c;
338 	buffer[31] = 0x8c;
339 	buffer[32] = 0x79;
340 	buffer[33] = 0x26;
341 	buffer[34] = 0x00;
342 
343 	/* reset status */
344 	i2c_flag_error (-1);
345 
346 	i2c_bstart(si->ps.tv_encoder.bus);
347 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
348 	i2c_bstop(si->ps.tv_encoder.bus);
349 	/* log on errors */
350 	stat = i2c_flag_error(0);
351 	if (stat)
352 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL640\n"));
353 
354 	return stat;
355 }//end BT_init_PAL640.
356 
357 static uint8 BT_init_PAL800()
358 {
359 	uint8 stat;
360 
361 	uint8 buffer[35];
362 
363 	LOG(4,("Brooktree: Setting PAL 800x600 desktop mode\n"));
364 
365 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
366 	buffer[1] = 0x76;			//select first bt register to write to
367 	buffer[2] = 0x00;
368 	buffer[3] = 0x20;
369 	buffer[4] = 0xaa;
370 	buffer[5] = 0xca;
371 	buffer[6] = 0x9a;
372 	buffer[7] = 0x0d;
373 	buffer[8] = 0x29;
374 	buffer[9] = 0xfc;
375 	buffer[10] = 0x39;
376 	buffer[11] = 0x00;
377 	buffer[12] = 0xc0;
378 	buffer[13] = 0x8c;
379 	buffer[14] = 0x03;
380 	buffer[15] = 0xee;
381 	buffer[16] = 0x5f;
382 	buffer[17] = 0x58;
383 	buffer[18] = 0x3a;
384 	buffer[19] = 0x66;
385 	buffer[20] = 0x96;
386 	buffer[21] = 0x00;
387 	buffer[22] = 0x00;
388 	buffer[23] = 0x90;		//chip-pin CLKI is pixel clock (only non-default here!)
389 	buffer[24] = 0x24;
390 	buffer[25] = 0xf0;
391 	buffer[26] = 0x57;
392 	buffer[27] = 0x80;
393 	buffer[28] = 0x48;
394 	buffer[29] = 0x8c;
395 	buffer[30] = 0x18;
396 	buffer[31] = 0x28;
397 	buffer[32] = 0x87;
398 	buffer[33] = 0x1f;
399 	buffer[34] = 0x00;
400 
401 	/* reset status */
402 	i2c_flag_error (-1);
403 
404 	i2c_bstart(si->ps.tv_encoder.bus);
405 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
406 	i2c_bstop(si->ps.tv_encoder.bus);
407 	/* log on errors */
408 	stat = i2c_flag_error(0);
409 	if (stat)
410 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n"));
411 
412 	return stat;
413 }//end BT_init_PAL800.
414 
415 static uint8 BT_init_NTSC640()
416 {
417 	uint8 stat;
418 
419 	uint8 buffer[35];
420 
421 	LOG(4,("Brooktree: Setting NTSC 640x480 desktop mode\n"));
422 
423 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
424 	buffer[1] = 0x76;			//select first bt register to write to
425 	buffer[2] = 0x00;
426 	buffer[3] = 0x80;
427 	buffer[4] = 0x84;
428 	buffer[5] = 0x96;
429 	buffer[6] = 0x60;
430 	buffer[7] = 0x7d;
431 	buffer[8] = 0x22;
432 	buffer[9] = 0xd4;
433 	buffer[10] = 0x27;
434 	buffer[11] = 0x00;
435 	buffer[12] = 0x10;
436 	buffer[13] = 0x7e;
437 	buffer[14] = 0x03;
438 	buffer[15] = 0x58;
439 	buffer[16] = 0x4b;
440 	buffer[17] = 0xe0;
441 	buffer[18] = 0x36;
442 	buffer[19] = 0x92;
443 	buffer[20] = 0x54;
444 	buffer[21] = 0x0e;
445 	buffer[22] = 0x88;
446 	buffer[23] = 0x8c;		//chip-pin CLKI is pixel clock (only non-default here!)
447 	buffer[24] = 0x0a;
448 	buffer[25] = 0xe5;
449 	buffer[26] = 0x76;
450 	buffer[27] = 0x79;
451 	buffer[28] = 0x44;
452 	buffer[29] = 0x85;
453 	buffer[30] = 0x00;
454 	buffer[31] = 0x00;
455 	buffer[32] = 0x80;
456 	buffer[33] = 0x20;
457 	buffer[34] = 0x00;
458 
459 	/* reset status */
460 	i2c_flag_error (-1);
461 
462 	i2c_bstart(si->ps.tv_encoder.bus);
463 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
464 	i2c_bstop(si->ps.tv_encoder.bus);
465 	/* log on errors */
466 	stat = i2c_flag_error(0);
467 	if (stat)
468 		LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC640\n"));
469 
470 	return stat;
471 }//end BT_init_NTSC640.
472 
473 static uint8 BT_init_NTSC800()
474 {
475 	uint8 stat;
476 
477 	uint8 buffer[35];
478 
479 	LOG(4,("Brooktree: Setting NTSC 800x600 desktop mode\n"));
480 
481 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
482 	buffer[1] = 0x76;			//select first bt register to write to
483 	buffer[2] = 0xa0;
484 	buffer[3] = 0x20;
485 	buffer[4] = 0xb6;
486 	buffer[5] = 0xce;
487 	buffer[6] = 0x84;
488 	buffer[7] = 0x55;
489 	buffer[8] = 0x20;
490 	buffer[9] = 0xd8;
491 	buffer[10] = 0x39;
492 	buffer[11] = 0x00;
493 	buffer[12] = 0x70;
494 	buffer[13] = 0x42;
495 	buffer[14] = 0x03;
496 	buffer[15] = 0xdf;
497 	buffer[16] = 0x56;
498 	buffer[17] = 0x58;
499 	buffer[18] = 0x3a;
500 	buffer[19] = 0xcd;
501 	buffer[20] = 0x9c;
502 	buffer[21] = 0x14;
503 	buffer[22] = 0x3b;
504 	buffer[23] = 0x91;		//chip-pin CLKI is pixel clock (only non-default here!)
505 	buffer[24] = 0x0a;
506 	buffer[25] = 0xe5;
507 	buffer[26] = 0x74;
508 	buffer[27] = 0x77;
509 	buffer[28] = 0x43;
510 	buffer[29] = 0x85;
511 	buffer[30] = 0xba;
512 	buffer[31] = 0xe8;
513 	buffer[32] = 0xa2;
514 	buffer[33] = 0x17;
515 	buffer[34] = 0x00;
516 
517 	/* reset status */
518 	i2c_flag_error (-1);
519 
520 	i2c_bstart(si->ps.tv_encoder.bus);
521 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
522 	i2c_bstop(si->ps.tv_encoder.bus);
523 	/* log on errors */
524 	stat = i2c_flag_error(0);
525 	if (stat)
526 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n"));
527 
528 	return stat;
529 }//end BT_init_NTSC800.
530 
531 static uint8 BT_init_PAL720()
532 {
533 	uint8 stat;
534 
535 	uint8 buffer[35];
536 
537 	LOG(4,("Brooktree: Setting PAL 720x576 overscanning DVD mode\n"));
538 
539 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
540 	buffer[1] = 0x76;			//select first bt register to write to
541 	buffer[2] = 0xf0;
542 	buffer[3] = 0xd0;
543 	buffer[4] = 0x82;
544 	buffer[5] = 0x9c;
545 	buffer[6] = 0x5a;
546 	buffer[7] = 0x31;
547 	buffer[8] = 0x16;
548 	buffer[9] = 0x22;
549 	buffer[10] = 0xa6;
550 	buffer[11] = 0x00;
551 	buffer[12] = 0x78;
552 	buffer[13] = 0x93;
553 	buffer[14] = 0x03;
554 	buffer[15] = 0x71;
555 	buffer[16] = 0x2a;
556 	buffer[17] = 0x40;
557 	buffer[18] = 0x0a;
558 	buffer[19] = 0x00;
559 	buffer[20] = 0x50;
560 	buffer[21] = 0x55;
561 	buffer[22] = 0x55;
562 	buffer[23] = 0x8c;		//chip-pin CLKI is pixel clock (only non-default here!)
563 	buffer[24] = 0x24;
564 	buffer[25] = 0xf0;
565 	buffer[26] = 0x59;
566 	buffer[27] = 0x82;
567 	buffer[28] = 0x49;
568 	buffer[29] = 0x8c;
569 	buffer[30] = 0x8e;
570 	buffer[31] = 0xb0;
571 	buffer[32] = 0xe6;
572 	buffer[33] = 0x28;
573 	buffer[34] = 0x00;
574 
575 	/* reset status */
576 	i2c_flag_error (-1);
577 
578 	i2c_bstart(si->ps.tv_encoder.bus);
579 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
580 	i2c_bstop(si->ps.tv_encoder.bus);
581 	/* log on errors */
582 	stat = i2c_flag_error(0);
583 	if (stat)
584 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL720\n"));
585 
586 	return stat;
587 }//end BT_init_PAL720.
588 
589 static uint8 BT_init_NTSC720()
590 {
591 	uint8 stat;
592 
593 	uint8 buffer[35];
594 
595 	LOG(4,("Brooktree: Setting NTSC 720x480 overscanning DVD mode\n"));
596 
597 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
598 	buffer[1] = 0x76;		//select first bt register to write to.
599 	buffer[2] = 0xf0;		//lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1)
600 	buffer[3] = 0xd0;		//lsb h_active: h_active = 720 pixels wide port
601 	buffer[4] = 0x83;	//scope: OK hsync_width: (hsync_width / h_clk_o) * 63.55556uS = 4.70uS for NTSC
602 	buffer[5] = 0x98;	//scope: OK	hburst_begin: (hburst_begin / h_clk_o) * 63.55556uS = 5.3uS for NTSC
603 	buffer[6] = 0x5e;	//scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 63.55556uS = 7.94uS for NTSC
604 
605 	//How to find the correct values for h_blank_o and v_blank_o:
606 	// 1. Calculate h_blank_o according to initial setting guideline mentioned below;
607 	// 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while
608 	//    horizontal position is about OK;
609 	// 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch);
610 	// 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above);
611 	// 5. If no vertical shivering occurs when image is centered, you're done. Else:
612 	// 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!:
613 	// 7. Make sure you update the Chrontel horizontal Phase setting also then!
614 
615 	buffer[7] = 0x28;	//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV
616 						//(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC)
617 	buffer[8] = 0x18;	//try-out; scope: checked against other modes, looks OK.	v_blank_o: 1e active line ('pixel')
618 
619 	buffer[9] = 0xf2;		//v_active_o: = (active output lines + 2) / field (on TV)
620 	buffer[10] = 0x26;		//lsn = msn h_clk_o;
621 							//b4-5 = msbits h_active;
622 							//b7 = b8 v_avtive_o.
623 	buffer[11] = 0x00;		//h_fract is always 0.
624 	buffer[12] = 0x78;		//lsb h_clk_i: h_clk_i is horizontal total = 888.
625 	buffer[13] = 0x90; 	//try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync!
626 	buffer[14] = 0x03;		//b2-0 = msn h_clk_i;
627 						//try-out: b3 = msn h_blank_i;
628 							//b4 = vblankdly is always 0.
629 	buffer[15] = 0x0d;		//lsb v_lines_i: v_lines_i = 525
630 	buffer[16] = 0x1a; 	//try-out;	v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync!
631 						//Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV.
632 	buffer[17] = 0xe0;		//lsb v_active_i: v_active_i = 480
633 	buffer[18] = 0x36;		//b1-0 = msn v_lines_i;
634 							//b3-2 = msn v_active_i;
635 							//b5-4 = ylpf = 3;
636 							//b7-6 = clpf = 0.
637 	buffer[19] = 0x00;		//lsb v_scale: v_scale = off = $1000
638 	buffer[20] = 0x50;		//b5-0 = msn v_scale;
639 						//scope: tuned. b7-6 = msn h_blank_o.
640 							//(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 60Hz)
641 	buffer[21] = 0x98;		//lsb PLL fract: PLL fract = 0x6e98
642 	buffer[22] = 0x6e;		//msb PLL fract
643 	buffer[23] = 0x8c;		//b5-0 = PLL int: PLL int = 0x0c;
644 							//b6 = by_pll: by_pll = 0;
645 							//b7 = EN_XCLK: chip-pin CLKI is pixel clock.
646 	buffer[24] = 0x0a;		//b0 = ni_out is always 0;
647 							//b1 = setup = 1 for NTSC;
648 							//b2 = 625line = 0 for NTSC;
649 							//b3 = vsync_dur = 1 for NTSC;
650 							//b4 = dic_screset is always 0;
651 							//b5 = pal_md = 0 for NTSC;
652 							//b6 = eclip is always 0;
653 							//b7 = reserved (en_scart) is always 0.
654 	buffer[25] = 0xe5;		//sync_amp $e5 for NTSC
655 	buffer[26] = 0x75;		//bst_amp $74-$76 for NTSC
656 	buffer[27] = 0x78;		//mcr: r-y $77-$79 for NTSC
657 	buffer[28] = 0x44;		//mcb: b-y $43-$44 for NTSC
658 	buffer[29] = 0x85;		//my: y $85 for NTSC
659 	buffer[30] = 0x3c;		//lsb msc: msc b31-0: NTSC formula: ((3579545 / pixelclk) * 2^32) = MSC
660 	buffer[31] = 0x91;		//msc = $20c2913c
661 	buffer[32] = 0xc2;
662 	buffer[33] = 0x20;		//msb msc.
663 	buffer[34] = 0x00;		//phase_off always $00
664 
665 	/* reset status */
666 	i2c_flag_error (-1);
667 
668 	i2c_bstart(si->ps.tv_encoder.bus);
669 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
670 	i2c_bstop(si->ps.tv_encoder.bus);
671 	/* log on errors */
672 	stat = i2c_flag_error(0);
673 	if (stat)
674 		LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC720\n"));
675 
676 	return stat;
677 }//end BT_init_NTSC720.
678 
679 static uint8 BT_init_PAL800_OS()
680 {
681 	uint8 stat;
682 
683 	uint8 buffer[35];
684 
685 	LOG(4,("Brooktree: Setting PAL 800x600 overscanning VCD mode\n"));
686 
687 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
688 	buffer[1] = 0x76;		//select first bt register to write to.
689 	buffer[2] = 0x60;		//lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1)
690 	buffer[3] = 0x20;		//lsb h_active: h_active = 800 pixels wide port
691 	buffer[4] = 0x8b;	//scope: OK hsync_width: (hsync_width / h_clk_o) * 64.0uS = 4.70uS for PAL
692 	buffer[5] = 0xa5;	//scope: OK	hburst_begin: (hburst_begin / h_clk_o) * 64.0uS = 5.6uS for PAL
693 	buffer[6] = 0x6b;	//scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 64.0uS = 7.97uS for PAL
694 
695 	//How to find the correct values for h_blank_o and v_blank_o:
696 	// 1. Calculate h_blank_o according to initial setting guideline mentioned below;
697 	// 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while
698 	//    horizontal position is about OK;
699 	// 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch);
700 	// 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above);
701 	// 5. If no vertical shivering occurs when image is centered, you're done. Else:
702 	// 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!:
703 	// 7. Make sure you update the Chrontel horizontal Phase setting also then!
704 
705 	if (si->ps.tv_encoder.type >= CX25870)//set CX value
706 	{
707 		buffer[7] = 0xf4;
708 		buffer[8] = 0x17;
709 	}
710 	else
711 	{	//set BT value
712 		//fixme: checkout ws-tv (added 0x10)..
713 		/* confirmed on TNT1 using 4:3 TV */
714 		buffer[7] = 0xd0;//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV
715 						//(guideline for initial setting: (h_blank_o / h_clk_0) * 64.0uS = 10.0uS for PAL)
716 		buffer[8] = 0x18;//try-out; scope: checked against other modes, looks OK.	v_blank_o: 1e active line ('pixel')
717 	}
718 
719 	buffer[9] = 0x2e;		//v_active_o: = (active output lines + 2) / field (on TV)
720 	buffer[10] = 0xb7;		//lsn = msn h_clk_o;
721 							//b4-5 = msbits h_active;
722 							//b7 = b8 v_avtive_o.
723 	buffer[11] = 0x00;		//h_fract is always 0.
724 	buffer[12] = 0xb0;		//lsb h_clk_i: h_clk_i is horizontal total = 944.
725 
726 	if (si->ps.tv_encoder.type >= CX25870)//set CX value
727 		buffer[13] = 0x20;
728 	else				//set BT value
729 		buffer[13] = 0x14;//try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync!
730 
731 	buffer[14] = 0x03;		//b2-0 = msn h_clk_i;
732 					 	//try-out: b3 = msn h_blank_i;
733 							//b4 = vblankdly is always 0.
734 	buffer[15] = 0x71;		//lsb v_lines_i: v_lines_i = 625
735 
736 	if (si->ps.tv_encoder.type >= CX25870)//set CX value
737 		buffer[16] = 0x08;
738 	else				//set BT value
739 		buffer[16] = 0x2a;//try-out; v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync!
740 					 	//Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV.
741 
742 	buffer[17] = 0x58;		//lsb v_active_i: v_active_i = 600
743 	buffer[18] = 0x3a;		//b1-0 = msn v_lines_i;
744 							//b3-2 = msn v_active_i;
745 							//b5-4 = ylpf = 3;
746 							//b7-6 = clpf = 0.
747 	buffer[19] = 0x00;		//lsb v_scale: v_scale = off = $1000
748 	buffer[20] = 0x10;		//b5-0 = msn v_scale;
749 						//scope: tuned. b7-6 = msn h_blank_o.
750 							//(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 50Hz)
751 	buffer[21] = 0x72;		//lsb PLL fract: PLL fract = 0x1c72
752 	buffer[22] = 0x1c;		//msb PLL fract
753 	buffer[23] = 0x8d;		//b5-0 = PLL int: PLL int = 0x0d;
754 							//b6 = by_pll: by_pll = 0;
755 							//b7 = EN_XCLK: chip-pin CLKI is pixel clock.
756 	buffer[24] = 0x24;		//b0 = ni_out is always 0;
757 							//b1 = setup = 0 for PAL;
758 							//b2 = 625line = 1 for PAL;
759 							//b3 = vsync_dur = 0 for PAL;
760 							//b4 = dic_screset is always 0;
761 							//b5 = pal_md = 1 for PAL;
762 							//b6 = eclip is always 0;
763 							//b7 = reserved (en_scart) is always 0.
764 	buffer[25] = 0xf0;		//sync_amp $f0 for PAL
765 	buffer[26] = 0x57;		//bst_amp $57-$58 for PAL
766 	buffer[27] = 0x80;		//mcr: r-y $80-$81 for PAL
767 	buffer[28] = 0x48;		//mcb: b-y $48-$49 for PAL
768 	buffer[29] = 0x8c;		//my: y $8c for PAL
769 	buffer[30] = 0x31;		//lsb msc: msc b31-0: PAL formula: ((4433619 / pixelclk) * 2^32) = MSC
770 	buffer[31] = 0x8c;		//msc = $26798c31
771 	buffer[32] = 0x79;
772 	buffer[33] = 0x26;		//msb msc.
773 	buffer[34] = 0x00;		//phase_off always $00
774 
775 	/* reset status */
776 	i2c_flag_error (-1);
777 
778 	i2c_bstart(si->ps.tv_encoder.bus);
779 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
780 	i2c_bstop(si->ps.tv_encoder.bus);
781 	/* log on errors */
782 	stat = i2c_flag_error(0);
783 	if (stat)
784 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800 OS\n"));
785 
786 	return stat;
787 }//end BT_init_PAL800_OS.
788 
789 static uint8 BT_init_NTSC640_OS()
790 {
791 	uint8 stat;
792 
793 	uint8 buffer[35];
794 
795 	LOG(4,("Brooktree: Setting NTSC 640x480 overscanning VCD mode\n"));
796 
797 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
798 	buffer[1] = 0x76;		//select first bt register to write to.
799 	buffer[2] = 0x20;		//lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1)
800 	buffer[3] = 0x80;		//lsb h_active: h_active = 640 pixels wide port
801 	buffer[4] = 0x74;	//scope: OK hsync_width: (hsync_width / h_clk_o) * 63.55556uS = 4.70uS for NTSC
802 	buffer[5] = 0x83;	//scope: OK	hburst_begin: (hburst_begin / h_clk_o) * 63.55556uS = 5.3uS for NTSC
803 	buffer[6] = 0x44;	//scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 63.55556uS = 7.94uS for NTSC
804 
805 	//How to find the correct values for h_blank_o and v_blank_o:
806 	// 1. Calculate h_blank_o according to initial setting guideline mentioned below;
807 	// 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while
808 	//    horizontal position is about OK;
809 	// 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch);
810 	// 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above);
811 	// 5. If no vertical shivering occurs when image is centered, you're done. Else:
812 	// 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!:
813 	// 7. Make sure you update the Chrontel horizontal Phase setting also then!
814 
815 	buffer[7] = 0xf7;	//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV:
816 						//(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC)
817 
818 	if (si->ps.tv_encoder.type >= CX25870)//set CX value
819 		buffer[8] = 0x1d;
820 	else				//set BT value
821 		buffer[8] = 0x1c;//try-out; scope: checked against other modes, looks OK.	v_blank_o: 1e active line ('pixel')
822 
823 	buffer[9] = 0xf2;		//v_active_o: = (active output lines + 2) / field (on TV)
824 	buffer[10] = 0x26;		//lsn = msn h_clk_o;
825 							//b4-5 = msbits h_active;
826 							//b7 = b8 v_avtive_o.
827 	buffer[11] = 0x00;		//h_fract is always 0.
828 	buffer[12] = 0x10;		//lsb h_clk_i: h_clk_i is horizontal total = 784.
829 	buffer[13] = 0x14;	//try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync!
830 	buffer[14] = 0x03;		//b2-0 = msn h_clk_i;
831 						//try-out: b3 = msn h_blank_i;
832 							//b4 = vblankdly is always 0.
833 	buffer[15] = 0x0d;		//lsb v_lines_i: v_lines_i = 525
834 	buffer[16] = 0x18;	//try-out;	v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync!
835 					 	//Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV.
836 	buffer[17] = 0xe0;		//lsb v_active_i: v_active_i = 480
837 	buffer[18] = 0x36;		//b1-0 = msn v_lines_i;
838 							//b3-2 = msn v_active_i;
839 							//b5-4 = ylpf = 3;
840 							//b7-6 = clpf = 0.
841 	buffer[19] = 0x00;		//lsb v_scale: v_scale = off = $1000
842 	buffer[20] = 0x10;		//b5-0 = msn v_scale;
843 						//scope: tuned. b7-6 = msn h_blank_o.
844 							//(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 60Hz)
845 	buffer[21] = 0xdb;		//lsb PLL fract: PLL fract = 0xf9db
846 	buffer[22] = 0xf9;		//msb PLL fract
847 	buffer[23] = 0x8a;		//b5-0 = PLL int: PLL int = 0x0a;
848 							//b6 = by_pll: by_pll = 0;
849 							//b7 = EN_XCLK: chip-pin CLKI is pixel clock.
850 	buffer[24] = 0x0a;		//b0 = ni_out is always 0;
851 							//b1 = setup = 1 for NTSC;
852 							//b2 = 625line = 0 for NTSC;
853 							//b3 = vsync_dur = 1 for NTSC;
854 							//b4 = dic_screset is always 0;
855 							//b5 = pal_md = 0 for NTSC;
856 							//b6 = eclip is always 0;
857 							//b7 = reserved (en_scart) is always 0.
858 	buffer[25] = 0xe5;		//sync_amp $e5 for NTSC
859 	buffer[26] = 0x75;		//bst_amp $74-$76 for NTSC
860 	buffer[27] = 0x78;		//mcr: r-y $77-$79 for NTSC
861 	buffer[28] = 0x44;		//mcb: b-y $43-$44 for NTSC
862 	buffer[29] = 0x85;		//my: y $85 for NTSC
863 	buffer[30] = 0x37;		//lsb msc: msc b31-0: NTSC formula: ((3579545 / pixelclk) * 2^32) = MSC
864 	buffer[31] = 0x12;		//msc = $251b1237
865 	buffer[32] = 0x1b;
866 	buffer[33] = 0x25;		//msb msc.
867 	buffer[34] = 0x00;		//phase_off always $00
868 
869 	/* reset status */
870 	i2c_flag_error (-1);
871 
872 	i2c_bstart(si->ps.tv_encoder.bus);
873 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
874 	i2c_bstop(si->ps.tv_encoder.bus);
875 	/* log on errors */
876 	stat = i2c_flag_error(0);
877 	if (stat)
878 		LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC640 OS\n"));
879 
880 	return stat;
881 }//end BT_init_NTSC640_OS.
882 
883 static uint8 BT_testsignal(void)
884 {
885 	uint8 stat;
886 
887 	uint8 buffer[3];
888 
889 	LOG(4,("Brooktree: Enabling testsignal\n"));
890 
891 	buffer[0] = si->ps.tv_encoder.adress + WR;
892 	/* select bt register for enabling colorbars and outputs */
893 	buffer[1] = 0xc4;
894 	/* issue the actual command */
895 	buffer[2] = 0x05;
896 
897 	/* reset status */
898 	i2c_flag_error (-1);
899 
900 	i2c_bstart(si->ps.tv_encoder.bus);
901 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
902 	i2c_bstop(si->ps.tv_encoder.bus);
903 	/* log on errors */
904 	stat = i2c_flag_error(0);
905 	if (stat)
906 		LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n"));
907 
908 	return stat;
909 }//end BT_testsignal.
910 
911 static uint8 BT_setup_output(uint8 monstat, uint8 output, uint8 ffilter)
912 {
913 	uint8 stat;
914 
915 	uint8 buffer[7];
916 
917 	buffer[0] = si->ps.tv_encoder.adress + WR;
918 	/* select first TV config register to write */
919 	buffer[1] = 0xc6;
920 	/* input is 24bit mpx'd RGB, BLANK = out, sync = act. hi */
921 	buffer[2] = 0x98;
922 	/* disable all filters, exept flicker filter */
923 	buffer[3] = 0x98;
924 	if (!ffilter)
925 	{
926 		/* disable flicker filter */
927 		buffer[3] = 0xc0;
928 		LOG(4,("Brooktree: Disabling flickerfilter\n"));
929 	}
930 	else
931 		LOG(4,("Brooktree: Enabling flickerfilter\n"));
932 
933 	/* (disable filters) */
934 	buffer[4] = 0xc0;
935 	/* (disable filters) */
936 	buffer[5] = 0xc0;
937 	switch (output)
938 	/* Description of ELSA Erazor III hardware layout:
939 	 * (This is the default (recommended) layout by NVIDIA)
940 	 * DAC A = CVBS
941 	 * DAC B = C (chrominance)
942 	 * DAC C = Y (luminance) */
943 
944 	/* Description of Diamond VIPER550:
945 	 * DAC A = Not connected
946 	 * DAC B = C (chrominance)
947 	 * DAC C = Y (luminance)
948 	 * To be able to connect to CVBS TV's a special cable is supplied:
949 	 * This cable connects the Y (DAC C) output to the TV CVBS input. */
950 	{
951 	case 1:
952 		LOG(4,("Brooktree: Outputting both Y/C and CVBS where supported by hardware\n"));
953 		buffer[6] = 0x18;	// Y/C and CVBS out if all ports implemented
954 							// in hardware, else only Y/C or CVBS out.
955 		break;
956 	case 2:
957 		LOG(4,("Brooktree: Outputting CVBS on all outputs\n"));
958 		buffer[6] = 0x00;	// put CVBS on all outputs. Used for cards
959 		break;				// with only Y/C out and 'translation cable'.
960 	default:
961 		LOG(4,("Brooktree: Outputting signals according to autodetect status:\n"));
962 		switch (monstat)	// only 'autodetect' remains...
963 		{
964 		case 1:
965 			LOG(4,("Brooktree: Only Y connected, outputting CVBS on all outputs\n"));
966 			buffer[6] = 0x00;	//only Y connected: must be CVBS!
967 			break;
968 		case 2:
969 			LOG(4,("Brooktree: Only C connected, outputting CVBS on all outputs\n"));
970 			buffer[6] = 0x00;	//only C connected: must be CVBS!
971 			break;				//(though cable is wired wrong...)
972 		case 5:
973 			LOG(4,("Brooktree: CVBS and only Y connected, outputting CVBS on all outputs\n"));
974 			buffer[6] = 0x00;	//CVBS and only Y connected: 2x CVBS!
975 			break;			   	//(officially not supported...)
976 		case 6:
977 			LOG(4,("Brooktree: CVBS and only C connected, outputting CVBS on all outputs\n"));
978 			buffer[6] = 0x00;	//CVBS and only C connected: 2x CVBS!
979 			break;			   	//(officially not supported...)
980 		default:
981 			LOG(4,("Brooktree: Outputting both Y/C and CVBS where supported by hardware\n"));
982 			buffer[6] = 0x18;	//nothing, or
983 							 	//Y/C only, or
984 							 	//CVBS only (but on CVBS output), or
985 							 	//Y/C and CVBS connected:
986 							 	//So activate recommended signals.
987 		}
988 	}
989 
990 	/* reset status */
991 	i2c_flag_error (-1);
992 
993 	i2c_bstart(si->ps.tv_encoder.bus);
994 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
995 	i2c_bstop(si->ps.tv_encoder.bus);
996 	/* log on errors */
997 	stat = i2c_flag_error(0);
998 	if (stat)
999 		LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n"));
1000 
1001 	return stat;
1002 }//end BT_setup_output.
1003 
1004 static uint8 BT_setup_hphase(uint8 mode)
1005 {
1006 	uint8 stat, hoffset;
1007 
1008 	uint8 buffer[7];
1009 
1010 	LOG(4,("Brooktree: Tuning horizontal phase\n"));
1011 
1012 	/* CX needs timing reset (advised on BT also), first 1mS delay needed! */
1013 	snooze(1000);
1014 
1015 	/* values below are all tested on TNT1, TNT2 and GeForce2MX */
1016 	buffer[0] = si->ps.tv_encoder.adress + WR;
1017 	/* select first TV output timing register to write */
1018 	buffer[1] = 0x6c;
1019 	/* turn on active video & generate timing reset on CX chips! */
1020 	buffer[2] = 0x86;
1021 	/* (set fail save values...) */
1022 	buffer[3] = 0x00;		//set default horizontal sync offset
1023 	buffer[4] = 0x02;		//set default horizontal sync width
1024 	buffer[5] = 0x00;		//set default vertical sync offset
1025 
1026 	/* do specific timing setup for all chips and modes: */
1027 	if ((si->ps.card_type == NV05) || (si->ps.card_type == NV05M64))
1028 	{
1029 		/* TNT2 and TNT2 M64...
1030 		 * (8 pixels delayed hpos, so picture more to the right) */
1031 		hoffset = 8;
1032 	}
1033 	else
1034 	{
1035 		/* TNT1 or GeForce2...
1036 		 * (std hpos)
1037 		 * NOTE: It might be that GeForce needs TNT2 offset:
1038 		 * for now CX chips get seperate extra offset, until sure.
1039 		 * (CX is only found AFAIK on GeForce cards, no BT tested
1040 		 * on GeForce yet. CH was tested on GeForce and seemed to
1041 		 * indicate TNT1 offset was needed.) */
1042 		hoffset = 0;
1043 	}
1044 
1045 	switch (mode)
1046 	{
1047 	case NTSC640_TST:
1048 	case NTSC640:
1049 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
1050 		buffer[3] = (0x25 + hoffset);	//set horizontal sync offset
1051 		break;
1052 	case NTSC800:
1053 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
1054 		buffer[3] = (0xe1 + hoffset);	//set horizontal sync offset
1055 		buffer[4] = 0xc2;
1056 		//Vsync offset reg. does not exist on CX: mode is checked and OK.
1057 		buffer[5] = 0x40;				//set VSync offset (on BT's only)
1058 		break;
1059 	case PAL640:
1060 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
1061 		buffer[3] = (0xa8 + hoffset);
1062 		break;
1063 	case PAL800_TST:
1064 	case PAL800:
1065 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
1066 		buffer[3] = (0x2c + hoffset);
1067 		break;
1068 	case NTSC720:
1069 		if (si->ps.tv_encoder.type >= CX25870)
1070 			buffer[3] = (0xb2 + hoffset); //set horizontal sync offset CX
1071 		else
1072 			buffer[3] = (0xd0 + hoffset); //set horizontal sync offset BT
1073 		buffer[4] = 0xff;				//hsync width = max:
1074 		break;							//to prevent vertical image 'shivering'.
1075 	case PAL720:
1076 		buffer[3] = (0xd4 + hoffset);
1077 		buffer[4] = 0xff;
1078 		break;
1079 	case NTSC640_OS:
1080 		buffer[3] = (0xc8 + hoffset);
1081 		buffer[4] = 0xff;
1082 		break;
1083 	case PAL800_OS:
1084 		if (si->ps.tv_encoder.type >= CX25870)
1085 			buffer[3] = (0x78 + hoffset); //set horizontal sync offset CX
1086 		else
1087 			buffer[3] = (0xc4 + hoffset); //set horizontal sync offset BT
1088 		buffer[4] = 0xff;
1089 		break;
1090 	default: //nothing to be done here...
1091 		break;
1092 	}
1093 
1094 	buffer[6] = 0x01;		//set default vertical sync width
1095 
1096 	/* reset status */
1097 	i2c_flag_error (-1);
1098 
1099 	i2c_bstart(si->ps.tv_encoder.bus);
1100 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
1101 	i2c_bstop(si->ps.tv_encoder.bus);
1102 	/* log on errors */
1103 	stat = i2c_flag_error(0);
1104 	if (stat)
1105 		LOG(4,("Brooktree: I2C errors occurred while setting up h_phase\n"));
1106 
1107 	return stat;
1108 }//end BT_setup_hphase.
1109 
1110 static uint8 BT_read_monstat(uint8* monstat)
1111 {
1112 	uint8 stat;
1113 	uint8 buffer[3];
1114 
1115 	/* make sure we have the recommended failsafe selected */
1116 	*monstat = 0;
1117 
1118 	LOG(4,("Brooktree: Autodetecting connected output devices\n"));
1119 
1120 	/* set BT to return connection status in ESTATUS on next read CMD: */
1121 	buffer[0] = si->ps.tv_encoder.adress + WR;
1122 	/* set ESTATUS at b'01' (return conn.stat.) */
1123 	buffer[1] = 0xc4;
1124 	/* and leave chip outputs on. */
1125 	buffer[2] = 0x41;
1126 
1127 	/* reset status */
1128 	i2c_flag_error (-1);
1129 
1130 	i2c_bstart(si->ps.tv_encoder.bus);
1131 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
1132 	i2c_bstop(si->ps.tv_encoder.bus);
1133 	/* log on errors */
1134 	stat = i2c_flag_error(0);
1135 	if (stat)
1136 	{
1137 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (1)\n"));
1138 		return stat;
1139 	}
1140 
1141 	/* do actual read connection status: */
1142 	buffer[0] = si->ps.tv_encoder.adress + WR;
1143 	/* select register with CHECK_STAT CMD */
1144 	buffer[1] = 0xba;
1145 	/* issue actual command. */
1146 	buffer[2] = 0x40;
1147 
1148 	i2c_bstart(si->ps.tv_encoder.bus);
1149 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
1150 	i2c_bstop(si->ps.tv_encoder.bus);
1151 	/* log on errors */
1152 	stat = i2c_flag_error(0);
1153 	if (stat)
1154 	{
1155 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (2)\n"));
1156 		return stat;
1157 	}
1158 
1159 	/* CX: Wait 600uS for signals to stabilize (see datasheet) */
1160 	/* warning, note:
1161 	 * datasheet is in error! 60mS needed!! */
1162 	snooze(60000);
1163 
1164 	/* read back updated connection status: */
1165 	buffer[0] = si->ps.tv_encoder.adress + RD;
1166 
1167 	/* transmit 1 byte */
1168 	i2c_bstart(si->ps.tv_encoder.bus);
1169 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 1);
1170 
1171 	/* receive 1 byte */
1172 	/* ACK level to TX after last byte to RX should be 1 (= NACK) (see I2C spec)
1173 	 * While the BT's don't care, CX chips will block the SDA line if an ACK gets sent! */
1174 	buffer[0] = 1;
1175 	i2c_readbuffer(si->ps.tv_encoder.bus, buffer, 1);
1176 	i2c_bstop(si->ps.tv_encoder.bus);
1177 	/* log on errors */
1178 	stat = i2c_flag_error(0);
1179 	if (stat)
1180 	{
1181 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (3)\n"));
1182 		return stat;
1183 	}
1184 
1185 	*monstat = ((buffer[0] & 0xe0) >> 5);
1186 	LOG(4,("Brooktree: TV output monitor status = %d\n", *monstat));
1187 
1188 	/* instruct BT to go back to normal operation: */
1189 	buffer[0] = si->ps.tv_encoder.adress + WR;
1190 	/* select register with CHECK_STAT CMD */
1191 	buffer[1] = 0xba;
1192 	/* issue actual command. */
1193 	buffer[2] = 0x00;
1194 
1195 	i2c_bstart(si->ps.tv_encoder.bus);
1196 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
1197 	i2c_bstop(si->ps.tv_encoder.bus);
1198 	/* log on errors */
1199 	stat = i2c_flag_error(0);
1200 	if (stat)
1201 	{
1202 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (4)\n"));
1203 		return stat;
1204 	}
1205 
1206 	return stat;
1207 }//end BT_read_monstat.
1208 
1209 static uint8 BT_killclk_blackout(void)
1210 {
1211 	uint8 stat;
1212 
1213 	uint8 buffer[4];
1214 
1215 	LOG(4,("Brooktree: Killing clock and/or blacking out (blocking output signals)\n"));
1216 
1217 	/* reset status */
1218 	i2c_flag_error (-1);
1219 
1220 	if (si->ps.tv_encoder.type <= BT869) //BT...
1221 	{
1222 		/* Only disable external pixelclock input on BT's.
1223 		 * CX chips will lock the bus if you do this.
1224 		 * (It looks like the external pixelclock is always OK as long as a valid
1225 		 * mode is programmed for the TVout chip. This means that disabling the use
1226 		 * of this clock is not needed anyway.
1227 		 * If you do disable this input, this pixelclock will rise to about 60Mhz BTW..) */
1228 
1229 		/* disable use of external pixelclock source... */
1230 		/* (should prevent BT for being 'overclocked' by RIVA in VGA-only mode...) */
1231 		buffer[0] = si->ps.tv_encoder.adress + WR;
1232 		/* select BT register for setting EN_XCLK */
1233 		buffer[1] = 0xa0;
1234 		/* clear it */
1235 		buffer[2] = 0x00;
1236 
1237 		i2c_bstart(si->ps.tv_encoder.bus);
1238 		i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
1239 		i2c_bstop(si->ps.tv_encoder.bus);
1240 		/* log on errors */
1241 		stat = i2c_flag_error(0);
1242 		if (stat)
1243 		{
1244 			LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-BT)\n"));
1245 			return stat;
1246 		}
1247 	}
1248 	else //CX...
1249 	{
1250 		/* Disable CX video out (or wild output will be seen on TV..) */
1251 		buffer[0] = si->ps.tv_encoder.adress + WR;
1252 		/* select register in CX */
1253 		buffer[1] = 0x6c;
1254 		/* disable active video out. */
1255 		buffer[2] = 0x02;
1256 
1257 		i2c_bstart(si->ps.tv_encoder.bus);
1258 		i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
1259 		i2c_bstop(si->ps.tv_encoder.bus);
1260 		/* log on errors */
1261 		stat = i2c_flag_error(0);
1262 		if (stat)
1263 		{
1264 			LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-CX)\n"));
1265 			return stat;
1266 		}
1267 	}
1268 
1269 	/* black-out TVout while outputs are enabled... */
1270 	buffer[0] = si->ps.tv_encoder.adress + WR;
1271 	/* select first TV config register to write */
1272 	buffer[1] = 0xc4;
1273 	/* disable testimage while outputs remain enabled */
1274 	buffer[2] = 0x01;
1275 	/* input is 24bit mpx'd RGB, BLANK = in, sync = act. hi */
1276 	buffer[3] = 0x18;
1277 
1278 	i2c_bstart(si->ps.tv_encoder.bus);
1279 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
1280 	i2c_bstop(si->ps.tv_encoder.bus);
1281 	/* log on errors */
1282 	stat = i2c_flag_error(0);
1283 	if (stat)
1284 	{
1285 		LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (2)\n"));
1286 		return stat;
1287 	}
1288 
1289 	return stat;
1290 }//end BT_killclk_blackout.
1291 
1292 uint8 BT_check_tvmode(display_mode target)
1293 {
1294 	uint8 status = NOT_SUPPORTED;
1295 	uint32 mode = ((target.timing.h_display) | ((target.timing.v_display) << 16));
1296 
1297 	switch (mode)
1298 	{
1299 	case (640 | (480 << 16)):
1300 		if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO)))
1301 			status = PAL640;
1302 		if ((target.flags & TV_BITS) == TV_NTSC)
1303 		{
1304 			if (!(target.flags & TV_VIDEO)) status = NTSC640;
1305 			else status = NTSC640_OS;
1306 		}
1307 		break;
1308 	case (768 | (576 << 16)):
1309 		if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO))
1310 			status = PAL800_OS;
1311 		break;
1312 	case (800 | (600 << 16)):
1313 		if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO)))
1314 			status = PAL800;
1315 		if (((target.flags & TV_BITS) == TV_NTSC) && (!(target.flags & TV_VIDEO)))
1316 			status = NTSC800;
1317 		break;
1318 	case (720 | (480 << 16)):
1319 		if (((target.flags & TV_BITS) == TV_NTSC) && (target.flags & TV_VIDEO))
1320 			status = NTSC720;
1321 		break;
1322 	case (720 | (576 << 16)):
1323 		if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO))
1324 			status = PAL720;
1325 		break;
1326 	}
1327 
1328 	return status;
1329 }//end BT_check_tvmode.
1330 
1331 
1332 /*
1333 //BeTVOut's SwitchRIVAtoTV(vtot) timing formula: (note: vtot = (v_total - 2))
1334 //-----------------------------------------------------------------------------------
1335 //HORIZONTAL:
1336 //-----------
1337 h_sync_start = h_display;
1338 
1339 //fixme, note, checkout:
1340 //feels like in fact TNT2-M64 nv_crtc.c registerprogramming should be adapted...
1341 if (TNT2-M64)
1342 {
1343 	h_sync_end = h_display + 8;
1344 	h_total = h_display + 56;
1345 }
1346 else //TNT1, TNT2, Geforce2... (so default)
1347 {
1348 	h_sync_end = h_display + 16;
1349 	h_total = h_display + 48;
1350 }
1351 
1352 //fixme, note, checkout:
1353 //BeTVOut uses two 'tweaks':
1354 // - on TNT2-M64 only:
1355 //   register h_blank_e is increased with 1 (so should be done in nv_crtc.c here)
1356 // - 'all cards':
1357 //   register h_blank_e b6 = 0 (only influences TNT2-M64 in modes NTSC800 and PAL800).
1358 //-----------------------------------------------------------------------------------
1359 //VERTICAL:
1360 //---------
1361 v_sync_start = v_display;
1362 v_total = vtot + 2;
1363 v_sync_end = v_total - 1; //(This takes care of the 'cursor trash' on TNT1's...)
1364 //-----------------------------------------------------------------------------------
1365 */
1366 static status_t BT_update_mode_for_gpu(display_mode *target, uint8 tvmode)
1367 {
1368 	//fixme if needed:
1369 	//pixelclock is not actually pgm'd because PLL is pgm' earlier during setmode...
1370 	switch (tvmode)
1371 	{
1372 	case NTSC640:
1373 	case NTSC640_TST:
1374 		target->timing.h_display = 640;
1375 		target->timing.h_sync_start = 640;
1376 		if (si->ps.card_type == NV05M64)
1377 		{
1378 			target->timing.h_sync_end = 648;
1379 			target->timing.h_total = 696;
1380 		}
1381 		else
1382 		{
1383 			target->timing.h_sync_end = 656;
1384 			target->timing.h_total = 688;
1385 		}
1386 		target->timing.v_display = 480;
1387 		target->timing.v_sync_start = 480;
1388 		target->timing.v_sync_end = 555;	//This prevents 'cursor trash' on TNT1's
1389 		target->timing.v_total = 556;		//Above 525 because mode scales down
1390 		if (si->ps.card_type == NV05M64)
1391 			target->timing.pixel_clock = ((696 * 556 * 60) / 1000);
1392 		else
1393 			target->timing.pixel_clock = ((688 * 556 * 60) / 1000);
1394 		break;
1395 	case NTSC800:
1396 		target->timing.h_display = 800;
1397 		target->timing.h_sync_start = 800;
1398 		if (si->ps.card_type == NV05M64)
1399 		{
1400 			target->timing.h_sync_end = 808;
1401 			target->timing.h_total = 856;
1402 		}
1403 		else
1404 		{
1405 			target->timing.h_sync_end = 816;
1406 			target->timing.h_total = 848;
1407 		}
1408 		target->timing.v_display = 600;
1409 		target->timing.v_sync_start = 600;
1410 		target->timing.v_sync_end = 685;	//This prevents 'cursor trash' on TNT1's
1411 		target->timing.v_total = 686;		//Above 525 because mode scales down
1412 		if (si->ps.card_type == NV05M64)
1413 			target->timing.pixel_clock = ((856 * 686 * 60) / 1000);
1414 		else
1415 			target->timing.pixel_clock = ((848 * 686 * 60) / 1000);
1416 		break;
1417 	case PAL640:
1418 		target->timing.h_display = 640;
1419 		target->timing.h_sync_start = 640;
1420 		if (si->ps.card_type == NV05M64)
1421 		{
1422 			target->timing.h_sync_end = 648;
1423 			target->timing.h_total = 696;
1424 		}
1425 		else
1426 		{
1427 			target->timing.h_sync_end = 656;
1428 			target->timing.h_total = 688;
1429 		}
1430 		target->timing.v_display = 480;
1431 		target->timing.v_sync_start = 480;
1432 		target->timing.v_sync_end = 570;	//This prevents 'cursor trash' on TNT1's
1433 		target->timing.v_total = 571;		//Below 625 because mode scales up
1434 		if (si->ps.card_type == NV05M64)
1435 			target->timing.pixel_clock = ((696 * 571 * 50) / 1000);
1436 		else
1437 			target->timing.pixel_clock = ((688 * 571 * 50) / 1000);
1438 		break;
1439 	case PAL800:
1440 	case PAL800_TST:
1441 		target->timing.h_display = 800;
1442 		target->timing.h_sync_start = 800;
1443 		if (si->ps.card_type == NV05M64)
1444 		{
1445 			target->timing.h_sync_end = 808;
1446 			target->timing.h_total = 856;
1447 		}
1448 		else
1449 		{
1450 			target->timing.h_sync_end = 816;
1451 			target->timing.h_total = 848;
1452 		}
1453 		target->timing.v_display = 600;
1454 		target->timing.v_sync_start = 600;
1455 		target->timing.v_sync_end = 695;	//This prevents 'cursor trash' on TNT1's
1456 		target->timing.v_total = 696;		//Above 625 because mode scales down
1457 		if (si->ps.card_type == NV05M64)
1458 			target->timing.pixel_clock = ((856 * 696 * 50) / 1000);
1459 		else
1460 			target->timing.pixel_clock = ((848 * 696 * 50) / 1000);
1461 		break;
1462 	case NTSC640_OS:
1463 		target->timing.h_display = 640;			//BT H_ACTIVE
1464 		target->timing.h_sync_start = 744;		//set for CH/BT compatible TV output
1465 		target->timing.h_sync_end = 744+20;		//delta is BT H_BLANKI
1466 		target->timing.h_total = 784;			//BT H_CLKI
1467 		target->timing.v_display = 480;			//BT  V_ACTIVEI
1468 		target->timing.v_sync_start = 490;		//set for centered sync pulse
1469 		target->timing.v_sync_end = 490+25;		//delta is BT V_BLANKI
1470 		target->timing.v_total = 525;			//BT V_LINESI (== 525: 1:1 scaled mode)
1471 		target->timing.pixel_clock = ((784 * 525 * 60) / 1000); //refresh
1472 		break;
1473 	case PAL800_OS:
1474 		target->timing.h_display = 768;			//H_ACTIVE
1475 		if (si->ps.tv_encoder.type <= BT869)
1476 		{
1477 			//fixme: checkout ws-tv (added 8)..
1478 			/* confirmed on TNT1 using 4:3 TV */
1479 			target->timing.h_sync_start = 856;		//set for centered TV output
1480 			target->timing.h_sync_end = 856+20;		//delta is BT H_BLANKI
1481 		}
1482 		else
1483 		{
1484 			target->timing.h_sync_start = 848;		//set for centered TV output
1485 			target->timing.h_sync_end = 848+20;		//delta is BT H_BLANKI
1486 		}
1487 		target->timing.h_total = 944;			//BT H_CLKI
1488 		target->timing.v_display = 576;			//V_ACTIVEI
1489 		target->timing.v_sync_start = 579;		//set for centered sync pulse
1490 		target->timing.v_sync_end = 579+42;		//delta is BT V_BLANKI
1491 		target->timing.v_total = 625;			//BT V_LINESI (== 625: 1:1 scaled mode)
1492 		target->timing.pixel_clock = ((944 * 625 * 50) / 1000); //refresh
1493 		break;
1494 	case NTSC720:
1495 		/* (tested on TNT2 with BT869) */
1496 		target->timing.h_display = 720;			//H_ACTIVE
1497 		target->timing.h_sync_start = 744;		//do not change!
1498 		target->timing.h_sync_end = 744+144;	//delta is H_sync_pulse
1499 		target->timing.h_total = 888;			//BT H_TOTAL
1500 		target->timing.v_display = 480;			//V_ACTIVEI
1501 		target->timing.v_sync_start = 490;		//set for centered sync pulse
1502 		target->timing.v_sync_end = 490+26;		//delta is V_sync_pulse
1503 		target->timing.v_total = 525;			//CH V_TOTAL (== 525: 1:1 scaled mode)
1504 		target->timing.pixel_clock = ((888 * 525 * 60) / 1000); //refresh
1505 		break;
1506 	case PAL720:
1507 		target->timing.h_display = 720;			//BT H_ACTIVE
1508 		target->timing.h_sync_start = 744;		//set for centered sync pulse
1509 		target->timing.h_sync_end = 744+140;	//delta is BT H_BLANKI
1510 		target->timing.h_total = 888;			//BT H_CLKI
1511 		target->timing.v_display = 576;			//BT  V_ACTIVEI
1512 		target->timing.v_sync_start = 579;		//set for centered sync pulse
1513 		target->timing.v_sync_end = 579+42;		//delta is BT V_BLANKI
1514 		target->timing.v_total = 625;			//BT V_LINESI (== 625: 1:1 scaled mode)
1515 		target->timing.pixel_clock = ((888 * 625 * 50) / 1000); //refresh
1516 		break;
1517 	default:
1518 		return B_ERROR;
1519 	}
1520 
1521 	return B_OK;
1522 }//end BT_update_mode_for_gpu.
1523 
1524 /* note:
1525  * tested on ELSA Erazor III 32Mb AGP (TNT2/BT869),
1526  * Diamond Viper V550 16Mb PCI (TNT1/BT869),
1527  * and ASUS V7100 GeForce2 MX200 AGP/32Mb (CH7007). */
1528 static status_t BT_start_tvout(void)
1529 {
1530 	/* enable access to primary head */
1531 	set_crtc_owner(0);
1532 
1533 	/* CAUTION:
1534 	 * On the TNT1, TV_SETUP and PLLSEL cannot be read (sometimes), but
1535 	 * write actions do succeed ... (tested on both ISA and PCI bus!) */
1536 
1537 	/* setup TVencoder connection */
1538 	/* b1-0 = %01: encoder type is MASTER;
1539 	 * b24 = 1: VIP datapos is b0-7 */
1540 	//fixme if needed: setup completely instead of relying on pre-init by BIOS..
1541 	//(it seems to work OK on TNT1 although read reg. doesn't seem to work)
1542 	DACW(TV_SETUP, ((DACR(TV_SETUP) & ~0x00000002) | 0x01000001));
1543 
1544 	/* tell GPU to use pixelclock from TVencoder instead of using internal source */
1545 	/* (nessecary or display will 'shiver' on both TV and VGA.) */
1546 	if (si->ps.secondary_head)
1547 	{
1548 		DACW(PLLSEL, (DACR(PLLSEL) | 0x00030000));
1549 	}
1550 	else
1551 	{
1552 		/* confirmed PLLSEL to be a write-only register on TNT1! */
1553 		DACW(PLLSEL, 0x00030700);
1554 	}
1555 
1556 	/* Set overscan color to 'black' */
1557 	/* note:
1558 	 * Change this instruction for a visible overscan color if you're trying to
1559 	 * center the output on TV. Use it as a guide-'line' then ;-) */
1560 	ATBW(OSCANCOLOR, 0x00);
1561 
1562 	/* set CRTC to slaved mode (b7 = 1) and clear TVadjust (b3-5 = %000) */
1563 	CRTCW(PIXEL, ((CRTCR(PIXEL) & 0xc7) | 0x80));
1564 	/* select TV encoder, not panel encoder (b0 = 0).
1565 	 * Note:
1566 	 * Both are devices (often) using the CRTC in slaved mode. */
1567 	CRTCW(LCD, (CRTCR(LCD) & 0xfe));
1568 
1569 	/* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of
1570 	 * H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */
1571 	CRTCW(TREG, 0x80);
1572 
1573 	return B_OK;
1574 }//end BT_start_tvout.
1575 
1576 /* note:
1577  * tested on ELSA Erazor III 32Mb AGP (TNT2/BT869),
1578  * Diamond Viper V550 16Mb PCI (TNT1/BT869),
1579  * and ASUS V7100 GeForce2 MX200 AGP/32Mb (CH7007). */
1580 status_t BT_stop_tvout(void)
1581 {
1582 	/* prevent BT from being overclocked by VGA-only modes & black-out TV-out */
1583 	BT_killclk_blackout();
1584 
1585 	/* enable access to primary head */
1586 	set_crtc_owner(0);
1587 
1588 	/* switch on VGA monitor HSYNC and VSYNC */
1589 //fixme: see if better DPMS state fetching can be setup for crtc.c (!)
1590 	CRTCW(REPAINT1, (CRTCR(REPAINT1) & 0x3f));
1591 
1592 
1593 	/* wait for one image to be generated to make sure VGA has kicked in and is
1594 	 * running OK before continuing...
1595 	 * (Kicking in will fail often if we do not wait here) */
1596 
1597 	/* make sure we are 'in' active VGA picture */
1598 	while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1);
1599 	/* wait for next vertical retrace start on VGA */
1600 	while (!(NV_REG8(NV8_INSTAT1) & 0x08)) snooze(1);
1601 	/* now wait until we are 'in' active VGA picture again */
1602 	while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1);
1603 
1604 
1605 	/* set CRTC to master mode (b7 = 0) if it wasn't slaved for a panel before */
1606 	if (!(si->ps.slaved_tmds1))	CRTCW(PIXEL, (CRTCR(PIXEL) & 0x03));
1607 
1608 	//fixme: checkout...
1609 	//CAUTION:
1610 	//On the TNT1, these memadresses apparantly cannot be read (sometimes)!;
1611 	//write actions do succeed though... (tested only on ISA bus yet..)
1612 
1613 	/* setup TVencoder connection */
1614 	/* b1-0 = %00: encoder type is SLAVE;
1615 	 * b24 = 1: VIP datapos is b0-7 */
1616 	//fixme if needed: setup completely instead of relying on pre-init by BIOS..
1617 	DACW(TV_SETUP, ((DACR(TV_SETUP) & ~0x00000003) | 0x01000000));
1618 
1619 	/* tell GPU to use pixelclock from internal source instead of using TVencoder */
1620 	DACW(PLLSEL, 0x10000700);
1621 	if (si->ps.secondary_head) DACW(PLLSEL, (DACR(PLLSEL) | 0x20000800));
1622 
1623 	/* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of
1624 	 * H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */
1625 	CRTCW(TREG, 0x00);
1626 
1627 	/* select panel encoder, not TV encoder if needed (b0 = 1).
1628 	 * Note:
1629 	 * Both are devices (often) using the CRTC in slaved mode. */
1630 	if (si->ps.slaved_tmds1) CRTCW(LCD, (CRTCR(LCD) | 0x01));
1631 
1632 	/* fixme if needed:
1633 	 * a full encoder chip reset could be done here (so after decoupling crtc)... */
1634 	/* (but: beware of the 'locked SDA' syndrome then!) */
1635 
1636 	return B_OK;
1637 }//end BT_stop_tvout.
1638 
1639 status_t BT_setmode(display_mode target)
1640 {
1641 	uint8 tvmode, monstat;
1642 	/* enable flickerfilter in desktop modes, disable it in video modes. */
1643 	uint8 ffilter = 0;
1644 
1645 	/* use a display_mode copy because we might tune it for TVout compatibility */
1646 	display_mode tv_target = target;
1647 
1648 	/* preset new TVout mode */
1649 	tvmode = BT_check_tvmode(tv_target);
1650 	if (!tvmode) return B_ERROR;
1651 
1652 	/* read current output devices connection status */
1653 	BT_read_monstat(&monstat);
1654 
1655 	/* (pre)set TV mode */
1656 	/* note:
1657 	 * Manual config is non-dependent of the state of the PAL hardware input pin;
1658 	 * Also SDA lockups occur when setting EN_XCLK after autoconfig!
1659 	 * Make sure PAL_MD=0 for NTSC and PAL_MD = 1 for PAL... */
1660 	switch (tvmode)
1661 	{
1662 	case NTSC640:
1663 	case NTSC640_TST:
1664 		ffilter = 1;
1665 		BT_init_NTSC640();
1666 		break;
1667 	case NTSC800:
1668 		ffilter = 1;
1669 		BT_init_NTSC800();
1670 		break;
1671 	case PAL640:
1672 		ffilter = 1;
1673 		BT_init_PAL640();
1674 		break;
1675 	case PAL800:
1676 	case PAL800_TST:
1677 		ffilter = 1;
1678 		BT_init_PAL800();
1679 		break;
1680 	case NTSC640_OS:
1681 		BT_init_NTSC640_OS();
1682 		break;
1683 	case PAL800_OS:
1684 		BT_init_PAL800_OS();
1685 		break;
1686 	case NTSC720:
1687 		BT_init_NTSC720();
1688 		break;
1689 	case PAL720:
1690 		BT_init_PAL720();
1691 		break;
1692 	}
1693 
1694 	/* modify BT Hphase signal to center TV image... */
1695 	BT_setup_hphase(tvmode);
1696 
1697 	/* disable Macro mode */
1698 	switch (tvmode)
1699 	{
1700 	case NTSC640:
1701 	case NTSC640_TST:
1702 	case NTSC800:
1703 	case NTSC640_OS:
1704 	case NTSC720:
1705 		/* NTSC */
1706 		BT_set_macro (0, 0);
1707 		break;
1708 	default:
1709 		/* PAL */
1710 		BT_set_macro (1, 0);
1711 		break;
1712 	}
1713 
1714 	/* setup output signal routing and flickerfilter */
1715 //fixme: add output force settings in nv.settings, defaulting to autodetect.
1716 	BT_setup_output(monstat, 0, ffilter);
1717 
1718 	/* update the GPU CRTC timing for the requested mode */
1719 	BT_update_mode_for_gpu(&tv_target, tvmode);
1720 
1721 	/* setup GPU CRTC timing */
1722 	head1_set_timing(tv_target);
1723 
1724 //fixme: only testing singlehead cards for now...
1725 if (si->ps.secondary_head)
1726 {
1727 	BT_testsignal();
1728 	return B_OK;
1729 }
1730 
1731 	/* now set GPU CRTC to slave mode */
1732 	BT_start_tvout();
1733 
1734 //fixme: add code to disable VGA screen when TVout enabled
1735 //(use via nv.setting preset)
1736 
1737 	return B_OK;
1738 }
1739