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