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