1 /* 2 * i2c interface. 3 * Bus should be run at max. 100kHz: see original Philips I2C specification 4 * 5 * Rudolf Cornelissen 12/2002-4/2021 6 */ 7 8 #define MODULE_BIT 0x00004000 9 10 #include "nv_std.h" 11 12 static void i2c_DumpSpecsEDID(edid_specs* specs); 13 14 char i2c_flag_error (char ErrNo) 15 //error code list: 16 //0 - OK status 17 //1 - SCL locked low by device (bus is still busy) 18 //2 - SDA locked low by device (bus is still busy) 19 //3 - No Acknowledge from device (no handshake) 20 //4 - SDA not released for master to generate STOP bit 21 { 22 static char I2CError = 0; 23 24 if (!I2CError) I2CError = ErrNo; 25 if (ErrNo == -1) I2CError = 0; 26 return I2CError; 27 } 28 29 static void i2c_select_bus_set(bool set) 30 { 31 /* I/O pins set selection is only valid on dualhead cards */ 32 if (!si->ps.secondary_head) return; 33 34 /* select GPU I/O pins set to connect to I2C 'registers' */ 35 if (set) { 36 /* this setup wires the 'I2C registers' to unknown I/O pins on the GPU? */ 37 NV_REG32(NV32_FUNCSEL) &= ~0x00000010; 38 NV_REG32(NV32_2FUNCSEL) |= 0x00000010; 39 } else { 40 /* this setup wires the 'I2C registers' to the I2C buses */ 41 NV_REG32(NV32_2FUNCSEL) &= ~0x00000010; 42 NV_REG32(NV32_FUNCSEL) |= 0x00000010; 43 } 44 } 45 46 static void OutSCL(uint8 BusNR, bool Bit) 47 { 48 uint8 data; 49 uint32 data32; 50 51 if ((CFGR(DEVID) & 0xfff0ffff) == 0x024010de) { 52 /* C51 chipset */ 53 switch (BusNR) { 54 case 0: 55 data32 = NV_REG32(NV32_NV4E_I2CBUS_0) & ~0x2f; 56 if (Bit) 57 NV_REG32(NV32_NV4E_I2CBUS_0) = data32 | 0x21; 58 else 59 NV_REG32(NV32_NV4E_I2CBUS_0) = data32 | 0x01; 60 break; 61 case 1: 62 data32 = NV_REG32(NV32_NV4E_I2CBUS_1) & ~0x2f; 63 if (Bit) 64 NV_REG32(NV32_NV4E_I2CBUS_1) = data32 | 0x21; 65 else 66 NV_REG32(NV32_NV4E_I2CBUS_1) = data32 | 0x01; 67 break; 68 case 2: 69 data32 = NV_REG32(NV32_NV4E_I2CBUS_2) & ~0x2f; 70 if (Bit) 71 NV_REG32(NV32_NV4E_I2CBUS_2) = data32 | 0x21; 72 else 73 NV_REG32(NV32_NV4E_I2CBUS_2) = data32 | 0x01; 74 break; 75 } 76 } else { 77 switch (BusNR) { 78 case 0: 79 data = (CRTCR(WR_I2CBUS_0) & 0xf0) | 0x01; 80 if (Bit) 81 CRTCW(WR_I2CBUS_0, (data | 0x20)); 82 else 83 CRTCW(WR_I2CBUS_0, (data & ~0x20)); 84 break; 85 case 1: 86 data = (CRTCR(WR_I2CBUS_1) & 0xf0) | 0x01; 87 if (Bit) 88 CRTCW(WR_I2CBUS_1, (data | 0x20)); 89 else 90 CRTCW(WR_I2CBUS_1, (data & ~0x20)); 91 break; 92 case 2: 93 data = (CRTCR(WR_I2CBUS_2) & 0xf0) | 0x01; 94 if (Bit) 95 CRTCW(WR_I2CBUS_2, (data | 0x20)); 96 else 97 CRTCW(WR_I2CBUS_2, (data & ~0x20)); 98 break; 99 } 100 } 101 } 102 103 static void OutSDA(uint8 BusNR, bool Bit) 104 { 105 uint8 data; 106 uint32 data32; 107 108 if ((CFGR(DEVID) & 0xfff0ffff) == 0x024010de) { 109 /* C51 chipset */ 110 switch (BusNR) { 111 case 0: 112 data32 = NV_REG32(NV32_NV4E_I2CBUS_0) & ~0x1f; 113 if (Bit) 114 NV_REG32(NV32_NV4E_I2CBUS_0) = data32 | 0x11; 115 else 116 NV_REG32(NV32_NV4E_I2CBUS_0) = data32 | 0x01; 117 break; 118 case 1: 119 data32 = NV_REG32(NV32_NV4E_I2CBUS_1) & ~0x1f; 120 if (Bit) 121 NV_REG32(NV32_NV4E_I2CBUS_1) = data32 | 0x11; 122 else 123 NV_REG32(NV32_NV4E_I2CBUS_1) = data32 | 0x01; 124 break; 125 case 2: 126 data32 = NV_REG32(NV32_NV4E_I2CBUS_2) & ~0x1f; 127 if (Bit) 128 NV_REG32(NV32_NV4E_I2CBUS_2) = data32 | 0x11; 129 else 130 NV_REG32(NV32_NV4E_I2CBUS_2) = data32 | 0x01; 131 break; 132 } 133 } else { 134 switch (BusNR) { 135 case 0: 136 data = (CRTCR(WR_I2CBUS_0) & 0xf0) | 0x01; 137 if (Bit) 138 CRTCW(WR_I2CBUS_0, (data | 0x10)); 139 else 140 CRTCW(WR_I2CBUS_0, (data & ~0x10)); 141 break; 142 case 1: 143 data = (CRTCR(WR_I2CBUS_1) & 0xf0) | 0x01; 144 if (Bit) 145 CRTCW(WR_I2CBUS_1, (data | 0x10)); 146 else 147 CRTCW(WR_I2CBUS_1, (data & ~0x10)); 148 break; 149 case 2: 150 data = (CRTCR(WR_I2CBUS_2) & 0xf0) | 0x01; 151 if (Bit) 152 CRTCW(WR_I2CBUS_2, (data | 0x10)); 153 else 154 CRTCW(WR_I2CBUS_2, (data & ~0x10)); 155 break; 156 } 157 } 158 } 159 160 static bool InSCL(uint8 BusNR) 161 { 162 if ((CFGR(DEVID) & 0xfff0ffff) == 0x024010de) { 163 /* C51 chipset */ 164 switch (BusNR) { 165 case 0: 166 if (NV_REG32(NV32_NV4E_I2CBUS_0) & 0x00040000) return true; 167 break; 168 case 1: 169 if (NV_REG32(NV32_NV4E_I2CBUS_1) & 0x00040000) return true; 170 break; 171 case 2: 172 if (NV_REG32(NV32_NV4E_I2CBUS_2) & 0x00040000) return true; 173 break; 174 } 175 } else { 176 switch (BusNR) { 177 case 0: 178 if ((CRTCR(RD_I2CBUS_0) & 0x04)) return true; 179 break; 180 case 1: 181 if ((CRTCR(RD_I2CBUS_1) & 0x04)) return true; 182 break; 183 case 2: 184 if ((CRTCR(RD_I2CBUS_2) & 0x04)) return true; 185 break; 186 } 187 } 188 189 return false; 190 } 191 192 static bool InSDA(uint8 BusNR) 193 { 194 if ((CFGR(DEVID) & 0xfff0ffff) == 0x024010de) { 195 /* C51 chipset */ 196 switch (BusNR) { 197 case 0: 198 if (NV_REG32(NV32_NV4E_I2CBUS_0) & 0x00080000) return true; 199 break; 200 case 1: 201 if (NV_REG32(NV32_NV4E_I2CBUS_1) & 0x00080000) return true; 202 break; 203 case 2: 204 if (NV_REG32(NV32_NV4E_I2CBUS_2) & 0x00080000) return true; 205 break; 206 } 207 } else { 208 switch (BusNR) { 209 case 0: 210 if ((CRTCR(RD_I2CBUS_0) & 0x08)) return true; 211 break; 212 case 1: 213 if ((CRTCR(RD_I2CBUS_1) & 0x08)) return true; 214 break; 215 case 2: 216 if ((CRTCR(RD_I2CBUS_2) & 0x08)) return true; 217 break; 218 } 219 } 220 221 return false; 222 } 223 224 static void TXBit (uint8 BusNR, bool Bit) 225 { 226 /* send out databit */ 227 if (Bit) { 228 OutSDA(BusNR, true); 229 snooze(3); 230 if (!InSDA(BusNR)) i2c_flag_error (2); 231 } else { 232 OutSDA(BusNR, false); 233 } 234 /* generate clock pulse */ 235 snooze(6); 236 OutSCL(BusNR, true); 237 snooze(3); 238 if (!InSCL(BusNR)) i2c_flag_error (1); 239 snooze(6); 240 OutSCL(BusNR, false); 241 snooze(6); 242 } 243 244 static uint8 RXBit (uint8 BusNR) 245 { 246 uint8 Bit = 0; 247 248 /* set SDA so input is possible */ 249 OutSDA(BusNR, true); 250 /* generate clock pulse */ 251 snooze(6); 252 OutSCL(BusNR, true); 253 snooze(3); 254 if (!InSCL(BusNR)) i2c_flag_error (1); 255 snooze(3); 256 /* read databit */ 257 if (InSDA(BusNR)) Bit = 1; 258 /* finish clockpulse */ 259 OutSCL(BusNR, false); 260 snooze(6); 261 262 return Bit; 263 } 264 265 void i2c_bstart (uint8 BusNR) 266 { 267 /* enable access to primary head */ 268 set_crtc_owner(0); 269 270 /* make sure SDA is high */ 271 OutSDA(BusNR, true); 272 snooze(3); 273 OutSCL(BusNR, true); 274 snooze(3); 275 if (!InSCL(BusNR)) i2c_flag_error (1); 276 snooze(6); 277 /* clear SDA while SCL set (bus-start condition) */ 278 OutSDA(BusNR, false); 279 snooze(6); 280 OutSCL(BusNR, false); 281 snooze(6); 282 283 LOG(4,("I2C: START condition generated on bus %d; status is %d\n", 284 BusNR, i2c_flag_error (0))); 285 } 286 287 void i2c_bstop (uint8 BusNR) 288 { 289 /* enable access to primary head */ 290 set_crtc_owner(0); 291 292 /* make sure SDA is low */ 293 OutSDA(BusNR, false); 294 snooze(3); 295 OutSCL(BusNR, true); 296 snooze(3); 297 if (!InSCL(BusNR)) i2c_flag_error (1); 298 snooze(6); 299 /* set SDA while SCL set (bus-stop condition) */ 300 OutSDA(BusNR, true); 301 snooze(3); 302 if (!InSDA(BusNR)) i2c_flag_error (4); 303 snooze(3); 304 305 LOG(4,("I2C: STOP condition generated on bus %d; status is %d\n", 306 BusNR, i2c_flag_error (0))); 307 } 308 309 uint8 i2c_readbyte(uint8 BusNR, bool Ack) 310 { 311 uint8 cnt, bit, byte = 0; 312 313 /* enable access to primary head */ 314 set_crtc_owner(0); 315 316 /* read data */ 317 for (cnt = 8; cnt > 0; cnt--) { 318 byte <<= 1; 319 bit = RXBit (BusNR); 320 byte += bit; 321 } 322 /* send acknowledge */ 323 TXBit (BusNR, Ack); 324 325 LOG(4,("I2C: read byte ($%02x) from bus #%d; status is %d\n", 326 byte, BusNR, i2c_flag_error(0))); 327 328 return byte; 329 } 330 331 bool i2c_writebyte (uint8 BusNR, uint8 byte) 332 { 333 uint8 cnt; 334 bool bit; 335 uint8 tmp = byte; 336 337 /* enable access to primary head */ 338 set_crtc_owner(0); 339 340 /* write data */ 341 for (cnt = 8; cnt > 0; cnt--) { 342 bit = (tmp & 0x80); 343 TXBit (BusNR, bit); 344 tmp <<= 1; 345 } 346 /* read acknowledge */ 347 bit = RXBit (BusNR); 348 if (bit) i2c_flag_error (3); 349 350 LOG(4,("I2C: written byte ($%02x) to bus #%d; status is %d\n", 351 byte, BusNR, i2c_flag_error(0))); 352 353 return bit; 354 } 355 356 void i2c_readbuffer (uint8 BusNR, uint8* buf, uint8 size) 357 { 358 uint8 cnt; 359 360 for (cnt = 0; cnt < size; cnt++) 361 buf[cnt] = i2c_readbyte(BusNR, buf[cnt]); 362 } 363 364 void i2c_writebuffer (uint8 BusNR, uint8* buf, uint8 size) 365 { 366 uint8 cnt; 367 368 for (cnt = 0; cnt < size; cnt++) 369 i2c_writebyte(BusNR, buf[cnt]); 370 } 371 372 status_t i2c_init(void) 373 { 374 uint8 bus, buses; 375 bool *i2c_bus = &(si->ps.i2c_bus0); 376 status_t result = B_ERROR; 377 378 LOG(4,("I2C: searching for wired I2C buses...\n")); 379 380 /* select GPU I/O pins for I2C buses */ 381 i2c_select_bus_set(false); 382 383 /* enable access to primary head */ 384 set_crtc_owner(0); 385 386 /* on some NV40 architecture cards the i2c busses can be disabled: enable them */ 387 if (si->ps.card_arch == NV40A) 388 CRTCW(I2C_LOCK ,(CRTCR(I2C_LOCK) | 0x04)); 389 390 /* preset no board wired buses */ 391 si->ps.i2c_bus0 = false; 392 si->ps.i2c_bus1 = false; 393 si->ps.i2c_bus2 = false; 394 395 /* set number of buses to test for */ 396 buses = 2; 397 398 /* newer cards (can) have a third bus.. */ 399 if (((si->ps.card_arch == NV10A) && (si->ps.card_type >= NV17)) || (si->ps.card_arch >= NV30A)) 400 buses = 3; 401 402 /* find existing buses */ 403 for (bus = 0; bus < buses; bus++) { 404 /* reset status */ 405 i2c_flag_error (-1); 406 snooze(6); 407 /* init and/or stop I2C bus */ 408 i2c_bstop(bus); 409 /* check for hardware coupling of SCL and SDA -out and -in lines */ 410 snooze(6); 411 OutSCL(bus, false); 412 snooze(3); 413 OutSDA(bus, true); 414 snooze(3); 415 if (InSCL(bus) || !InSDA(bus)) continue; 416 snooze(3); 417 OutSCL(bus, true); 418 snooze(3); 419 OutSDA(bus, false); 420 snooze(3); 421 if (!InSCL(bus) || InSDA(bus)) continue; 422 i2c_bus[bus] = true; 423 snooze(3); 424 /* re-init bus */ 425 i2c_bstop(bus); 426 } 427 428 for (bus = 0; bus < buses; bus++) { 429 if (i2c_bus[bus]) { 430 LOG(4,("I2C: bus #%d wiring check: passed\n", bus)); 431 result = B_OK; 432 } else { 433 LOG(4,("I2C: bus #%d wiring check: failed\n", bus)); 434 } 435 } 436 437 i2c_DetectScreens(); 438 LOG(4,("I2C: dumping EDID specs for connector 1:\n")); 439 i2c_DumpSpecsEDID(&si->ps.con1_screen); 440 LOG(4,("I2C: dumping EDID specs for connector 2:\n")); 441 i2c_DumpSpecsEDID(&si->ps.con2_screen); 442 443 return result; 444 } 445 446 /*** DDC/EDID library use ***/ 447 typedef struct { 448 uint8 port; 449 } ddc_port_info; 450 451 /* Dump EDID info in driver's logfile */ 452 static void 453 i2c_DumpEDID(edid1_info *edid) 454 { 455 int i, j; 456 457 LOG(4,("Vendor: %s\n", edid->vendor.manufacturer)); 458 LOG(4,("Product ID: %d\n", (int)edid->vendor.prod_id)); 459 LOG(4,("Serial #: %d\n", (int)edid->vendor.serial)); 460 LOG(4,("Produced in week/year: %d/%d\n", edid->vendor.week, edid->vendor.year)); 461 462 LOG(4,("EDID version: %d.%d\n", edid->version.version, edid->version.revision)); 463 464 LOG(4,("Type: %s\n", edid->display.input_type ? "Digital" : "Analog")); 465 LOG(4,("Size: %d cm x %d cm\n", edid->display.h_size, edid->display.v_size)); 466 LOG(4,("Gamma=%.3f\n", (edid->display.gamma + 100) / 100.0)); 467 LOG(4,("White (X,Y)=(%.3f,%.3f)\n", edid->display.white_x / 1024.0, 468 edid->display.white_y / 1024.0)); 469 470 LOG(4,("Supported Future Video Modes:\n")); 471 for (i = 0; i < EDID1_NUM_STD_TIMING; ++i) { 472 if (edid->std_timing[i].h_size <= 256) 473 continue; 474 475 LOG(4,("%dx%d@%dHz (id=%d)\n", 476 edid->std_timing[i].h_size, edid->std_timing[i].v_size, 477 edid->std_timing[i].refresh, edid->std_timing[i].id)); 478 } 479 480 LOG(4,("Supported VESA Video Modes:\n")); 481 if (edid->established_timing.res_720x400x70) 482 LOG(4,("720x400@70\n")); 483 if (edid->established_timing.res_720x400x88) 484 LOG(4,("720x400@88\n")); 485 if (edid->established_timing.res_640x480x60) 486 LOG(4,("640x480@60\n")); 487 if (edid->established_timing.res_640x480x67) 488 LOG(4,("640x480x67\n")); 489 if (edid->established_timing.res_640x480x72) 490 LOG(4,("640x480x72\n")); 491 if (edid->established_timing.res_640x480x75) 492 LOG(4,("640x480x75\n")); 493 if (edid->established_timing.res_800x600x56) 494 LOG(4,("800x600@56\n")); 495 if (edid->established_timing.res_800x600x60) 496 LOG(4,("800x600@60\n")); 497 498 if (edid->established_timing.res_800x600x72) 499 LOG(4,("800x600@72\n")); 500 if (edid->established_timing.res_800x600x75) 501 LOG(4,("800x600@75\n")); 502 if (edid->established_timing.res_832x624x75) 503 LOG(4,("832x624@75\n")); 504 if (edid->established_timing.res_1024x768x87i) 505 LOG(4,("1024x768@87 interlaced\n")); 506 if (edid->established_timing.res_1024x768x60) 507 LOG(4,("1024x768@60\n")); 508 if (edid->established_timing.res_1024x768x70) 509 LOG(4,("1024x768@70\n")); 510 if (edid->established_timing.res_1024x768x75) 511 LOG(4,("1024x768@75\n")); 512 if (edid->established_timing.res_1280x1024x75) 513 LOG(4,("1280x1024@75\n")); 514 515 if (edid->established_timing.res_1152x870x75) 516 LOG(4,("1152x870@75\n")); 517 518 for (i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) { 519 edid1_detailed_monitor *monitor = &edid->detailed_monitor[i]; 520 521 switch(monitor->monitor_desc_type) { 522 case EDID1_SERIAL_NUMBER: 523 LOG(4,("Serial Number: %s\n", monitor->data.serial_number)); 524 break; 525 526 case EDID1_ASCII_DATA: 527 LOG(4,("Ascii Data: %s\n", monitor->data.ascii_data)); 528 break; 529 530 case EDID1_MONITOR_RANGES: 531 { 532 edid1_monitor_range monitor_range = monitor->data.monitor_range; 533 534 LOG(4,("Horizontal frequency range = %d..%d kHz\n", 535 monitor_range.min_h, monitor_range.max_h)); 536 LOG(4,("Vertical frequency range = %d..%d Hz\n", 537 monitor_range.min_v, monitor_range.max_v)); 538 LOG(4,("Maximum pixel clock = %d MHz\n", (uint16)monitor_range.max_clock * 10)); 539 break; 540 } 541 542 case EDID1_MONITOR_NAME: 543 LOG(4,("Monitor Name: %s\n", monitor->data.monitor_name)); 544 break; 545 546 case EDID1_ADD_COLOUR_POINTER: 547 { 548 for (j = 0; j < EDID1_NUM_EXTRA_WHITEPOINTS; ++j) { 549 edid1_whitepoint *whitepoint = &monitor->data.whitepoint[j]; 550 551 if (whitepoint->index == 0) 552 continue; 553 554 LOG(4,("Additional whitepoint: (X,Y)=(%f,%f) gamma=%f index=%i\n", 555 whitepoint->white_x / 1024.0, 556 whitepoint->white_y / 1024.0, 557 (whitepoint->gamma + 100) / 100.0, 558 whitepoint->index)); 559 } 560 break; 561 } 562 563 case EDID1_ADD_STD_TIMING: 564 { 565 for (j = 0; j < EDID1_NUM_EXTRA_STD_TIMING; ++j) { 566 edid1_std_timing *timing = &monitor->data.std_timing[j]; 567 568 if (timing->h_size <= 256) 569 continue; 570 571 LOG(4,("%dx%d@%dHz (id=%d)\n", 572 timing->h_size, timing->v_size, 573 timing->refresh, timing->id)); 574 } 575 break; 576 } 577 578 case EDID1_IS_DETAILED_TIMING: 579 { 580 edid1_detailed_timing *timing = &monitor->data.detailed_timing; 581 582 LOG(4,("Additional Video Mode:\n")); 583 LOG(4,("clock=%f MHz\n", timing->pixel_clock / 100.0)); 584 LOG(4,("h: (%d, %d, %d, %d)\n", 585 timing->h_active, timing->h_active + timing->h_sync_off, 586 timing->h_active + timing->h_sync_off + timing->h_sync_width, 587 timing->h_active + timing->h_blank)); 588 LOG(4,("v: (%d, %d, %d, %d)\n", 589 timing->v_active, timing->v_active + timing->v_sync_off, 590 timing->v_active + timing->v_sync_off + timing->v_sync_width, 591 timing->v_active + timing->v_blank)); 592 LOG(4,("size: %.1f cm x %.1f cm\n", 593 timing->h_size / 10.0, timing->v_size / 10.0)); 594 LOG(4,("border: %.1f cm x %.1f cm\n", 595 timing->h_border / 10.0, timing->v_border / 10.0)); 596 break; 597 } 598 } 599 } 600 } 601 602 /* callback for getting signals from I2C bus */ 603 static status_t 604 get_signals(void *cookie, int *clk, int *data) 605 { 606 ddc_port_info *info = (ddc_port_info *)cookie; 607 608 *clk = *data = 0x0000; 609 if (InSCL(info->port)) *clk = 0x0001; 610 if (InSDA(info->port)) *data = 0x0001; 611 612 return B_OK; 613 } 614 615 /* callback for setting signals on I2C bus */ 616 static status_t 617 set_signals(void *cookie, int clk, int data) 618 { 619 ddc_port_info *info = (ddc_port_info *)cookie; 620 621 if (clk) 622 OutSCL(info->port, true); 623 else 624 OutSCL(info->port, false); 625 626 if (data) 627 OutSDA(info->port, true); 628 else 629 OutSDA(info->port, false); 630 631 return B_OK; 632 } 633 634 /* Read EDID information from monitor via the display data channel (DDC) */ 635 static status_t 636 i2c_ReadEDID(uint8 BusNR, edid1_info *edid) 637 { 638 i2c_bus bus; 639 ddc_port_info info; 640 641 info.port = BusNR; 642 643 bus.cookie = &info; 644 bus.set_signals = &set_signals; 645 bus.get_signals = &get_signals; 646 ddc2_init_timing(&bus); 647 648 /* select GPU I/O pins for I2C buses */ 649 i2c_select_bus_set(false); 650 651 /* enable access to primary head */ 652 set_crtc_owner(0); 653 654 if (ddc2_read_edid1(&bus, edid, NULL, NULL) == B_OK) { 655 LOG(4,("I2C: EDID succesfully read from monitor at bus %d\n", BusNR)); 656 LOG(4,("I2C: EDID dump follows (bus %d):\n", BusNR)); 657 i2c_DumpEDID(edid); 658 LOG(4,("I2C: end EDID dump (bus %d).\n", BusNR)); 659 } else { 660 LOG(4,("I2C: reading EDID failed at bus %d!\n", BusNR)); 661 return B_ERROR; 662 } 663 664 return B_OK; 665 } 666 667 void i2c_TestEDID(void) 668 { 669 uint8 bus; 670 edid1_info edid; 671 bool *i2c_bus = &(si->ps.i2c_bus0); 672 673 /* test wired bus(es) */ 674 for (bus = 0; bus < 3; bus++) { 675 if (i2c_bus[bus]) 676 i2c_ReadEDID(bus, &edid); 677 } 678 } 679 680 static status_t 681 i2c_ExtractSpecsEDID(edid1_info* edid, edid_specs* specs) 682 { 683 uint32 i; 684 edid1_detailed_timing edid_timing; 685 686 specs->have_full_edid = false; 687 specs->have_native_edid = false; 688 specs->timing.h_display = 0; 689 specs->timing.v_display = 0; 690 691 /* find the optimum (native) modeline */ 692 for (i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) { 693 switch(edid->detailed_monitor[i].monitor_desc_type) { 694 case EDID1_IS_DETAILED_TIMING: 695 // TODO: handle flags correctly! 696 edid_timing = edid->detailed_monitor[i].data.detailed_timing; 697 698 if (edid_timing.pixel_clock <= 0/* || edid_timing.sync != 3*/) 699 break; 700 701 /* we want the optimum (native) modeline only, widescreen if possible. 702 * So only check for horizontal display, not for vertical display. */ 703 if (edid_timing.h_active <= specs->timing.h_display) 704 break; 705 706 specs->timing.pixel_clock = edid_timing.pixel_clock * 10; 707 specs->timing.h_display = edid_timing.h_active; 708 specs->timing.h_sync_start = edid_timing.h_active + edid_timing.h_sync_off; 709 specs->timing.h_sync_end = specs->timing.h_sync_start + edid_timing.h_sync_width; 710 specs->timing.h_total = specs->timing.h_display + edid_timing.h_blank; 711 specs->timing.v_display = edid_timing.v_active; 712 specs->timing.v_sync_start = edid_timing.v_active + edid_timing.v_sync_off; 713 specs->timing.v_sync_end = specs->timing.v_sync_start + edid_timing.v_sync_width; 714 specs->timing.v_total = specs->timing.v_display + edid_timing.v_blank; 715 specs->timing.flags = 0; 716 if (edid_timing.sync == 3) { 717 if (edid_timing.misc & 1) 718 specs->timing.flags |= B_POSITIVE_HSYNC; 719 if (edid_timing.misc & 2) 720 specs->timing.flags |= B_POSITIVE_VSYNC; 721 } 722 if (edid_timing.interlaced) 723 specs->timing.flags |= B_TIMING_INTERLACED; 724 break; 725 } 726 } 727 728 /* check if we actually got a modeline */ 729 if (!specs->timing.h_display || !specs->timing.v_display) return B_ERROR; 730 731 /* check if the mode is at least VGA. If it's not, ignore specs */ 732 if ((specs->timing.h_display < 640) || (specs->timing.v_display < 480)) { 733 LOG(4,("I2C: specsEDID: screen reports lower than VGA native mode, ignoring specs!\n")); 734 return B_ERROR; 735 } 736 737 /* determine screen aspect ratio */ 738 specs->aspect = 739 (specs->timing.h_display / ((float)specs->timing.v_display)); 740 741 /* determine connection type */ 742 specs->digital = false; 743 if (edid->display.input_type) specs->digital = true; 744 745 /* and also copy full edid1_info for reference */ 746 memcpy(&(specs->full_edid), edid, sizeof(specs->full_edid)); 747 748 /* we succesfully fetched the specs we need */ 749 specs->have_native_edid = true; 750 /* we also got full and valid EDID via DDC */ 751 specs->have_full_edid = true; 752 753 return B_OK; 754 } 755 756 /* Dump EDID info in driver's logfile */ 757 static void 758 i2c_DumpSpecsEDID(edid_specs* specs) 759 { 760 LOG(4,("I2C: specsEDID: have_native_edid: %s\n", specs->have_native_edid ? "True" : "False")); 761 if (!specs->have_native_edid) return; 762 LOG(4,("I2C: specsEDID: timing.pixel_clock %.3f Mhz\n", specs->timing.pixel_clock / 1000.0)); 763 LOG(4,("I2C: specsEDID: timing.h_display %d\n", specs->timing.h_display)); 764 LOG(4,("I2C: specsEDID: timing.h_sync_start %d\n", specs->timing.h_sync_start)); 765 LOG(4,("I2C: specsEDID: timing.h_sync_end %d\n", specs->timing.h_sync_end)); 766 LOG(4,("I2C: specsEDID: timing.h_total %d\n", specs->timing.h_total)); 767 LOG(4,("I2C: specsEDID: timing.v_display %d\n", specs->timing.v_display)); 768 LOG(4,("I2C: specsEDID: timing.v_sync_start %d\n", specs->timing.v_sync_start)); 769 LOG(4,("I2C: specsEDID: timing.v_sync_end %d\n", specs->timing.v_sync_end)); 770 LOG(4,("I2C: specsEDID: timing.v_total %d\n", specs->timing.v_total)); 771 LOG(4,("I2C: specsEDID: timing.flags $%08x\n", specs->timing.flags)); 772 LOG(4,("I2C: specsEDID: aspect: %1.2f\n", specs->aspect)); 773 LOG(4,("I2C: specsEDID: digital: %s\n", specs->digital ? "True" : "False")); 774 } 775 776 /* notes: 777 * - con1 resides closest to the mainboard on for example NV25 and NV28, while for 778 * example on NV34 con2 sits closest to the mainboard. 779 * - i2c bus0 is connected to con1, and i2c bus1 is connected to con2 on all pre-NV40 780 * architecture cards. On later cards it's vice versa. These connections do not depend 781 * on the analog VGA switch setting (see nv_general_output_select()). It also does 782 * not depend on the way screens are connected to the cards (DVI/VGA, 1 or 2 screens). 783 * - on some NV40 architecture cards i2c bus2 connects to con2 instead of i2c bus0. This 784 * is confirmed on GeForce FX 6600 (NV43, id 0x0141) and GeForce 7300 (G72, id 0x01d1). 785 * - on pre-NV40 laptops i2c bus2 can connect to con2 as well: confirmed on a Geforce FX 786 * 5200 Go (NV34, id 0x0324). 787 * - con1 has CRTC1 and DAC1, and con2 has CRTC2 and DAC2 if nv_general_output_select() 788 * is set to 'straight' and there are only VGA type screens connected. */ 789 void i2c_DetectScreens(void) 790 { 791 edid1_info edid; 792 793 si->ps.con1_screen.have_native_edid = false; 794 si->ps.con2_screen.have_native_edid = false; 795 si->ps.con1_screen.have_full_edid = false; 796 si->ps.con2_screen.have_full_edid = false; 797 si->ps.con1_screen.aspect = 0; 798 si->ps.con2_screen.aspect = 0; 799 800 /* check existance of bus 0 */ 801 if (si->ps.i2c_bus0) { 802 /* check I2C bus 0 for an EDID capable screen */ 803 if (i2c_ReadEDID(0, &edid) == B_OK) { 804 /* fetch optimum (native) modeline */ 805 switch (si->ps.card_arch) { 806 case NV40A: 807 i2c_ExtractSpecsEDID(&edid, &si->ps.con2_screen); 808 break; 809 default: 810 i2c_ExtractSpecsEDID(&edid, &si->ps.con1_screen); 811 break; 812 } 813 } 814 } 815 816 /* check existance of bus 1 */ 817 if (si->ps.i2c_bus1) { 818 /* check I2C bus 1 for an EDID screen */ 819 if (i2c_ReadEDID(1, &edid) == B_OK) { 820 /* fetch optimum (native) modeline */ 821 switch (si->ps.card_arch) { 822 case NV40A: 823 i2c_ExtractSpecsEDID(&edid, &si->ps.con1_screen); 824 break; 825 default: 826 i2c_ExtractSpecsEDID(&edid, &si->ps.con2_screen); 827 break; 828 } 829 } 830 } 831 832 /* check existance of bus 2 */ 833 if (si->ps.i2c_bus2) { 834 /* check I2C bus 2 for an EDID screen */ 835 if (i2c_ReadEDID(2, &edid) == B_OK) { 836 /* fetch optimum (native) modeline */ 837 switch (si->ps.card_arch) { 838 case NV40A: 839 if (!si->ps.con2_screen.have_native_edid) { 840 i2c_ExtractSpecsEDID(&edid, &si->ps.con2_screen); 841 } else { 842 LOG(4,("I2C: DetectScreens: WARNING, unexpected behaviour detected!\n")); 843 } 844 break; 845 default: 846 if (!si->ps.con2_screen.have_native_edid && si->ps.laptop) { 847 i2c_ExtractSpecsEDID(&edid, &si->ps.con2_screen); 848 } else { 849 LOG(4,("I2C: DetectScreens: WARNING, unexpected behaviour detected!\n")); 850 } 851 break; 852 } 853 } 854 } 855 } 856