xref: /haiku/src/add-ons/accelerants/nvidia/engine/nv_brooktreetv.c (revision 4022652c41c8005e690ae18d8a977a254b75c027)
1 /*
2 	Author:
3 	Rudolf Cornelissen 4/2002-11/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 
BT_set_macro(int std,int mode)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 */
BT_check(uint8 bus,uint8 adress)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 */
BT_read_type(void)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 
BT_probe()216 bool BT_probe()
217 {
218 	uint8 bus;
219 	bool btfound = false;
220 	bool *i2c_bus = &(si->ps.i2c_bus0);
221 
222 	LOG(4,("Brooktree: Checking wired I2C bus(ses) for first possible TV encoder...\n"));
223 	for (bus = 0; bus < 3; bus++)
224 	{
225 		if (i2c_bus[bus] && !btfound)
226 		{
227 			/* try primary adress on bus */
228 			if (!BT_check(bus, PRADR))
229 			{
230 				btfound = true;
231 				si->ps.tv_encoder.adress = PRADR;
232 				si->ps.tv_encoder.bus = bus;
233 			}
234 			else
235 			{
236 				/* try secondary adress on bus */
237 				if (!BT_check(bus, SCADR))
238 				{
239 					btfound = true;
240 					si->ps.tv_encoder.adress = SCADR;
241 					si->ps.tv_encoder.bus = bus;
242 				}
243 			}
244 		}
245 	}
246 
247 	/* identify exact TV encoder type */
248 	if (btfound)
249 	{
250 		/* if errors are found, retry */
251 		/* note:
252 		 * NACK: occurs on some ASUS V7700 GeForce cards!
253 		 * (apparantly the video-in chip or another chip resides at 'BT' adresses
254 		 * there..) */
255 		uint8 stat;
256 		uint8 cnt = 0;
257 		while ((stat = BT_read_type()) && (cnt < 3))
258 		{
259 			/* don't retry on unsupported chiptype */
260 			if (stat == 0x80)
261 			{
262 				btfound = 0;
263 				break;
264 			}
265 			cnt++;
266 		}
267 		if (stat & 0x7f)
268 		{
269 			LOG(4,("Brooktree: Too much errors occurred, aborting.\n"));
270 			btfound = 0;
271 		}
272 	}
273 
274 	if (btfound)
275 		LOG(4,("Brooktree: Found TV encoder on bus %d, adress $%02x\n",
276 			si->ps.tv_encoder.bus, si->ps.tv_encoder.adress));
277 	else
278 		LOG(4,("Brooktree: No TV encoder Found\n"));
279 
280 	return btfound;
281 }
282 
BT_init_PAL640()283 static uint8 BT_init_PAL640()
284 {
285 	uint8 stat;
286 
287 	uint8 buffer[35];
288 
289 	LOG(4,("Brooktree: Setting PAL 640x480 desktop mode\n"));
290 
291 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
292 	buffer[1] = 0x76;			//select first bt register to write to
293 	buffer[2] = 0x60;
294 	buffer[3] = 0x80;
295 	buffer[4] = 0x8a;
296 	buffer[5] = 0xa6;
297 	buffer[6] = 0x68;
298 	buffer[7] = 0xc1;
299 	buffer[8] = 0x2e;
300 	buffer[9] = 0xf2;
301 	buffer[10] = 0x27;
302 	buffer[11] = 0x00;
303 	buffer[12] = 0xb0;
304 	buffer[13] = 0x0a;
305 	buffer[14] = 0x0b;
306 	buffer[15] = 0x71;
307 	buffer[16] = 0x5a;
308 	buffer[17] = 0xe0;
309 	buffer[18] = 0x36;
310 	buffer[19] = 0x00;
311 	buffer[20] = 0x50;
312 	buffer[21] = 0x72;
313 	buffer[22] = 0x1c;
314 	buffer[23] = 0x8d;		//chip-pin CLKI is pixel clock (only non-default here!)
315 	buffer[24] = 0x24;
316 	buffer[25] = 0xf0;
317 	buffer[26] = 0x58;
318 	buffer[27] = 0x81;
319 	buffer[28] = 0x49;
320 	buffer[29] = 0x8c;
321 	buffer[30] = 0x0c;
322 	buffer[31] = 0x8c;
323 	buffer[32] = 0x79;
324 	buffer[33] = 0x26;
325 	buffer[34] = 0x00;
326 
327 	/* reset status */
328 	i2c_flag_error (-1);
329 
330 	i2c_bstart(si->ps.tv_encoder.bus);
331 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
332 	i2c_bstop(si->ps.tv_encoder.bus);
333 	/* log on errors */
334 	stat = i2c_flag_error(0);
335 	if (stat)
336 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL640\n"));
337 
338 	return stat;
339 }//end BT_init_PAL640.
340 
BT_init_PAL800()341 static uint8 BT_init_PAL800()
342 {
343 	uint8 stat;
344 
345 	uint8 buffer[35];
346 
347 	LOG(4,("Brooktree: Setting PAL 800x600 desktop mode\n"));
348 
349 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
350 	buffer[1] = 0x76;			//select first bt register to write to
351 	buffer[2] = 0x00;
352 	buffer[3] = 0x20;
353 	buffer[4] = 0xaa;
354 	buffer[5] = 0xca;
355 	buffer[6] = 0x9a;
356 	buffer[7] = 0x0d;
357 	buffer[8] = 0x29;
358 	buffer[9] = 0xfc;
359 	buffer[10] = 0x39;
360 	buffer[11] = 0x00;
361 	buffer[12] = 0xc0;
362 	buffer[13] = 0x8c;
363 	buffer[14] = 0x03;
364 	buffer[15] = 0xee;
365 	buffer[16] = 0x5f;
366 	buffer[17] = 0x58;
367 	buffer[18] = 0x3a;
368 	buffer[19] = 0x66;
369 	buffer[20] = 0x96;
370 	buffer[21] = 0x00;
371 	buffer[22] = 0x00;
372 	buffer[23] = 0x90;		//chip-pin CLKI is pixel clock (only non-default here!)
373 	buffer[24] = 0x24;
374 	buffer[25] = 0xf0;
375 	buffer[26] = 0x57;
376 	buffer[27] = 0x80;
377 	buffer[28] = 0x48;
378 	buffer[29] = 0x8c;
379 	buffer[30] = 0x18;
380 	buffer[31] = 0x28;
381 	buffer[32] = 0x87;
382 	buffer[33] = 0x1f;
383 	buffer[34] = 0x00;
384 
385 	/* reset status */
386 	i2c_flag_error (-1);
387 
388 	i2c_bstart(si->ps.tv_encoder.bus);
389 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
390 	i2c_bstop(si->ps.tv_encoder.bus);
391 	/* log on errors */
392 	stat = i2c_flag_error(0);
393 	if (stat)
394 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n"));
395 
396 	return stat;
397 }//end BT_init_PAL800.
398 
BT_init_NTSC640()399 static uint8 BT_init_NTSC640()
400 {
401 	uint8 stat;
402 
403 	uint8 buffer[35];
404 
405 	LOG(4,("Brooktree: Setting NTSC 640x480 desktop mode\n"));
406 
407 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
408 	buffer[1] = 0x76;			//select first bt register to write to
409 	buffer[2] = 0x00;
410 	buffer[3] = 0x80;
411 	buffer[4] = 0x84;
412 	buffer[5] = 0x96;
413 	buffer[6] = 0x60;
414 	buffer[7] = 0x7d;
415 	buffer[8] = 0x22;
416 	buffer[9] = 0xd4;
417 	buffer[10] = 0x27;
418 	buffer[11] = 0x00;
419 	buffer[12] = 0x10;
420 	buffer[13] = 0x7e;
421 	buffer[14] = 0x03;
422 	buffer[15] = 0x58;
423 	buffer[16] = 0x4b;
424 	buffer[17] = 0xe0;
425 	buffer[18] = 0x36;
426 	buffer[19] = 0x92;
427 	buffer[20] = 0x54;
428 	buffer[21] = 0x0e;
429 	buffer[22] = 0x88;
430 	buffer[23] = 0x8c;		//chip-pin CLKI is pixel clock (only non-default here!)
431 	buffer[24] = 0x0a;
432 	buffer[25] = 0xe5;
433 	buffer[26] = 0x76;
434 	buffer[27] = 0x79;
435 	buffer[28] = 0x44;
436 	buffer[29] = 0x85;
437 	buffer[30] = 0x00;
438 	buffer[31] = 0x00;
439 	buffer[32] = 0x80;
440 	buffer[33] = 0x20;
441 	buffer[34] = 0x00;
442 
443 	/* reset status */
444 	i2c_flag_error (-1);
445 
446 	i2c_bstart(si->ps.tv_encoder.bus);
447 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
448 	i2c_bstop(si->ps.tv_encoder.bus);
449 	/* log on errors */
450 	stat = i2c_flag_error(0);
451 	if (stat)
452 		LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC640\n"));
453 
454 	return stat;
455 }//end BT_init_NTSC640.
456 
BT_init_NTSC800()457 static uint8 BT_init_NTSC800()
458 {
459 	uint8 stat;
460 
461 	uint8 buffer[35];
462 
463 	LOG(4,("Brooktree: Setting NTSC 800x600 desktop mode\n"));
464 
465 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
466 	buffer[1] = 0x76;			//select first bt register to write to
467 	buffer[2] = 0xa0;
468 	buffer[3] = 0x20;
469 	buffer[4] = 0xb6;
470 	buffer[5] = 0xce;
471 	buffer[6] = 0x84;
472 	buffer[7] = 0x55;
473 	buffer[8] = 0x20;
474 	buffer[9] = 0xd8;
475 	buffer[10] = 0x39;
476 	buffer[11] = 0x00;
477 	buffer[12] = 0x70;
478 	buffer[13] = 0x42;
479 	buffer[14] = 0x03;
480 	buffer[15] = 0xdf;
481 	buffer[16] = 0x56;
482 	buffer[17] = 0x58;
483 	buffer[18] = 0x3a;
484 	buffer[19] = 0xcd;
485 	buffer[20] = 0x9c;
486 	buffer[21] = 0x14;
487 	buffer[22] = 0x3b;
488 	buffer[23] = 0x91;		//chip-pin CLKI is pixel clock (only non-default here!)
489 	buffer[24] = 0x0a;
490 	buffer[25] = 0xe5;
491 	buffer[26] = 0x74;
492 	buffer[27] = 0x77;
493 	buffer[28] = 0x43;
494 	buffer[29] = 0x85;
495 	buffer[30] = 0xba;
496 	buffer[31] = 0xe8;
497 	buffer[32] = 0xa2;
498 	buffer[33] = 0x17;
499 	buffer[34] = 0x00;
500 
501 	/* reset status */
502 	i2c_flag_error (-1);
503 
504 	i2c_bstart(si->ps.tv_encoder.bus);
505 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
506 	i2c_bstop(si->ps.tv_encoder.bus);
507 	/* log on errors */
508 	stat = i2c_flag_error(0);
509 	if (stat)
510 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n"));
511 
512 	return stat;
513 }//end BT_init_NTSC800.
514 
BT_init_PAL720()515 static uint8 BT_init_PAL720()
516 {
517 	uint8 stat;
518 
519 	uint8 buffer[35];
520 
521 	LOG(4,("Brooktree: Setting PAL 720x576 overscanning DVD mode\n"));
522 
523 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
524 	buffer[1] = 0x76;			//select first bt register to write to
525 	buffer[2] = 0xf0;
526 	buffer[3] = 0xd0;
527 	buffer[4] = 0x82;
528 	buffer[5] = 0x9c;
529 	buffer[6] = 0x5a;
530 	buffer[7] = 0x31;
531 	buffer[8] = 0x16;
532 	buffer[9] = 0x22;
533 	buffer[10] = 0xa6;
534 	buffer[11] = 0x00;
535 	buffer[12] = 0x78;
536 	buffer[13] = 0x93;
537 	buffer[14] = 0x03;
538 	buffer[15] = 0x71;
539 	buffer[16] = 0x2a;
540 	buffer[17] = 0x40;
541 	buffer[18] = 0x0a;
542 	buffer[19] = 0x00;
543 	buffer[20] = 0x50;
544 	buffer[21] = 0x55;
545 	buffer[22] = 0x55;
546 	buffer[23] = 0x8c;		//chip-pin CLKI is pixel clock (only non-default here!)
547 	buffer[24] = 0x24;
548 	buffer[25] = 0xf0;
549 	buffer[26] = 0x59;
550 	buffer[27] = 0x82;
551 	buffer[28] = 0x49;
552 	buffer[29] = 0x8c;
553 	buffer[30] = 0x8e;
554 	buffer[31] = 0xb0;
555 	buffer[32] = 0xe6;
556 	buffer[33] = 0x28;
557 	buffer[34] = 0x00;
558 
559 	/* reset status */
560 	i2c_flag_error (-1);
561 
562 	i2c_bstart(si->ps.tv_encoder.bus);
563 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
564 	i2c_bstop(si->ps.tv_encoder.bus);
565 	/* log on errors */
566 	stat = i2c_flag_error(0);
567 	if (stat)
568 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL720\n"));
569 
570 	return stat;
571 }//end BT_init_PAL720.
572 
BT_init_NTSC720()573 static uint8 BT_init_NTSC720()
574 {
575 	uint8 stat;
576 
577 	uint8 buffer[35];
578 
579 	LOG(4,("Brooktree: Setting NTSC 720x480 overscanning DVD mode\n"));
580 
581 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
582 	buffer[1] = 0x76;		//select first bt register to write to.
583 	buffer[2] = 0xf0;		//lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1)
584 	buffer[3] = 0xd0;		//lsb h_active: h_active = 720 pixels wide port
585 	buffer[4] = 0x83;	//scope: OK hsync_width: (hsync_width / h_clk_o) * 63.55556uS = 4.70uS for NTSC
586 	buffer[5] = 0x98;	//scope: OK	hburst_begin: (hburst_begin / h_clk_o) * 63.55556uS = 5.3uS for NTSC
587 	buffer[6] = 0x5e;	//scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 63.55556uS = 7.94uS for NTSC
588 
589 	//How to find the correct values for h_blank_o and v_blank_o:
590 	// 1. Calculate h_blank_o according to initial setting guideline mentioned below;
591 	// 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while
592 	//    horizontal position is about OK;
593 	// 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch);
594 	// 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above);
595 	// 5. If no vertical shivering occurs when image is centered, you're done. Else:
596 	// 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!:
597 	// 7. Make sure you update the Chrontel horizontal Phase setting also then!
598 
599 	if (si->ps.tv_encoder.type >= CX25870)//set CX value
600 	{
601 		/* confirmed on NV11 using 4:3 TV and 16:9 TV */
602 		buffer[7] = 0x0c;	//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV
603 							//(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC)
604 	}
605 	else //set BT value
606 	{
607 		/* confirmed on TNT1 using 4:3 TV and 16:9 TV */
608 		buffer[7] = 0x28;	//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV
609 							//(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC)
610 	}
611 	buffer[8] = 0x18;	//try-out; scope: checked against other modes, looks OK.	v_blank_o: 1e active line ('pixel')
612 
613 	buffer[9] = 0xf2;		//v_active_o: = (active output lines + 2) / field (on TV)
614 	buffer[10] = 0x26;		//lsn = msn h_clk_o;
615 							//b4-5 = msbits h_active;
616 							//b7 = b8 v_avtive_o.
617 	buffer[11] = 0x00;		//h_fract is always 0.
618 	buffer[12] = 0x78;		//lsb h_clk_i: h_clk_i is horizontal total = 888.
619 	buffer[13] = 0x90; 	//try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync!
620 	buffer[14] = 0x03;		//b2-0 = msn h_clk_i;
621 						//try-out: b3 = msn h_blank_i;
622 							//b4 = vblankdly is always 0.
623 	buffer[15] = 0x0d;		//lsb v_lines_i: v_lines_i = 525
624 	buffer[16] = 0x1a; 	//try-out;	v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync!
625 						//Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV.
626 	buffer[17] = 0xe0;		//lsb v_active_i: v_active_i = 480
627 	buffer[18] = 0x36;		//b1-0 = msn v_lines_i;
628 							//b3-2 = msn v_active_i;
629 							//b5-4 = ylpf = 3;
630 							//b7-6 = clpf = 0.
631 	buffer[19] = 0x00;		//lsb v_scale: v_scale = off = $1000
632 	buffer[20] = 0x50;		//b5-0 = msn v_scale;
633 						//scope: tuned. b7-6 = msn h_blank_o.
634 							//(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 60Hz)
635 	buffer[21] = 0x98;		//lsb PLL fract: PLL fract = 0x6e98
636 	buffer[22] = 0x6e;		//msb PLL fract
637 	buffer[23] = 0x8c;		//b5-0 = PLL int: PLL int = 0x0c;
638 							//b6 = by_pll: by_pll = 0;
639 							//b7 = EN_XCLK: chip-pin CLKI is pixel clock.
640 	buffer[24] = 0x0a;		//b0 = ni_out is always 0;
641 							//b1 = setup = 1 for NTSC;
642 							//b2 = 625line = 0 for NTSC;
643 							//b3 = vsync_dur = 1 for NTSC;
644 							//b4 = dic_screset is always 0;
645 							//b5 = pal_md = 0 for NTSC;
646 							//b6 = eclip is always 0;
647 							//b7 = reserved (en_scart) is always 0.
648 	buffer[25] = 0xe5;		//sync_amp $e5 for NTSC
649 	buffer[26] = 0x75;		//bst_amp $74-$76 for NTSC
650 	buffer[27] = 0x78;		//mcr: r-y $77-$79 for NTSC
651 	buffer[28] = 0x44;		//mcb: b-y $43-$44 for NTSC
652 	buffer[29] = 0x85;		//my: y $85 for NTSC
653 	buffer[30] = 0x3c;		//lsb msc: msc b31-0: NTSC formula: ((3579545 / pixelclk) * 2^32) = MSC
654 	buffer[31] = 0x91;		//msc = $20c2913c
655 	buffer[32] = 0xc2;
656 	buffer[33] = 0x20;		//msb msc.
657 	buffer[34] = 0x00;		//phase_off always $00
658 
659 	/* reset status */
660 	i2c_flag_error (-1);
661 
662 	i2c_bstart(si->ps.tv_encoder.bus);
663 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
664 	i2c_bstop(si->ps.tv_encoder.bus);
665 	/* log on errors */
666 	stat = i2c_flag_error(0);
667 	if (stat)
668 		LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC720\n"));
669 
670 	return stat;
671 }//end BT_init_NTSC720.
672 
BT_init_PAL800_OS()673 static uint8 BT_init_PAL800_OS()
674 {
675 	uint8 stat;
676 
677 	uint8 buffer[35];
678 
679 	LOG(4,("Brooktree: Setting PAL 800x600 overscanning VCD mode\n"));
680 
681 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
682 	buffer[1] = 0x76;		//select first bt register to write to.
683 	buffer[2] = 0x60;		//lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1)
684 	buffer[3] = 0x20;		//lsb h_active: h_active = 800 pixels wide port
685 	buffer[4] = 0x8b;	//scope: OK hsync_width: (hsync_width / h_clk_o) * 64.0uS = 4.70uS for PAL
686 	buffer[5] = 0xa5;	//scope: OK	hburst_begin: (hburst_begin / h_clk_o) * 64.0uS = 5.6uS for PAL
687 	buffer[6] = 0x6b;	//scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 64.0uS = 7.97uS for PAL
688 
689 	//How to find the correct values for h_blank_o and v_blank_o:
690 	// 1. Calculate h_blank_o according to initial setting guideline mentioned below;
691 	// 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while
692 	//    horizontal position is about OK;
693 	// 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch);
694 	// 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above);
695 	// 5. If no vertical shivering occurs when image is centered, you're done. Else:
696 	// 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!:
697 	// 7. Make sure you update the Chrontel horizontal Phase setting also then!
698 
699 	if (si->ps.tv_encoder.type >= CX25870)//set CX value
700 	{
701 		/* confirmed on NV11 using 4:3 TV and 16:9 TV */
702 		buffer[7] = 0xf0;
703 		buffer[8] = 0x17;
704 	}
705 	else //set BT value
706 	{
707 		/* confirmed on TNT1 using 4:3 TV and 16:9 TV */
708 		buffer[7] = 0xd0;//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 
BT_init_NTSC640_OS()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 
BT_testsignal(void)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 
BT_setup_output(uint8 monstat,uint8 output,uint8 ffilter)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: Forcing both Y/C and CVBS signals 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: Forcing CVBS signals 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 			LOG(4,("Brooktree: Only Y connected, outputting CVBS on all outputs\n"));
960 			buffer[6] = 0x00;	//only Y connected: must be CVBS!
961 			break;
962 		case 2:
963 			LOG(4,("Brooktree: Only C connected, outputting CVBS on all outputs\n"));
964 			buffer[6] = 0x00;	//only C connected: must be CVBS!
965 			break;				//(though cable is wired wrong...)
966 		case 5:
967 			LOG(4,("Brooktree: CVBS and only Y connected, outputting CVBS on all outputs\n"));
968 			buffer[6] = 0x00;	//CVBS and only Y connected: 2x CVBS!
969 			break;			   	//(officially not supported...)
970 		case 6:
971 			LOG(4,("Brooktree: CVBS and only C connected, outputting CVBS on all outputs\n"));
972 			buffer[6] = 0x00;	//CVBS and only C connected: 2x CVBS!
973 			break;			   	//(officially not supported...)
974 		default:
975 			LOG(4,("Brooktree: Outputting both Y/C and CVBS where supported by hardware\n"));
976 			buffer[6] = 0x18;	//nothing, or
977 							 	//Y/C only, or
978 							 	//CVBS only (but on CVBS output), or
979 							 	//Y/C and CVBS connected:
980 							 	//So activate recommended signals.
981 		}
982 	}
983 
984 	/* reset status */
985 	i2c_flag_error (-1);
986 
987 	i2c_bstart(si->ps.tv_encoder.bus);
988 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
989 	i2c_bstop(si->ps.tv_encoder.bus);
990 	/* log on errors */
991 	stat = i2c_flag_error(0);
992 	if (stat)
993 		LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n"));
994 
995 	return stat;
996 }//end BT_setup_output.
997 
BT_setup_hphase(uint8 mode)998 static uint8 BT_setup_hphase(uint8 mode)
999 {
1000 	uint8 stat, hoffset;
1001 
1002 	uint8 buffer[7];
1003 
1004 	LOG(4,("Brooktree: Tuning horizontal phase\n"));
1005 
1006 	/* CX needs timing reset (advised on BT also), first 1mS delay needed! */
1007 	snooze(1000);
1008 
1009 	/* values below are all tested on TNT1, TNT2 and GeForce2MX */
1010 	buffer[0] = si->ps.tv_encoder.adress + WR;
1011 	/* select first TV output timing register to write */
1012 	buffer[1] = 0x6c;
1013 	/* turn on active video & generate timing reset on CX chips! */
1014 	buffer[2] = 0x86;
1015 	/* (set fail save values...) */
1016 	buffer[3] = 0x00;		//set default horizontal sync offset
1017 	buffer[4] = 0x02;		//set default horizontal sync width
1018 	buffer[5] = 0x00;		//set default vertical sync offset
1019 
1020 	/* do specific timing setup for all chips and modes: */
1021 	switch (si->ps.card_type)
1022 	{
1023 	case NV05:
1024 	case NV05M64:
1025 	case NV15:
1026 		/* confirmed TNT2, TNT2M64, GeForce2Ti.
1027 		 * (8 pixels delayed hpos, so picture more to the right) */
1028 		hoffset = 8;
1029 		break;
1030 	default:
1031 		/* confirmed TNT1, GeForce256, GeForce2MX.
1032 		 * (std hpos)
1033 		 * NOTE: It might be that GeForce needs TNT2 offset:
1034 		 * for now CX chips get seperate extra offset, until sure.
1035 		 * (CX is only found AFAIK on GeForce cards, no BT tested
1036 		 * on GeForce yet. CH was tested on GeForce and seemed to
1037 		 * indicate TNT1 offset was needed.) */
1038 		hoffset = 0;
1039 		break;
1040 	}
1041 
1042 	switch (mode)
1043 	{
1044 	case NTSC640_TST:
1045 	case NTSC640:
1046 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
1047 		/* confirmed on TNT1 with BT869 using 4:3 TV and 16:9 TV */
1048 		buffer[3] = (0x1e + hoffset);	//set horizontal sync offset
1049 		break;
1050 	case NTSC800:
1051 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
1052 		buffer[3] = (0xe1 + hoffset);	//set horizontal sync offset
1053 		buffer[4] = 0xc2;
1054 		//Vsync offset reg. does not exist on CX: mode is checked and OK.
1055 		buffer[5] = 0x40;				//set VSync offset (on BT's only)
1056 		break;
1057 	case PAL640:
1058 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
1059 		buffer[3] = (0xa8 + hoffset);
1060 		break;
1061 	case PAL800_TST:
1062 	case PAL800:
1063 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
1064 		buffer[3] = (0x2c + hoffset);
1065 		break;
1066 	case NTSC720:
1067 		if (si->ps.tv_encoder.type >= CX25870)
1068 			buffer[3] = (0xb2 + hoffset); //set horizontal sync offset CX
1069 		else
1070 			buffer[3] = (0xd0 + hoffset); //set horizontal sync offset BT
1071 		buffer[4] = 0xff;				//hsync width = max:
1072 		break;							//to prevent vertical image 'shivering'.
1073 	case PAL720:
1074 		buffer[3] = (0xd4 + hoffset);
1075 		buffer[4] = 0xff;
1076 		break;
1077 	case NTSC640_OS:
1078 		buffer[3] = (0xc8 + hoffset);
1079 		buffer[4] = 0xff;
1080 		break;
1081 	case PAL800_OS:
1082 		if (si->ps.tv_encoder.type >= CX25870)
1083 			buffer[3] = (0x78 + hoffset); //set horizontal sync offset CX
1084 		else
1085 			buffer[3] = (0xc4 + hoffset); //set horizontal sync offset BT
1086 		buffer[4] = 0xff;
1087 		break;
1088 	default: //nothing to be done here...
1089 		break;
1090 	}
1091 
1092 	buffer[6] = 0x01;		//set default vertical sync width
1093 
1094 	/* reset status */
1095 	i2c_flag_error (-1);
1096 
1097 	i2c_bstart(si->ps.tv_encoder.bus);
1098 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
1099 	i2c_bstop(si->ps.tv_encoder.bus);
1100 	/* log on errors */
1101 	stat = i2c_flag_error(0);
1102 	if (stat)
1103 		LOG(4,("Brooktree: I2C errors occurred while setting up h_phase\n"));
1104 
1105 	return stat;
1106 }//end BT_setup_hphase.
1107 
BT_read_monstat(uint8 * monstat)1108 static uint8 BT_read_monstat(uint8* monstat)
1109 {
1110 	uint8 stat;
1111 	uint8 buffer[3];
1112 
1113 	/* make sure we have the recommended failsafe selected */
1114 	*monstat = 0;
1115 
1116 	LOG(4,("Brooktree: Autodetecting connected output devices\n"));
1117 
1118 	/* set BT to return connection status in ESTATUS on next read CMD: */
1119 	buffer[0] = si->ps.tv_encoder.adress + WR;
1120 	/* set ESTATUS at b'01' (return conn.stat.) */
1121 	buffer[1] = 0xc4;
1122 	/* and leave chip outputs on. */
1123 	buffer[2] = 0x41;
1124 
1125 	/* reset status */
1126 	i2c_flag_error (-1);
1127 
1128 	i2c_bstart(si->ps.tv_encoder.bus);
1129 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
1130 	i2c_bstop(si->ps.tv_encoder.bus);
1131 	/* log on errors */
1132 	stat = i2c_flag_error(0);
1133 	if (stat)
1134 	{
1135 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (1)\n"));
1136 		return stat;
1137 	}
1138 
1139 	/* do actual read connection status: */
1140 	buffer[0] = si->ps.tv_encoder.adress + WR;
1141 	/* select register with CHECK_STAT CMD */
1142 	buffer[1] = 0xba;
1143 	/* issue actual command. */
1144 	buffer[2] = 0x40;
1145 
1146 	i2c_bstart(si->ps.tv_encoder.bus);
1147 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
1148 	i2c_bstop(si->ps.tv_encoder.bus);
1149 	/* log on errors */
1150 	stat = i2c_flag_error(0);
1151 	if (stat)
1152 	{
1153 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (2)\n"));
1154 		return stat;
1155 	}
1156 
1157 	/* CX: Wait 600uS for signals to stabilize (see datasheet) */
1158 	/* warning, note:
1159 	 * datasheet is in error! 60mS needed!! */
1160 	snooze(60000);
1161 
1162 	/* read back updated connection status: */
1163 	buffer[0] = si->ps.tv_encoder.adress + RD;
1164 
1165 	/* transmit 1 byte */
1166 	i2c_bstart(si->ps.tv_encoder.bus);
1167 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 1);
1168 
1169 	/* receive 1 byte */
1170 	/* ACK level to TX after last byte to RX should be 1 (= NACK) (see I2C spec)
1171 	 * While the BT's don't care, CX chips will block the SDA line if an ACK gets sent! */
1172 	buffer[0] = 1;
1173 	i2c_readbuffer(si->ps.tv_encoder.bus, buffer, 1);
1174 	i2c_bstop(si->ps.tv_encoder.bus);
1175 	/* log on errors */
1176 	stat = i2c_flag_error(0);
1177 	if (stat)
1178 	{
1179 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (3)\n"));
1180 		return stat;
1181 	}
1182 
1183 	*monstat = ((buffer[0] & 0xe0) >> 5);
1184 	LOG(4,("Brooktree: TV output monitor status = %d\n", *monstat));
1185 
1186 	/* instruct BT to go back to normal operation: */
1187 	buffer[0] = si->ps.tv_encoder.adress + WR;
1188 	/* select register with CHECK_STAT CMD */
1189 	buffer[1] = 0xba;
1190 	/* issue actual command. */
1191 	buffer[2] = 0x00;
1192 
1193 	i2c_bstart(si->ps.tv_encoder.bus);
1194 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
1195 	i2c_bstop(si->ps.tv_encoder.bus);
1196 	/* log on errors */
1197 	stat = i2c_flag_error(0);
1198 	if (stat)
1199 	{
1200 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (4)\n"));
1201 		return stat;
1202 	}
1203 
1204 	return stat;
1205 }//end BT_read_monstat.
1206 
BT_killclk_blackout(void)1207 static uint8 BT_killclk_blackout(void)
1208 {
1209 	uint8 stat;
1210 
1211 	uint8 buffer[4];
1212 
1213 	LOG(4,("Brooktree: Killing clock and/or blacking out (blocking output signals)\n"));
1214 
1215 	/* reset status */
1216 	i2c_flag_error (-1);
1217 
1218 	if (si->ps.tv_encoder.type <= BT869) //BT...
1219 	{
1220 		/* Only disable external pixelclock input on BT's.
1221 		 * CX chips will lock the bus if you do this.
1222 		 * (It looks like the external pixelclock is always OK as long as a valid
1223 		 * mode is programmed for the TVout chip. This means that disabling the use
1224 		 * of this clock is not needed anyway.
1225 		 * If you do disable this input, this pixelclock will rise to about 60Mhz BTW..) */
1226 
1227 		/* disable use of external pixelclock source... */
1228 		/* (should prevent BT for being 'overclocked' by RIVA in VGA-only mode...) */
1229 		buffer[0] = si->ps.tv_encoder.adress + WR;
1230 		/* select BT register for setting EN_XCLK */
1231 		buffer[1] = 0xa0;
1232 		/* clear it */
1233 		buffer[2] = 0x00;
1234 
1235 		i2c_bstart(si->ps.tv_encoder.bus);
1236 		i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
1237 		i2c_bstop(si->ps.tv_encoder.bus);
1238 		/* log on errors */
1239 		stat = i2c_flag_error(0);
1240 		if (stat)
1241 		{
1242 			LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-BT)\n"));
1243 			return stat;
1244 		}
1245 	}
1246 	else //CX...
1247 	{
1248 		/* Disable CX video out (or wild output will be seen on TV..) */
1249 		buffer[0] = si->ps.tv_encoder.adress + WR;
1250 		/* select register in CX */
1251 		buffer[1] = 0x6c;
1252 		/* disable active video out. */
1253 		buffer[2] = 0x02;
1254 
1255 		i2c_bstart(si->ps.tv_encoder.bus);
1256 		i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
1257 		i2c_bstop(si->ps.tv_encoder.bus);
1258 		/* log on errors */
1259 		stat = i2c_flag_error(0);
1260 		if (stat)
1261 		{
1262 			LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-CX)\n"));
1263 			return stat;
1264 		}
1265 	}
1266 
1267 	/* black-out TVout while outputs are enabled... */
1268 	buffer[0] = si->ps.tv_encoder.adress + WR;
1269 	/* select first TV config register to write */
1270 	buffer[1] = 0xc4;
1271 	/* disable testimage while outputs remain enabled */
1272 	buffer[2] = 0x01;
1273 	/* input is 24bit mpx'd RGB, BLANK = in, sync = act. hi */
1274 	buffer[3] = 0x18;
1275 
1276 	i2c_bstart(si->ps.tv_encoder.bus);
1277 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
1278 	i2c_bstop(si->ps.tv_encoder.bus);
1279 	/* log on errors */
1280 	stat = i2c_flag_error(0);
1281 	if (stat)
1282 	{
1283 		LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (2)\n"));
1284 		return stat;
1285 	}
1286 
1287 	return stat;
1288 }//end BT_killclk_blackout.
1289 
BT_dpms(bool display)1290 uint8 BT_dpms(bool display)
1291 {
1292 	uint8 stat;
1293 
1294 	uint8 buffer[3];
1295 
1296 	LOG(4,("Brooktree: setting DPMS: "));
1297 
1298 	/* reset status */
1299 	i2c_flag_error (-1);
1300 
1301 	/* shutdown all analog electronics... */
1302 	buffer[0] = si->ps.tv_encoder.adress + WR;
1303 	/* select first TV config register to write */
1304 	buffer[1] = 0xba;
1305 	if (display)
1306 	{
1307 		/* enable all DACs */
1308 		buffer[2] = 0x00;
1309 		LOG(4,("display on\n"));
1310 	}
1311 	else
1312 	{
1313 		/* shutdown all DACs */
1314 		buffer[2] = 0x10;
1315 		LOG(4,("display off\n"));
1316 	}
1317 
1318 	i2c_bstart(si->ps.tv_encoder.bus);
1319 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
1320 	i2c_bstop(si->ps.tv_encoder.bus);
1321 	/* log on errors */
1322 	stat = i2c_flag_error(0);
1323 	if (stat)
1324 	{
1325 		LOG(4,("Brooktree: I2C errors occurred while setting DPMS\n"));
1326 		return stat;
1327 	}
1328 
1329 	return stat;
1330 }//end BT_dpms.
1331 
BT_check_tvmode(display_mode target)1332 uint8 BT_check_tvmode(display_mode target)
1333 {
1334 	uint8 status = NOT_SUPPORTED;
1335 	uint32 mode = ((target.timing.h_display) | ((target.timing.v_display) << 16));
1336 
1337 	switch (mode)
1338 	{
1339 	case (640 | (480 << 16)):
1340 		if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO)))
1341 			status = PAL640;
1342 		if ((target.flags & TV_BITS) == TV_NTSC)
1343 		{
1344 			if (!(target.flags & TV_VIDEO)) status = NTSC640;
1345 			else status = NTSC640_OS;
1346 		}
1347 		break;
1348 	case (768 | (576 << 16)):
1349 		if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO))
1350 			status = PAL800_OS;
1351 		break;
1352 	case (800 | (600 << 16)):
1353 		if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO)))
1354 			status = PAL800;
1355 		if (((target.flags & TV_BITS) == TV_NTSC) && (!(target.flags & TV_VIDEO)))
1356 			status = NTSC800;
1357 		break;
1358 	case (720 | (480 << 16)):
1359 		if (((target.flags & TV_BITS) == TV_NTSC) && (target.flags & TV_VIDEO))
1360 			status = NTSC720;
1361 		break;
1362 	case (720 | (576 << 16)):
1363 		if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO))
1364 			status = PAL720;
1365 		break;
1366 	}
1367 
1368 	return status;
1369 }//end BT_check_tvmode.
1370 
1371 
1372 /*
1373 //BeTVOut's SwitchRIVAtoTV(vtot) timing formula: (note: vtot = (v_total - 2))
1374 //-----------------------------------------------------------------------------------
1375 //HORIZONTAL:
1376 //-----------
1377 h_sync_start = h_display;
1378 
1379 //fixme, note, checkout:
1380 //feels like in fact TNT2-M64 nv_crtc.c registerprogramming should be adapted...
1381 if (TNT2-M64)
1382 {
1383 	h_sync_end = h_display + 8;
1384 	h_total = h_display + 56;
1385 }
1386 else //TNT1, TNT2, Geforce2... (so default)
1387 {
1388 	h_sync_end = h_display + 16;
1389 	h_total = h_display + 48;
1390 }
1391 
1392 //fixme, note, checkout:
1393 //BeTVOut uses two 'tweaks':
1394 // - on TNT2-M64 only:
1395 //   register h_blank_e is increased with 1 (so should be done in nv_crtc.c here)
1396 // - 'all cards':
1397 //   register h_blank_e b6 = 0 (only influences TNT2-M64 in modes NTSC800 and PAL800).
1398 //-----------------------------------------------------------------------------------
1399 //VERTICAL:
1400 //---------
1401 v_sync_start = v_display;
1402 v_total = vtot + 2;
1403 v_sync_end = v_total - 1; //(This takes care of the 'cursor trash' on TNT1's...)
1404 //-----------------------------------------------------------------------------------
1405 */
BT_update_mode_for_gpu(display_mode * target,uint8 tvmode)1406 static status_t BT_update_mode_for_gpu(display_mode *target, uint8 tvmode)
1407 {
1408 	//fixme if needed:
1409 	//pixelclock is not actually pgm'd because PLL is pgm' earlier during setmode...
1410 	switch (tvmode)
1411 	{
1412 	case NTSC640:
1413 	case NTSC640_TST:
1414 		target->timing.h_display = 640;
1415 		target->timing.h_sync_start = 640;
1416 		if (si->ps.card_type == NV05M64)
1417 		{
1418 			target->timing.h_sync_end = 648;
1419 			target->timing.h_total = 696;
1420 		}
1421 		else
1422 		{
1423 			//fixme if possible:
1424 			//see if tweaking h_sync_end can shift picture 8 pixels right to fix
1425 			//ws tv's tuning fault (always going for max. compatibility :)
1426 			target->timing.h_sync_end = 656;
1427 			target->timing.h_total = 688;
1428 		}
1429 		target->timing.v_display = 480;
1430 		target->timing.v_sync_start = 480;
1431 		target->timing.v_sync_end = 555;	//This prevents 'cursor trash' on TNT1's
1432 		target->timing.v_total = 556;		//Above 525 because mode scales down
1433 		if (si->ps.card_type == NV05M64)
1434 			target->timing.pixel_clock = ((696 * 556 * 60) / 1000);
1435 		else
1436 			target->timing.pixel_clock = ((688 * 556 * 60) / 1000);
1437 		break;
1438 	case NTSC800:
1439 		target->timing.h_display = 800;
1440 		target->timing.h_sync_start = 800;
1441 		if (si->ps.card_type == NV05M64)
1442 		{
1443 			target->timing.h_sync_end = 808;
1444 			target->timing.h_total = 856;
1445 		}
1446 		else
1447 		{
1448 			target->timing.h_sync_end = 816;
1449 			target->timing.h_total = 848;
1450 		}
1451 		target->timing.v_display = 600;
1452 		target->timing.v_sync_start = 600;
1453 		target->timing.v_sync_end = 685;	//This prevents 'cursor trash' on TNT1's
1454 		target->timing.v_total = 686;		//Above 525 because mode scales down
1455 		if (si->ps.card_type == NV05M64)
1456 			target->timing.pixel_clock = ((856 * 686 * 60) / 1000);
1457 		else
1458 			target->timing.pixel_clock = ((848 * 686 * 60) / 1000);
1459 		break;
1460 	case PAL640:
1461 		target->timing.h_display = 640;
1462 		target->timing.h_sync_start = 640;
1463 		if (si->ps.card_type == NV05M64)
1464 		{
1465 			target->timing.h_sync_end = 648;
1466 			target->timing.h_total = 696;
1467 		}
1468 		else
1469 		{
1470 			target->timing.h_sync_end = 656;
1471 			target->timing.h_total = 688;
1472 		}
1473 		target->timing.v_display = 480;
1474 		target->timing.v_sync_start = 480;
1475 		target->timing.v_sync_end = 570;	//This prevents 'cursor trash' on TNT1's
1476 		target->timing.v_total = 571;		//Below 625 because mode scales up
1477 		if (si->ps.card_type == NV05M64)
1478 			target->timing.pixel_clock = ((696 * 571 * 50) / 1000);
1479 		else
1480 			target->timing.pixel_clock = ((688 * 571 * 50) / 1000);
1481 		break;
1482 	case PAL800:
1483 	case PAL800_TST:
1484 		target->timing.h_display = 800;
1485 		target->timing.h_sync_start = 800;
1486 		if (si->ps.card_type == NV05M64)
1487 		{
1488 			target->timing.h_sync_end = 808;
1489 			target->timing.h_total = 856;
1490 		}
1491 		else
1492 		{
1493 			target->timing.h_sync_end = 816;
1494 			target->timing.h_total = 848;
1495 		}
1496 		target->timing.v_display = 600;
1497 		target->timing.v_sync_start = 600;
1498 		target->timing.v_sync_end = 695;	//This prevents 'cursor trash' on TNT1's
1499 		target->timing.v_total = 696;		//Above 625 because mode scales down
1500 		if (si->ps.card_type == NV05M64)
1501 			target->timing.pixel_clock = ((856 * 696 * 50) / 1000);
1502 		else
1503 			target->timing.pixel_clock = ((848 * 696 * 50) / 1000);
1504 		break;
1505 	case NTSC640_OS:
1506 		target->timing.h_display = 640;			//BT H_ACTIVE
1507 		target->timing.h_sync_start = 744;		//set for CH/BT compatible TV output
1508 		target->timing.h_sync_end = 744+20;		//delta is BT H_BLANKI
1509 		target->timing.h_total = 784;			//BT H_CLKI
1510 		target->timing.v_display = 480;			//BT  V_ACTIVEI
1511 		target->timing.v_sync_start = 490;		//set for centered sync pulse
1512 		target->timing.v_sync_end = 490+25;		//delta is BT V_BLANKI
1513 		target->timing.v_total = 525;			//BT V_LINESI (== 525: 1:1 scaled mode)
1514 		target->timing.pixel_clock = ((784 * 525 * 60) / 1000); //refresh
1515 		break;
1516 	case PAL800_OS:
1517 		target->timing.h_display = 768;			//H_ACTIVE
1518 		if (si->ps.tv_encoder.type <= BT869)
1519 		{
1520 			/* confirmed on TNT1 using 4:3 TV and 16:9 TV */
1521 			target->timing.h_sync_start = 856;		//set for centered TV output
1522 			target->timing.h_sync_end = 856+20;		//delta is BT H_BLANKI
1523 		}
1524 		else
1525 		{
1526 			/* confirmed on NV11 using 4:3 TV and 16:9 TV */
1527 			target->timing.h_sync_start = 848;		//set for centered TV output
1528 			target->timing.h_sync_end = 848+20;		//delta is BT H_BLANKI
1529 		}
1530 		target->timing.h_total = 944;			//BT H_CLKI
1531 		target->timing.v_display = 576;			//V_ACTIVEI
1532 		target->timing.v_sync_start = 579;		//set for centered sync pulse
1533 		target->timing.v_sync_end = 579+42;		//delta is BT V_BLANKI
1534 		target->timing.v_total = 625;			//BT V_LINESI (== 625: 1:1 scaled mode)
1535 		target->timing.pixel_clock = ((944 * 625 * 50) / 1000); //refresh
1536 		break;
1537 	case NTSC720:
1538 		/* (tested on TNT2 with BT869) */
1539 		target->timing.h_display = 720;			//H_ACTIVE
1540 		if (si->ps.tv_encoder.type <= BT869)
1541 		{
1542 			/* confirmed on TNT1 using 4:3 TV and 16:9 TV */
1543 			target->timing.h_sync_start = 744;		//do not change!
1544 			target->timing.h_sync_end = 744+144;	//delta is H_sync_pulse
1545 		}
1546 		else
1547 		{
1548 			/* confirmed on NV11 using 4:3 TV and 16:9 TV */
1549 			target->timing.h_sync_start = 728;		//do not change!
1550 			target->timing.h_sync_end = 728+160;	//delta is H_sync_pulse
1551 		}
1552 		target->timing.h_total = 888;			//BT H_TOTAL
1553 		target->timing.v_display = 480;			//V_ACTIVEI
1554 		target->timing.v_sync_start = 490;		//set for centered sync pulse
1555 		target->timing.v_sync_end = 490+26;		//delta is V_sync_pulse
1556 		target->timing.v_total = 525;			//CH V_TOTAL (== 525: 1:1 scaled mode)
1557 		target->timing.pixel_clock = ((888 * 525 * 60) / 1000); //refresh
1558 		break;
1559 	case PAL720:
1560 		target->timing.h_display = 720;			//BT H_ACTIVE
1561 		target->timing.h_sync_start = 744;		//set for centered sync pulse
1562 		target->timing.h_sync_end = 744+140;	//delta is BT H_BLANKI
1563 		target->timing.h_total = 888;			//BT H_CLKI
1564 		target->timing.v_display = 576;			//BT  V_ACTIVEI
1565 		target->timing.v_sync_start = 579;		//set for centered sync pulse
1566 		target->timing.v_sync_end = 579+42;		//delta is BT V_BLANKI
1567 		target->timing.v_total = 625;			//BT V_LINESI (== 625: 1:1 scaled mode)
1568 		target->timing.pixel_clock = ((888 * 625 * 50) / 1000); //refresh
1569 		break;
1570 	default:
1571 		return B_ERROR;
1572 	}
1573 
1574 	return B_OK;
1575 }//end BT_update_mode_for_gpu.
1576 
1577 /* note:
1578  * tested on ELSA Erazor III 32Mb AGP (TNT2/BT869),
1579  * Diamond Viper V550 16Mb PCI (TNT1/BT869),
1580  * and ASUS V7100 GeForce2 MX200 AGP/32Mb (CH7007). */
BT_start_tvout(display_mode tv_target)1581 static status_t BT_start_tvout(display_mode tv_target)
1582 {
1583 	/* TV_PRIMARY tells us that the head to be used with TVout is the head that's
1584 	 * actually assigned as being the primary head at powerup:
1585 	 * so non dualhead-mode-dependant, and not 'fixed' CRTC1! */
1586 	if (tv_target.flags & TV_PRIMARY)
1587 	{
1588 		if ((tv_target.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
1589 			head1_start_tvout();
1590 		else
1591 			head2_start_tvout();
1592 	}
1593 	else
1594 	{
1595 		if ((tv_target.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
1596 			head2_start_tvout();
1597 		else
1598 			head1_start_tvout();
1599 	}
1600 
1601 	return B_OK;
1602 }//end BT_start_tvout.
1603 
1604 /* note:
1605  * tested on ELSA Erazor III 32Mb AGP (TNT2/BT869),
1606  * Diamond Viper V550 16Mb PCI (TNT1/BT869),
1607  * and ASUS V7100 GeForce2 MX200 AGP/32Mb (CH7007). */
BT_stop_tvout(void)1608 status_t BT_stop_tvout(void)
1609 {
1610 	/* prevent BT from being overclocked by VGA-only modes & black-out TV-out */
1611 	BT_killclk_blackout();
1612 
1613 	/* TV_PRIMARY tells us that the head to be used with TVout is the head that's
1614 	 * actually assigned as being the primary head at powerup:
1615 	 * so non dualhead-mode-dependant, and not 'fixed' CRTC1! */
1616 	if (si->dm.flags & TV_PRIMARY)
1617 	{
1618 		if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
1619 			head1_stop_tvout();
1620 		else
1621 			head2_stop_tvout();
1622 	}
1623 	else
1624 	{
1625 		if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
1626 			head2_stop_tvout();
1627 		else
1628 			head1_stop_tvout();
1629 	}
1630 
1631 	/* fixme if needed:
1632 	 * a full encoder chip reset could be done here (so after decoupling crtc)... */
1633 	/* (but: beware of the 'locked SDA' syndrome then!) */
1634 
1635 	/* fixme if needed: we _could_ setup a TVout mode and apply the testsignal here... */
1636 	if (0)
1637 	{
1638 		//set mode (selecting PAL/NTSC according to board wiring for example) etc, then:
1639 		BT_testsignal();
1640 	}
1641 
1642 	return B_OK;
1643 }//end BT_stop_tvout.
1644 
BT_setmode(display_mode target)1645 status_t BT_setmode(display_mode target)
1646 {
1647 	uint8 tvmode, monstat;
1648 	/* enable flickerfilter in desktop modes, disable it in video modes. */
1649 	uint8 ffilter = 0;
1650 
1651 	/* use a display_mode copy because we might tune it for TVout compatibility */
1652 	display_mode tv_target = target;
1653 
1654 	/* preset new TVout mode */
1655 	tvmode = BT_check_tvmode(tv_target);
1656 	if (!tvmode) return B_ERROR;
1657 
1658 	/* read current output devices connection status */
1659 	BT_read_monstat(&monstat);
1660 
1661 	/* (pre)set TV mode */
1662 	/* note:
1663 	 * Manual config is non-dependent of the state of the PAL hardware input pin;
1664 	 * Also SDA lockups occur when setting EN_XCLK after autoconfig!
1665 	 * Make sure PAL_MD=0 for NTSC and PAL_MD = 1 for PAL... */
1666 	switch (tvmode)
1667 	{
1668 	case NTSC640:
1669 	case NTSC640_TST:
1670 		ffilter = 1;
1671 		BT_init_NTSC640();
1672 		break;
1673 	case NTSC800:
1674 		ffilter = 1;
1675 		BT_init_NTSC800();
1676 		break;
1677 	case PAL640:
1678 		ffilter = 1;
1679 		BT_init_PAL640();
1680 		break;
1681 	case PAL800:
1682 	case PAL800_TST:
1683 		ffilter = 1;
1684 		BT_init_PAL800();
1685 		break;
1686 	case NTSC640_OS:
1687 		BT_init_NTSC640_OS();
1688 		break;
1689 	case PAL800_OS:
1690 		BT_init_PAL800_OS();
1691 		break;
1692 	case NTSC720:
1693 		BT_init_NTSC720();
1694 		break;
1695 	case PAL720:
1696 		BT_init_PAL720();
1697 		break;
1698 	}
1699 
1700 	/* modify BT Hphase signal to center TV image... */
1701 	BT_setup_hphase(tvmode);
1702 
1703 	/* disable Macro mode */
1704 	switch (tvmode)
1705 	{
1706 	case NTSC640:
1707 	case NTSC640_TST:
1708 	case NTSC800:
1709 	case NTSC640_OS:
1710 	case NTSC720:
1711 		/* NTSC */
1712 		BT_set_macro (0, 0);
1713 		break;
1714 	default:
1715 		/* PAL */
1716 		BT_set_macro (1, 0);
1717 		break;
1718 	}
1719 
1720 	/* setup output signal routing and flickerfilter */
1721 	BT_setup_output(monstat, (uint8)(si->settings.tv_output), ffilter);
1722 
1723 	/* update the GPU CRTC timing for the requested mode */
1724 	BT_update_mode_for_gpu(&tv_target, tvmode);
1725 
1726 	/* setup GPU CRTC timing */
1727 	/* TV_PRIMARY tells us that the head to be used with TVout is the head that's
1728 	 * actually assigned as being the primary head at powerup:
1729 	 * so non dualhead-mode-dependant, and not 'fixed' CRTC1! */
1730 	if (tv_target.flags & TV_PRIMARY)
1731 	{
1732 		if ((tv_target.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
1733 			head1_set_timing(tv_target);
1734 		else
1735 			head2_set_timing(tv_target);
1736 	}
1737 	else
1738 	{
1739 		if ((tv_target.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
1740 			head2_set_timing(tv_target);
1741 		else
1742 			head1_set_timing(tv_target);
1743 	}
1744 
1745 	/* now set GPU CRTC to slave mode */
1746 	BT_start_tvout(tv_target);
1747 
1748 	return B_OK;
1749 }
1750