1 /* 2 * Copyright 2006-2015, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 * Michael Lotz, mmlr@mlotz.ch 8 * Alexander von Gluck IV, kallisti5@unixzen.com 9 */ 10 11 12 #include "Ports.h" 13 14 #include <ddc.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <Debug.h> 18 #include <KernelExport.h> 19 20 #include "accelerant.h" 21 #include "accelerant_protos.h" 22 #include "FlexibleDisplayInterface.h" 23 #include "intel_extreme.h" 24 #include "PanelFitter.h" 25 26 #include <new> 27 28 29 #undef TRACE 30 #define TRACE_PORTS 31 #ifdef TRACE_PORTS 32 # define TRACE(x...) _sPrintf("intel_extreme: " x) 33 #else 34 # define TRACE(x...) 35 #endif 36 37 #define ERROR(x...) _sPrintf("intel_extreme: " x) 38 #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__) 39 40 41 static bool 42 wait_for_set(addr_t address, uint32 mask, uint32 timeout) 43 { 44 int interval = 50; 45 uint32 i = 0; 46 for(i = 0; i <= timeout; i += interval) { 47 spin(interval); 48 if ((read32(address) & mask) != 0) 49 return true; 50 } 51 return false; 52 } 53 54 55 static bool 56 wait_for_clear(addr_t address, uint32 mask, uint32 timeout) 57 { 58 int interval = 50; 59 uint32 i = 0; 60 for(i = 0; i <= timeout; i += interval) { 61 spin(interval); 62 if ((read32(address) & mask) == 0) 63 return true; 64 } 65 return false; 66 } 67 68 69 Port::Port(port_index index, const char* baseName) 70 : 71 fPipe(NULL), 72 fEDIDState(B_NO_INIT), 73 fPortIndex(index), 74 fPortName(NULL) 75 { 76 char portID[2]; 77 portID[0] = 'A' + index - INTEL_PORT_A; 78 portID[1] = 0; 79 80 char buffer[32]; 81 buffer[0] = 0; 82 83 strlcat(buffer, baseName, sizeof(buffer)); 84 strlcat(buffer, " ", sizeof(buffer)); 85 strlcat(buffer, portID, sizeof(buffer)); 86 fPortName = strdup(buffer); 87 } 88 89 90 Port::~Port() 91 { 92 free(fPortName); 93 } 94 95 96 bool 97 Port::HasEDID() 98 { 99 if (fEDIDState == B_NO_INIT) 100 GetEDID(NULL); 101 102 return fEDIDState == B_OK; 103 } 104 105 106 status_t 107 Port::SetPipe(Pipe* pipe) 108 { 109 CALLED(); 110 111 if (pipe == NULL) { 112 ERROR("%s: Invalid pipe provided!\n", __func__); 113 return B_ERROR; 114 } 115 116 uint32 portRegister = _PortRegister(); 117 if (portRegister == 0) { 118 ERROR("%s: Invalid PortRegister ((0x%" B_PRIx32 ") for %s\n", __func__, 119 portRegister, PortName()); 120 return B_ERROR; 121 } 122 123 // TODO: UnAssignPipe? This likely needs reworked a little 124 if (fPipe != NULL) { 125 ERROR("%s: Can't reassign display pipe (yet)\n", __func__); 126 return B_ERROR; 127 } 128 129 switch (pipe->Index()) { 130 case INTEL_PIPE_B: 131 TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe B\n", __func__, 132 PortName(), portRegister); 133 break; 134 case INTEL_PIPE_C: 135 TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe C\n", __func__, 136 PortName(), portRegister); 137 break; 138 case INTEL_PIPE_D: 139 TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe D\n", __func__, 140 PortName(), portRegister); 141 break; 142 default: 143 TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe A\n", __func__, 144 PortName(), portRegister); 145 break; 146 } 147 148 uint32 portState = read32(portRegister); 149 150 // FIXME is the use of PORT_TRANS_* constants correct for Sandy Bridge / 151 // Cougar Point? Or is it only for Ivy Bridge / Panther point onwards? 152 if (gInfo->shared_info->pch_info == INTEL_PCH_CPT) { 153 portState &= ~PORT_TRANS_SEL_MASK; 154 if (pipe->Index() == INTEL_PIPE_A) 155 write32(portRegister, portState | PORT_TRANS_A_SEL_CPT); 156 else 157 write32(portRegister, portState | PORT_TRANS_B_SEL_CPT); 158 } else { 159 if (pipe->Index() == INTEL_PIPE_A) 160 write32(portRegister, portState & ~DISPLAY_MONITOR_PIPE_B); 161 else 162 write32(portRegister, portState | DISPLAY_MONITOR_PIPE_B); 163 } 164 fPipe = pipe; 165 166 if (fPipe == NULL) 167 return B_NO_MEMORY; 168 169 // Disable display pipe until modesetting enables it 170 if (fPipe->IsEnabled()) 171 fPipe->Enable(false); 172 173 read32(portRegister); 174 175 return B_OK; 176 } 177 178 179 status_t 180 Port::Power(bool enabled) 181 { 182 if (fPipe == NULL) { 183 ERROR("%s: Setting power mode without assigned pipe!\n", __func__); 184 return B_ERROR; 185 } 186 187 fPipe->Enable(enabled); 188 189 return B_OK; 190 } 191 192 193 status_t 194 Port::GetEDID(edid1_info* edid, bool forceRead) 195 { 196 CALLED(); 197 198 if (fEDIDState == B_NO_INIT || forceRead) { 199 TRACE("%s: trying to read EDID\n", PortName()); 200 201 addr_t ddcRegister = _DDCRegister(); 202 if (ddcRegister == 0) { 203 TRACE("%s: no DDC register found\n", PortName()); 204 fEDIDState = B_ERROR; 205 return fEDIDState; 206 } 207 208 TRACE("%s: using ddc @ 0x%" B_PRIxADDR "\n", PortName(), ddcRegister); 209 210 i2c_bus bus; 211 bus.cookie = (void*)ddcRegister; 212 bus.set_signals = &_SetI2CSignals; 213 bus.get_signals = &_GetI2CSignals; 214 ddc2_init_timing(&bus); 215 216 fEDIDState = ddc2_read_edid1(&bus, &fEDIDInfo, NULL, NULL); 217 218 if (fEDIDState == B_OK) { 219 TRACE("%s: found EDID information!\n", PortName()); 220 edid_dump(&fEDIDInfo); 221 } 222 } 223 224 if (fEDIDState != B_OK) { 225 TRACE("%s: no EDID information found.\n", PortName()); 226 return fEDIDState; 227 } 228 229 if (edid != NULL) 230 memcpy(edid, &fEDIDInfo, sizeof(edid1_info)); 231 232 return B_OK; 233 } 234 235 236 status_t 237 Port::GetPLLLimits(pll_limits& limits) 238 { 239 return B_ERROR; 240 } 241 242 243 pipe_index 244 Port::PipePreference() 245 { 246 CALLED(); 247 // Ideally we could just return INTEL_PIPE_ANY for all devices by default, but 248 // this doesn't quite work yet. We need to use the BIOS presetup pipes for now. 249 if (gInfo->shared_info->device_type.Generation() < 4) 250 return INTEL_PIPE_ANY; 251 252 // Notes: 253 // - The BIOSes seen sofar do not use PIPE C by default. 254 // - The BIOSes seen sofar program transcoder A to PIPE A, etc. 255 // - Later devices add a pipe C alongside the added transcoder C. 256 257 // FIXME How's this setup in newer gens? Currently return INTEL_PIPE_ANY there.. 258 if ((gInfo->shared_info->device_type.Generation() <= 7) && 259 (!gInfo->shared_info->device_type.HasDDI())) { 260 uint32 portState = read32(_PortRegister()); 261 if (gInfo->shared_info->pch_info == INTEL_PCH_CPT) { 262 portState &= PORT_TRANS_SEL_MASK; 263 if (portState == PORT_TRANS_B_SEL_CPT) 264 return INTEL_PIPE_B; 265 else 266 return INTEL_PIPE_A; 267 } else { 268 if (portState & DISPLAY_MONITOR_PIPE_B) 269 return INTEL_PIPE_B; 270 else 271 return INTEL_PIPE_A; 272 } 273 } 274 275 if (gInfo->shared_info->device_type.HasDDI()) { 276 // scan all our pipes to find the one connected to the current port 277 uint32 pipeState = 0; 278 for (uint32 pipeCnt = 0; pipeCnt < 4; pipeCnt++) { 279 switch (pipeCnt) { 280 case 0: 281 pipeState = read32(PIPE_DDI_FUNC_CTL_A); 282 break; 283 case 1: 284 pipeState = read32(PIPE_DDI_FUNC_CTL_B); 285 break; 286 case 2: 287 pipeState = read32(PIPE_DDI_FUNC_CTL_C); 288 break; 289 default: 290 pipeState = read32(PIPE_DDI_FUNC_CTL_EDP); 291 break; 292 } 293 294 if ((((pipeState & PIPE_DDI_SELECT_MASK) >> PIPE_DDI_SELECT_SHIFT) + 1) 295 == (uint32)PortIndex()) { 296 switch (pipeCnt) { 297 case 0: 298 return INTEL_PIPE_A; 299 case 1: 300 return INTEL_PIPE_B; 301 case 2: 302 return INTEL_PIPE_C; 303 default: 304 return INTEL_PIPE_D; 305 } 306 } 307 } 308 } 309 310 return INTEL_PIPE_ANY; 311 } 312 313 314 status_t 315 Port::_GetI2CSignals(void* cookie, int* _clock, int* _data) 316 { 317 addr_t ioRegister = (addr_t)cookie; 318 uint32 value = read32(ioRegister); 319 320 *_clock = (value & I2C_CLOCK_VALUE_IN) != 0; 321 *_data = (value & I2C_DATA_VALUE_IN) != 0; 322 323 return B_OK; 324 } 325 326 327 status_t 328 Port::_SetI2CSignals(void* cookie, int clock, int data) 329 { 330 addr_t ioRegister = (addr_t)cookie; 331 uint32 value; 332 333 if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_83x)) { 334 // on these chips, the reserved values are fixed 335 value = 0; 336 } else { 337 // on all others, we have to preserve them manually 338 value = read32(ioRegister) & I2C_RESERVED; 339 } 340 341 // if we send clk or data, we always send low logic level; 342 // if we want to send high level, we actually receive and let the 343 // external pullup resistors create the high level on the bus. 344 value |= I2C_DATA_VALUE_MASK; //sets data = 0, always latch 345 value |= I2C_CLOCK_VALUE_MASK; //sets clock = 0, always latch 346 347 if (data != 0) 348 value |= I2C_DATA_DIRECTION_MASK; 349 else { 350 value |= I2C_DATA_DIRECTION_MASK | I2C_DATA_DIRECTION_OUT; 351 } 352 353 if (clock != 0) 354 value |= I2C_CLOCK_DIRECTION_MASK; 355 else { 356 value |= I2C_CLOCK_DIRECTION_MASK | I2C_CLOCK_DIRECTION_OUT; 357 } 358 359 write32(ioRegister, value); 360 read32(ioRegister); 361 // make sure the PCI bus has flushed the write 362 363 return B_OK; 364 } 365 366 367 // #pragma mark - Analog Port 368 369 370 AnalogPort::AnalogPort() 371 : 372 Port(INTEL_PORT_A, "Analog") 373 { 374 } 375 376 377 bool 378 AnalogPort::IsConnected() 379 { 380 TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(), 381 _PortRegister()); 382 return HasEDID(); 383 } 384 385 386 addr_t 387 AnalogPort::_DDCRegister() 388 { 389 // always fixed 390 return INTEL_I2C_IO_A; 391 } 392 393 394 addr_t 395 AnalogPort::_PortRegister() 396 { 397 // always fixed 398 return INTEL_ANALOG_PORT; 399 } 400 401 402 status_t 403 AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode) 404 { 405 CALLED(); 406 TRACE("%s: %s %dx%d\n", __func__, PortName(), target->timing.h_display, 407 target->timing.v_display); 408 409 if (fPipe == NULL) { 410 ERROR("%s: Setting display mode without assigned pipe!\n", __func__); 411 return B_ERROR; 412 } 413 414 // Setup PanelFitter and Train FDI if it exists 415 PanelFitter* fitter = fPipe->PFT(); 416 if (fitter != NULL) 417 fitter->Enable(target->timing); 418 FDILink* link = fPipe->FDI(); 419 if (link != NULL) { 420 uint32 lanes = 0; 421 uint32 linkBandwidth = 0; 422 uint32 bitsPerPixel = 0; 423 link->PreTrain(&target->timing, &linkBandwidth, &lanes, &bitsPerPixel); 424 fPipe->SetFDILink(target->timing, linkBandwidth, lanes, bitsPerPixel); 425 link->Train(&target->timing, lanes); 426 } 427 pll_divisors divisors; 428 compute_pll_divisors(&target->timing, &divisors, false); 429 430 uint32 extraPLLFlags = 0; 431 if (gInfo->shared_info->device_type.Generation() >= 3) 432 extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL; 433 434 // Program general pipe config 435 fPipe->Configure(target); 436 437 // Program pipe PLL's 438 fPipe->ConfigureClocks(divisors, target->timing.pixel_clock, extraPLLFlags); 439 440 write32(_PortRegister(), (read32(_PortRegister()) 441 & ~(DISPLAY_MONITOR_POLARITY_MASK | DISPLAY_MONITOR_VGA_POLARITY)) 442 | ((target->timing.flags & B_POSITIVE_HSYNC) != 0 443 ? DISPLAY_MONITOR_POSITIVE_HSYNC : 0) 444 | ((target->timing.flags & B_POSITIVE_VSYNC) != 0 445 ? DISPLAY_MONITOR_POSITIVE_VSYNC : 0)); 446 447 // Program target display mode 448 fPipe->ConfigureTimings(target); 449 450 // Set fCurrentMode to our set display mode 451 memcpy(&fCurrentMode, target, sizeof(display_mode)); 452 453 return B_OK; 454 } 455 456 457 // #pragma mark - LVDS Panel 458 459 460 LVDSPort::LVDSPort() 461 : 462 Port(INTEL_PORT_C, "LVDS") 463 { 464 // Always unlock LVDS port as soon as we start messing with it. 465 uint32 panelControl = INTEL_PANEL_CONTROL; 466 if (gInfo->shared_info->pch_info != INTEL_PCH_NONE) { 467 // FIXME writing there results in black screen on SandyBridge 468 return; 469 // panelControl = PCH_PANEL_CONTROL; 470 } 471 write32(panelControl, read32(panelControl) | PANEL_REGISTER_UNLOCK); 472 } 473 474 475 pipe_index 476 LVDSPort::PipePreference() 477 { 478 CALLED(); 479 // Older devices have hardcoded pipe/port mappings, so just use that 480 if (gInfo->shared_info->device_type.Generation() < 4) 481 return INTEL_PIPE_B; 482 483 // Ideally we could just return INTEL_PIPE_ANY for the newer devices, but 484 // this doesn't quite work yet. 485 486 // On SandyBridge and later, there is a transcoder C. On SandyBridge at least 487 // that can't be used by the LVDS port (but A and B would be fine). 488 // On Ibex Point, SandyBridge and IvyBridge (tested) changing pipes does not 489 // work yet. 490 // Notes: 491 // - Switching Pipes only works reliably when a 'full modeswitch' is executed 492 // (FDI training) so we have to reuse the BIOS preset setup always for now. 493 // - The BIOSes seen sofar do not use PIPE C by default. 494 // - The BIOSes seen sofar program transcoder A to PIPE A, etc. 495 // - Later devices add a pipe C alongside the added transcoder C. 496 497 // FIXME How's this setup in newer gens? Currently return Pipe B fixed there.. 498 if (gInfo->shared_info->device_type.Generation() <= 7) { 499 uint32 portState = read32(_PortRegister()); 500 if (gInfo->shared_info->pch_info == INTEL_PCH_CPT) { 501 portState &= PORT_TRANS_SEL_MASK; 502 if (portState == PORT_TRANS_B_SEL_CPT) 503 return INTEL_PIPE_B; 504 else 505 return INTEL_PIPE_A; 506 } else { 507 if (portState & DISPLAY_MONITOR_PIPE_B) 508 return INTEL_PIPE_B; 509 else 510 return INTEL_PIPE_A; 511 } 512 } 513 514 return INTEL_PIPE_B; 515 } 516 517 518 bool 519 LVDSPort::IsConnected() 520 { 521 TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(), 522 _PortRegister()); 523 524 if (gInfo->shared_info->pch_info != INTEL_PCH_NONE) { 525 uint32 registerValue = read32(_PortRegister()); 526 // there's a detection bit we can use 527 if ((registerValue & PCH_LVDS_DETECTED) == 0) { 528 TRACE("LVDS: Not detected\n"); 529 return false; 530 } 531 // TODO: Skip if eDP support 532 } else if (gInfo->shared_info->device_type.Generation() <= 4) { 533 // Older generations don't have LVDS detection. If not mobile skip. 534 if (!gInfo->shared_info->device_type.IsMobile()) { 535 TRACE("LVDS: Skipping LVDS detection due to gen and not mobile\n"); 536 return false; 537 } 538 // If mobile, try to grab EDID 539 // Linux seems to look at lid status for LVDS port detection 540 // If we don't get EDID, we can use vbios native mode or vesa? 541 if (!HasEDID()) { 542 if (gInfo->shared_info->has_vesa_edid_info) { 543 TRACE("LVDS: Using VESA edid info\n"); 544 memcpy(&fEDIDInfo, &gInfo->shared_info->vesa_edid_info, 545 sizeof(edid1_info)); 546 if (fEDIDState != B_OK) { 547 fEDIDState = B_OK; 548 // HasEDID now true 549 edid_dump(&fEDIDInfo); 550 } 551 } else if (gInfo->shared_info->got_vbt) { 552 TRACE("LVDS: No EDID, but force enabled as we have a VBT\n"); 553 return true; 554 } else { 555 TRACE("LVDS: Couldn't find any valid EDID!\n"); 556 return false; 557 } 558 } 559 } 560 561 // Try getting EDID, as the LVDS port doesn't overlap with anything else, 562 // we don't run the risk of getting someone else's data. 563 return HasEDID(); 564 } 565 566 567 addr_t 568 LVDSPort::_DDCRegister() 569 { 570 // always fixed 571 return INTEL_I2C_IO_C; 572 } 573 574 575 addr_t 576 LVDSPort::_PortRegister() 577 { 578 // always fixed 579 return INTEL_DIGITAL_LVDS_PORT; 580 } 581 582 583 status_t 584 LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode) 585 { 586 CALLED(); 587 if (target == NULL) { 588 ERROR("%s: Invalid target mode passed!\n", __func__); 589 return B_ERROR; 590 } 591 592 TRACE("%s: %s-%d %dx%d\n", __func__, PortName(), PortIndex(), 593 target->timing.h_display, target->timing.v_display); 594 595 if (fPipe == NULL) { 596 ERROR("%s: Setting display mode without assigned pipe!\n", __func__); 597 return B_ERROR; 598 } 599 600 addr_t panelControl = INTEL_PANEL_CONTROL; 601 addr_t panelStatus = INTEL_PANEL_STATUS; 602 if (gInfo->shared_info->pch_info != INTEL_PCH_NONE) { 603 panelControl = PCH_PANEL_CONTROL; 604 panelStatus = PCH_PANEL_STATUS; 605 } 606 607 if (gInfo->shared_info->device_type.Generation() != 4) { 608 // TODO not needed on any generation if we are using the panel fitter 609 // Power off Panel 610 write32(panelControl, 611 read32(panelControl) & ~PANEL_CONTROL_POWER_TARGET_ON); 612 read32(panelControl); 613 614 if (!wait_for_clear(panelStatus, PANEL_STATUS_POWER_ON, 1000)) { 615 ERROR("%s: %s didn't power off within 1000ms!\n", __func__, 616 PortName()); 617 } 618 } 619 620 // For LVDS panels, we may need to set the timings according to the panel 621 // native video mode, and let the panel fitter do the scaling. But the 622 // place where the scaling happens varies accross generations of devices. 623 display_timing hardwareTarget; 624 bool needsScaling = false; 625 626 // TODO figure out how it's done (or if we need to configure something at 627 // all) for other generations 628 if (gInfo->shared_info->device_type.Generation() <= 6 629 && gInfo->shared_info->device_type.Generation() >= 3 630 && gInfo->shared_info->got_vbt) { 631 // Set vbios hardware panel mode as base 632 hardwareTarget = gInfo->shared_info->panel_timing; 633 634 if (hardwareTarget.h_display == target->timing.h_display 635 && hardwareTarget.v_display == target->timing.v_display) { 636 // We are setting the native video mode, nothing special to do 637 // Note: this means refresh and timing might vary according to requested mode. 638 hardwareTarget = target->timing; 639 TRACE("%s: Setting LVDS to native resolution at %" B_PRIu32 "Hz\n", __func__, 640 hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * hardwareTarget.v_total)); 641 } else { 642 // We need to enable the panel fitter 643 TRACE("%s: Hardware mode will actually be %dx%d at %" B_PRIu32 "Hz\n", __func__, 644 hardwareTarget.h_display, hardwareTarget.v_display, 645 hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * hardwareTarget.v_total)); 646 647 // FIXME we should also get the refresh frequency from the target 648 // mode, and then "sanitize" the resulting mode we made up. 649 needsScaling = true; 650 } 651 } else { 652 TRACE("Setting LVDS mode without VBT info or on unhandled hardware " 653 "generation, scaling may not work\n"); 654 // We don't have VBT data, try to set the requested mode directly 655 // and hope for the best 656 hardwareTarget = target->timing; 657 } 658 659 // Setup PanelFitter and Train FDI if it exists 660 PanelFitter* fitter = fPipe->PFT(); 661 if (fitter != NULL) 662 fitter->Enable(hardwareTarget); 663 FDILink* link = fPipe->FDI(); 664 if (link != NULL) { 665 uint32 lanes = 0; 666 uint32 linkBandwidth = 0; 667 uint32 bitsPerPixel = 0; 668 link->PreTrain(&hardwareTarget, &linkBandwidth, &lanes, &bitsPerPixel); 669 fPipe->SetFDILink(hardwareTarget, linkBandwidth, lanes, bitsPerPixel); 670 link->Train(&hardwareTarget, lanes); 671 } 672 673 pll_divisors divisors; 674 compute_pll_divisors(&hardwareTarget, &divisors, true); 675 676 uint32 lvds = read32(_PortRegister()) 677 | LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; 678 679 if (gInfo->shared_info->device_type.Generation() == 4) { 680 // LVDS_A3_POWER_UP == 24bpp 681 // otherwise, 18bpp 682 if ((lvds & LVDS_A3_POWER_MASK) != LVDS_A3_POWER_UP) 683 lvds |= LVDS_18BIT_DITHER; 684 } 685 686 // LVDS on PCH needs set before display enable 687 if (gInfo->shared_info->pch_info == INTEL_PCH_CPT) { 688 lvds &= ~PORT_TRANS_SEL_MASK; 689 if (fPipe->Index() == INTEL_PIPE_A) 690 lvds |= PORT_TRANS_A_SEL_CPT; 691 else 692 lvds |= PORT_TRANS_B_SEL_CPT; 693 } 694 695 // Set the B0-B3 data pairs corresponding to whether we're going to 696 // set the DPLLs for dual-channel mode or not. 697 if (divisors.p2 == 5 || divisors.p2 == 7) { 698 TRACE("LVDS: dual channel\n"); 699 lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; 700 } else { 701 TRACE("LVDS: single channel\n"); 702 lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); 703 } 704 705 // LVDS port control moves polarity bits because Intel hates you. 706 // Set LVDS sync polarity 707 lvds &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); 708 709 // set on - polarity. 710 if ((target->timing.flags & B_POSITIVE_HSYNC) == 0) 711 lvds |= LVDS_HSYNC_POLARITY; 712 if ((target->timing.flags & B_POSITIVE_VSYNC) == 0) 713 lvds |= LVDS_VSYNC_POLARITY; 714 715 TRACE("%s: LVDS Write: 0x%" B_PRIx32 "\n", __func__, lvds); 716 write32(_PortRegister(), lvds); 717 read32(_PortRegister()); 718 719 uint32 extraPLLFlags = 0; 720 721 // DPLL mode LVDS for i915+ 722 if (gInfo->shared_info->device_type.Generation() >= 3) 723 extraPLLFlags |= DISPLAY_PLL_MODE_LVDS | DISPLAY_PLL_2X_CLOCK; 724 725 // Program general pipe config 726 fPipe->Configure(target); 727 728 // Program pipe PLL's (using the hardware mode timings, since that's what 729 // the PLL is used for) 730 fPipe->ConfigureClocks(divisors, hardwareTarget.pixel_clock, 731 extraPLLFlags); 732 733 if (gInfo->shared_info->device_type.Generation() != 4) { 734 // G45: no need to power the panel off 735 // Power on Panel 736 write32(panelControl, 737 read32(panelControl) | PANEL_CONTROL_POWER_TARGET_ON); 738 read32(panelControl); 739 740 if (!wait_for_set(panelStatus, PANEL_STATUS_POWER_ON, 1000)) { 741 ERROR("%s: %s didn't power on within 1000ms!\n", __func__, 742 PortName()); 743 } 744 } 745 746 // Program target display mode 747 fPipe->ConfigureTimings(target, !needsScaling); 748 749 if (needsScaling) { 750 if (gInfo->shared_info->device_type.Generation() <= 4) { 751 // Enable panel fitter in automatic mode. It will figure out 752 // the scaling ratios automatically. 753 uint32 panelFitterControl = read32(INTEL_PANEL_FIT_CONTROL); 754 panelFitterControl |= PANEL_FITTER_ENABLED; 755 panelFitterControl &= ~(PANEL_FITTER_SCALING_MODE_MASK 756 | PANEL_FITTER_PIPE_MASK); 757 panelFitterControl |= PANEL_FITTER_PIPE_B; 758 // LVDS is always on pipe B. 759 write32(INTEL_PANEL_FIT_CONTROL, panelFitterControl); 760 } 761 // TODO do we need to do anything on later generations? 762 } else { 763 if (gInfo->shared_info->device_type.Generation() == 4 764 || gInfo->shared_info->device_type.Generation() == 3) { 765 // Bypass the panel fitter 766 uint32 panelFitterControl = read32(INTEL_PANEL_FIT_CONTROL); 767 panelFitterControl &= ~PANEL_FITTER_ENABLED; 768 write32(INTEL_PANEL_FIT_CONTROL, panelFitterControl); 769 } else { 770 // We don't need to do anything more for later generations, the 771 // scaling is handled at the transcoder level. We may want to 772 // configure dithering, but the code below ignores the previous 773 // value in the register and may mess things up so we should do 774 // this in a safeer way. For now, assume the BIOS did the right 775 // thing. 776 #if 0 777 // Disable panel fitting, but enable 8 to 6-bit dithering 778 write32(INTEL_PANEL_FIT_CONTROL, 0x4); 779 // TODO: do not do this if the connected panel is 24-bit 780 // (I don't know how to detect that) 781 #endif 782 } 783 } 784 785 // Set fCurrentMode to our set display mode 786 memcpy(&fCurrentMode, target, sizeof(display_mode)); 787 788 return B_OK; 789 } 790 791 792 // #pragma mark - DVI/SDVO/generic 793 794 795 DigitalPort::DigitalPort(port_index index, const char* baseName) 796 : 797 Port(index, baseName) 798 { 799 } 800 801 802 bool 803 DigitalPort::IsConnected() 804 { 805 TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(), 806 _PortRegister()); 807 808 // As this port overlaps with pretty much everything, this must be called 809 // after having ruled out all other port types. 810 return HasEDID(); 811 } 812 813 814 addr_t 815 DigitalPort::_DDCRegister() 816 { 817 //TODO: IS BROXTON, B = B, C = C, D = NIL 818 switch (PortIndex()) { 819 case INTEL_PORT_B: 820 return INTEL_I2C_IO_E; 821 case INTEL_PORT_C: 822 return INTEL_I2C_IO_D; 823 case INTEL_PORT_D: 824 return INTEL_I2C_IO_F; 825 default: 826 return 0; 827 } 828 829 return 0; 830 } 831 832 833 addr_t 834 DigitalPort::_PortRegister() 835 { 836 switch (PortIndex()) { 837 case INTEL_PORT_A: 838 return INTEL_DIGITAL_PORT_A; 839 case INTEL_PORT_B: 840 return INTEL_DIGITAL_PORT_B; 841 case INTEL_PORT_C: 842 return INTEL_DIGITAL_PORT_C; 843 default: 844 return 0; 845 } 846 return 0; 847 } 848 849 850 status_t 851 DigitalPort::SetDisplayMode(display_mode* target, uint32 colorMode) 852 { 853 CALLED(); 854 TRACE("%s: %s %dx%d\n", __func__, PortName(), target->timing.h_display, 855 target->timing.v_display); 856 857 if (fPipe == NULL) { 858 ERROR("%s: Setting display mode without assigned pipe!\n", __func__); 859 return B_ERROR; 860 } 861 862 // Setup PanelFitter and Train FDI if it exists 863 PanelFitter* fitter = fPipe->PFT(); 864 if (fitter != NULL) 865 fitter->Enable(target->timing); 866 FDILink* link = fPipe->FDI(); 867 if (link != NULL) { 868 uint32 lanes = 0; 869 uint32 linkBandwidth = 0; 870 uint32 bitsPerPixel = 0; 871 link->PreTrain(&target->timing, &linkBandwidth, &lanes, &bitsPerPixel); 872 fPipe->SetFDILink(target->timing, linkBandwidth, lanes, bitsPerPixel); 873 link->Train(&target->timing, lanes); 874 } 875 876 pll_divisors divisors; 877 compute_pll_divisors(&target->timing, &divisors, false); 878 879 uint32 extraPLLFlags = 0; 880 if (gInfo->shared_info->device_type.Generation() >= 3) 881 extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL | DISPLAY_PLL_2X_CLOCK; 882 883 // Program general pipe config 884 fPipe->Configure(target); 885 886 // Program pipe PLL's 887 fPipe->ConfigureClocks(divisors, target->timing.pixel_clock, extraPLLFlags); 888 889 // Program target display mode 890 fPipe->ConfigureTimings(target); 891 892 // Set fCurrentMode to our set display mode 893 memcpy(&fCurrentMode, target, sizeof(display_mode)); 894 895 return B_OK; 896 } 897 898 899 // #pragma mark - LVDS Panel 900 // #pragma mark - HDMI 901 902 903 HDMIPort::HDMIPort(port_index index) 904 : 905 DigitalPort(index, "HDMI") 906 { 907 } 908 909 910 bool 911 HDMIPort::IsConnected() 912 { 913 if (!gInfo->shared_info->device_type.SupportsHDMI()) 914 return false; 915 916 addr_t portRegister = _PortRegister(); 917 TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(), 918 portRegister); 919 920 if (portRegister == 0) 921 return false; 922 923 //Notes: 924 //- DISPLAY_MONITOR_PORT_DETECTED does only tell you *some* sort of digital display is 925 // connected to the port *if* you have the AUX channel stuff under power. It does not 926 // tell you which -type- of digital display is connected. 927 //- Since we rely on the BIOS anyway, let's just use the conclusions it made for us :) 928 // Beware though: set_display_power_mode() uses this DISPLAY_MONITOR_PORT_ENABLED bit 929 // for DPMS as well. So we should better buffer our findings here for i.e. possible 930 // accelerant clones starting up. For DPMS there's currently no problem as this bit 931 // is only programmed for LVDS, DVI and VGA while we detect presence only for DP and HDMI. 932 // 933 //if ((read32(portRegister) & DISPLAY_MONITOR_PORT_DETECTED) == 0) 934 if ((read32(portRegister) & DISPLAY_MONITOR_PORT_ENABLED) == 0) 935 return false; 936 937 return HasEDID(); 938 } 939 940 941 addr_t 942 HDMIPort::_PortRegister() 943 { 944 // on PCH there's an additional port sandwiched in 945 bool hasPCH = (gInfo->shared_info->pch_info != INTEL_PCH_NONE); 946 bool fourthGen = gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV); 947 948 switch (PortIndex()) { 949 case INTEL_PORT_B: 950 if (fourthGen) 951 return GEN4_HDMI_PORT_B; 952 return hasPCH ? PCH_HDMI_PORT_B : INTEL_HDMI_PORT_B; 953 case INTEL_PORT_C: 954 if (fourthGen) 955 return GEN4_HDMI_PORT_C; 956 return hasPCH ? PCH_HDMI_PORT_C : INTEL_HDMI_PORT_C; 957 case INTEL_PORT_D: 958 if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_CHV)) 959 return CHV_HDMI_PORT_D; 960 return hasPCH ? PCH_HDMI_PORT_D : 0; 961 default: 962 return 0; 963 } 964 965 return 0; 966 } 967 968 969 // #pragma mark - DisplayPort 970 971 972 DisplayPort::DisplayPort(port_index index, const char* baseName) 973 : 974 Port(index, baseName) 975 { 976 } 977 978 979 pipe_index 980 DisplayPort::PipePreference() 981 { 982 CALLED(); 983 if (gInfo->shared_info->device_type.Generation() <= 4) 984 return INTEL_PIPE_ANY; 985 986 // Notes: 987 // - The BIOSes seen sofar do not use PIPE C by default. 988 // - Looks like BIOS selected Transcoder (A,B,C) is not always same as selected Pipe (A,B,C) 989 // so these should probably be handled seperately. For now this is OK as we don't touch 990 // the pipe for DisplayPort, only the transcoder.. 991 uint32 TranscoderPort = INTEL_TRANS_DP_PORT_NONE; 992 switch (PortIndex()) { 993 case INTEL_PORT_A: 994 return INTEL_PIPE_ANY; 995 case INTEL_PORT_B: 996 TranscoderPort = INTEL_TRANS_DP_PORT_B; 997 break; 998 case INTEL_PORT_C: 999 TranscoderPort = INTEL_TRANS_DP_PORT_C; 1000 break; 1001 case INTEL_PORT_D: 1002 TranscoderPort = INTEL_TRANS_DP_PORT_D; 1003 break; 1004 default: 1005 return INTEL_PIPE_ANY; 1006 } 1007 1008 for (uint32 Transcoder = 0; Transcoder < 3; Transcoder++) { 1009 if ((read32(INTEL_TRANSCODER_A_DP_CTL + (Transcoder << 12)) & INTEL_TRANS_DP_PORT_MASK) == 1010 INTEL_TRANS_DP_PORT(TranscoderPort)) { 1011 switch (Transcoder) { 1012 case 0: 1013 return INTEL_PIPE_A; 1014 case 1: 1015 return INTEL_PIPE_B; 1016 case 2: 1017 return INTEL_PIPE_C; 1018 } 1019 } 1020 } 1021 1022 return INTEL_PIPE_ANY; 1023 } 1024 1025 1026 bool 1027 DisplayPort::IsConnected() 1028 { 1029 addr_t portRegister = _PortRegister(); 1030 1031 TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(), 1032 portRegister); 1033 1034 if (portRegister == 0) 1035 return false; 1036 1037 //Notes: 1038 //- DISPLAY_MONITOR_PORT_DETECTED does only tell you *some* sort of digital display is 1039 // connected to the port *if* you have the AUX channel stuff under power. It does not 1040 // tell you which -type- of digital display is connected. 1041 //- Since we rely on the BIOS anyway, let's just use the conclusions it made for us :) 1042 // Beware though: set_display_power_mode() uses this DISPLAY_MONITOR_PORT_ENABLED bit 1043 // for DPMS as well. So we should better buffer our findings here for i.e. possible 1044 // accelerant clones starting up. For DPMS there's currently no problem as this bit 1045 // is only programmed for LVDS, DVI and VGA while we detect presence only for DP and HDMI. 1046 // 1047 //if ((read32(portRegister) & DISPLAY_MONITOR_PORT_DETECTED) == 0) { 1048 if ((read32(portRegister) & DISPLAY_MONITOR_PORT_ENABLED) == 0) { 1049 TRACE("%s: %s link not detected\n", __func__, PortName()); 1050 return false; 1051 } 1052 1053 TRACE("%s: %s link detected\n", __func__, PortName()); 1054 1055 // On laptops we always have an internal panel.. (this is on the eDP port) 1056 if (gInfo->shared_info->device_type.IsMobile() && (PortIndex() == INTEL_PORT_A)) { 1057 if (gInfo->shared_info->has_vesa_edid_info) { 1058 TRACE("%s: Laptop. Using VESA edid info\n", __func__); 1059 memcpy(&fEDIDInfo, &gInfo->shared_info->vesa_edid_info, 1060 sizeof(edid1_info)); 1061 if (fEDIDState != B_OK) { 1062 fEDIDState = B_OK; 1063 // HasEDID now true 1064 edid_dump(&fEDIDInfo); 1065 } 1066 return true; 1067 } else if (gInfo->shared_info->got_vbt) { 1068 TRACE("%s: Laptop. No EDID, but force enabled as we have a VBT\n", __func__); 1069 return true; 1070 } 1071 } 1072 1073 //since EDID is not correctly implemented yet for this connection type we'll do without it for now 1074 //return HasEDID(); 1075 return true; 1076 } 1077 1078 1079 addr_t 1080 DisplayPort::_DDCRegister() 1081 { 1082 // TODO: Do VLV + CHV use the VLV_DP_AUX_CTL_B + VLV_DP_AUX_CTL_C? 1083 switch (PortIndex()) { 1084 case INTEL_PORT_A: 1085 return INTEL_DP_AUX_CTL_A; 1086 case INTEL_PORT_B: 1087 if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV)) 1088 return VLV_DP_AUX_CTL_B; 1089 return INTEL_DP_AUX_CTL_B; 1090 case INTEL_PORT_C: 1091 if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV)) 1092 return VLV_DP_AUX_CTL_C; 1093 return INTEL_DP_AUX_CTL_C; 1094 case INTEL_PORT_D: 1095 if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_CHV)) 1096 return CHV_DP_AUX_CTL_D; 1097 else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV)) 1098 return 0; 1099 return INTEL_DP_AUX_CTL_D; 1100 default: 1101 return 0; 1102 } 1103 1104 return 0; 1105 } 1106 1107 1108 addr_t 1109 DisplayPort::_PortRegister() 1110 { 1111 // There are 6000 lines of intel linux code probing DP registers 1112 // to properly detect DP vs eDP to then in-turn properly figure out 1113 // what is DP and what is HDMI. It only takes 3 lines to 1114 // ignore DisplayPort on ValleyView / CherryView 1115 1116 if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV) 1117 || gInfo->shared_info->device_type.InGroup(INTEL_GROUP_CHV)) { 1118 ERROR("TODO: DisplayPort on ValleyView / CherryView"); 1119 return 0; 1120 } 1121 1122 // Intel, are humans even involved anymore? 1123 // This is a lot more complex than this code makes it look. (see defines) 1124 // INTEL_DISPLAY_PORT_X moves around a lot based on PCH 1125 // except on ValleyView and CherryView. 1126 switch (PortIndex()) { 1127 case INTEL_PORT_A: 1128 return INTEL_DISPLAY_PORT_A; 1129 case INTEL_PORT_B: 1130 if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV)) 1131 return VLV_DISPLAY_PORT_B; 1132 return INTEL_DISPLAY_PORT_B; 1133 case INTEL_PORT_C: 1134 if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV)) 1135 return VLV_DISPLAY_PORT_C; 1136 return INTEL_DISPLAY_PORT_C; 1137 case INTEL_PORT_D: 1138 if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_CHV)) 1139 return CHV_DISPLAY_PORT_D; 1140 else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV)) 1141 return 0; 1142 return INTEL_DISPLAY_PORT_D; 1143 default: 1144 return 0; 1145 } 1146 1147 return 0; 1148 } 1149 1150 1151 status_t 1152 DisplayPort::_SetPortLinkGen4(const display_timing& timing) 1153 { 1154 // Khz / 10. ( each output octet encoded as 10 bits. 1155 //uint32 linkBandwidth = gInfo->shared_info->fdi_link_frequency * 1000 / 10; //=270000 khz 1156 //fixme: always so? 1157 uint32 linkBandwidth = 270000; //khz 1158 uint32 fPipeOffset = 0; 1159 if (fPipe->Index() == INTEL_PIPE_B) 1160 fPipeOffset = 0x1000; 1161 1162 TRACE("%s: DP M1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_DATA_M + fPipeOffset)); 1163 TRACE("%s: DP N1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_DATA_N + fPipeOffset)); 1164 TRACE("%s: DP M1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_LINK_M + fPipeOffset)); 1165 TRACE("%s: DP N1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_LINK_N + fPipeOffset)); 1166 1167 uint32 bitsPerPixel = 24; //fixme: always so? 1168 uint32 lanes = 4; //fixme: always so? 1169 1170 //Setup Data M/N 1171 uint64 linkspeed = lanes * linkBandwidth * 8; 1172 uint64 ret_n = 1; 1173 while(ret_n < linkspeed) { 1174 ret_n *= 2; 1175 } 1176 if (ret_n > 0x800000) { 1177 ret_n = 0x800000; 1178 } 1179 uint64 ret_m = timing.pixel_clock * ret_n * bitsPerPixel / linkspeed; 1180 while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) { 1181 ret_m >>= 1; 1182 ret_n >>= 1; 1183 } 1184 //Set TU size bits (to default, max) before link training so that error detection works 1185 write32(INTEL_PIPE_A_DATA_M + fPipeOffset, ret_m | FDI_PIPE_MN_TU_SIZE_MASK); 1186 write32(INTEL_PIPE_A_DATA_N + fPipeOffset, ret_n); 1187 1188 //Setup Link M/N 1189 linkspeed = linkBandwidth; 1190 ret_n = 1; 1191 while(ret_n < linkspeed) { 1192 ret_n *= 2; 1193 } 1194 if (ret_n > 0x800000) { 1195 ret_n = 0x800000; 1196 } 1197 ret_m = timing.pixel_clock * ret_n / linkspeed; 1198 while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) { 1199 ret_m >>= 1; 1200 ret_n >>= 1; 1201 } 1202 write32(INTEL_PIPE_A_LINK_M + fPipeOffset, ret_m); 1203 //Writing Link N triggers all four registers to be activated also (on next VBlank) 1204 write32(INTEL_PIPE_A_LINK_N + fPipeOffset, ret_n); 1205 1206 TRACE("%s: DP M1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_DATA_M + fPipeOffset)); 1207 TRACE("%s: DP N1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_DATA_N + fPipeOffset)); 1208 TRACE("%s: DP M1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_LINK_M + fPipeOffset)); 1209 TRACE("%s: DP N1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_LINK_N + fPipeOffset)); 1210 1211 return B_OK; 1212 } 1213 1214 1215 status_t 1216 DisplayPort::_SetPortLinkGen6(const display_timing& timing) 1217 { 1218 // Khz / 10. ( each output octet encoded as 10 bits. 1219 //uint32 linkBandwidth = gInfo->shared_info->fdi_link_frequency * 1000 / 10; //=270000 khz 1220 //fixme: eDP is fixed option 162 or 270Mc, other DPs go via DPLL programming to one of the same vals. 1221 uint32 linkBandwidth = 270000; //khz 1222 TRACE("%s: DP link reference clock is %gMhz\n", __func__, linkBandwidth / 1000.0f); 1223 1224 uint32 fPipeOffset = 0; 1225 switch (fPipe->Index()) { 1226 case INTEL_PIPE_B: 1227 fPipeOffset = 0x1000; 1228 break; 1229 case INTEL_PIPE_C: 1230 fPipeOffset = 0x2000; 1231 break; 1232 default: 1233 break; 1234 } 1235 1236 TRACE("%s: DP M1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_DATA_M1 + fPipeOffset)); 1237 TRACE("%s: DP N1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_DATA_N1 + fPipeOffset)); 1238 TRACE("%s: DP M1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_LINK_M1 + fPipeOffset)); 1239 TRACE("%s: DP N1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_LINK_N1 + fPipeOffset)); 1240 1241 uint32 bitsPerPixel = 1242 (read32(INTEL_TRANSCODER_A_DP_CTL + fPipeOffset) & INTEL_TRANS_DP_BPC_MASK) >> INTEL_TRANS_DP_COLOR_SHIFT; 1243 switch (bitsPerPixel) { 1244 case PIPE_DDI_8BPC: 1245 bitsPerPixel = 24; 1246 break; 1247 case PIPE_DDI_10BPC: 1248 bitsPerPixel = 30; 1249 break; 1250 case PIPE_DDI_6BPC: 1251 bitsPerPixel = 18; 1252 break; 1253 case PIPE_DDI_12BPC: 1254 bitsPerPixel = 36; 1255 break; 1256 default: 1257 ERROR("%s: DP illegal link colordepth set.\n", __func__); 1258 return B_ERROR; 1259 } 1260 TRACE("%s: DP link colordepth: %" B_PRIu32 "\n", __func__, bitsPerPixel); 1261 1262 uint32 lanes = 1263 1 << ((read32(_PortRegister()) & INTEL_DISP_PORT_WIDTH_MASK) >> INTEL_DISP_PORT_WIDTH_SHIFT); 1264 if (lanes > 4) { 1265 ERROR("%s: DP illegal number of lanes set.\n", __func__); 1266 return B_ERROR; 1267 } 1268 TRACE("%s: DP mode with %" B_PRIx32 " lane(s) in use\n", __func__, lanes); 1269 1270 //Reserving 5% bandwidth for possible spread spectrum clock use 1271 uint32 bps = timing.pixel_clock * bitsPerPixel * 21 / 20; 1272 //use DIV_ROUND_UP: 1273 uint32 required_lanes = (bps + (linkBandwidth * 8) - 1) / (linkBandwidth * 8); 1274 TRACE("%s: DP mode needs %" B_PRIx32 " lane(s) in use\n", __func__, required_lanes); 1275 if (required_lanes > lanes) { 1276 //Note that we *must* abort as otherwise the PIPE/DP-link hangs forever (without retraining!). 1277 ERROR("%s: DP not enough lanes active for requested mode.\n", __func__); 1278 return B_ERROR; 1279 } 1280 1281 //Setup Data M/N 1282 uint64 linkspeed = lanes * linkBandwidth * 8; 1283 uint64 ret_n = 1; 1284 while(ret_n < linkspeed) { 1285 ret_n *= 2; 1286 } 1287 if (ret_n > 0x800000) { 1288 ret_n = 0x800000; 1289 } 1290 uint64 ret_m = timing.pixel_clock * ret_n * bitsPerPixel / linkspeed; 1291 while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) { 1292 ret_m >>= 1; 1293 ret_n >>= 1; 1294 } 1295 //Set TU size bits (to default, max) before link training so that error detection works 1296 write32(INTEL_TRANSCODER_A_DATA_M1 + fPipeOffset, ret_m | INTEL_TRANSCODER_MN_TU_SIZE_MASK); 1297 write32(INTEL_TRANSCODER_A_DATA_N1 + fPipeOffset, ret_n); 1298 1299 //Setup Link M/N 1300 linkspeed = linkBandwidth; 1301 ret_n = 1; 1302 while(ret_n < linkspeed) { 1303 ret_n *= 2; 1304 } 1305 if (ret_n > 0x800000) { 1306 ret_n = 0x800000; 1307 } 1308 ret_m = timing.pixel_clock * ret_n / linkspeed; 1309 while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) { 1310 ret_m >>= 1; 1311 ret_n >>= 1; 1312 } 1313 write32(INTEL_TRANSCODER_A_LINK_M1 + fPipeOffset, ret_m); 1314 //Writing Link N triggers all four registers to be activated also (on next VBlank) 1315 write32(INTEL_TRANSCODER_A_LINK_N1 + fPipeOffset, ret_n); 1316 1317 TRACE("%s: DP M1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_DATA_M1 + fPipeOffset)); 1318 TRACE("%s: DP N1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_DATA_N1 + fPipeOffset)); 1319 TRACE("%s: DP M1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_LINK_M1 + fPipeOffset)); 1320 TRACE("%s: DP N1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_LINK_N1 + fPipeOffset)); 1321 1322 return B_OK; 1323 } 1324 1325 1326 status_t 1327 DisplayPort::SetDisplayMode(display_mode* target, uint32 colorMode) 1328 { 1329 CALLED(); 1330 TRACE("%s: %s %dx%d\n", __func__, PortName(), target->timing.h_display, 1331 target->timing.v_display); 1332 1333 if (fPipe == NULL) { 1334 ERROR("%s: Setting display mode without assigned pipe!\n", __func__); 1335 return B_ERROR; 1336 } 1337 1338 status_t result = B_OK; 1339 if (gInfo->shared_info->device_type.Generation() <= 4) { 1340 fPipe->ConfigureTimings(target); 1341 result = _SetPortLinkGen4(target->timing); 1342 } else { 1343 display_timing hardwareTarget = target->timing; 1344 bool needsScaling = false; 1345 if ((PortIndex() == INTEL_PORT_A) && gInfo->shared_info->device_type.IsMobile()) { 1346 // For internal panels, we may need to set the timings according to the panel 1347 // native video mode, and let the panel fitter do the scaling. 1348 // note: upto/including generation 5 laptop panels are still LVDS types, handled elsewhere. 1349 1350 if (gInfo->shared_info->got_vbt) { 1351 // Set vbios hardware panel mode as base 1352 hardwareTarget = gInfo->shared_info->panel_timing; 1353 1354 if (hardwareTarget.h_display == target->timing.h_display 1355 && hardwareTarget.v_display == target->timing.v_display) { 1356 // We are setting the native video mode, nothing special to do 1357 // Note: this means refresh and timing might vary according to requested mode. 1358 hardwareTarget = target->timing; 1359 TRACE("%s: Setting internal panel to native resolution at %" B_PRIu32 "Hz\n", __func__, 1360 hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * hardwareTarget.v_total)); 1361 } else { 1362 // We need to enable the panel fitter 1363 TRACE("%s: Hardware mode will actually be %dx%d at %" B_PRIu32 "Hz\n", __func__, 1364 hardwareTarget.h_display, hardwareTarget.v_display, 1365 hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * hardwareTarget.v_total)); 1366 1367 // FIXME we should also get the refresh frequency from the target 1368 // mode, and then "sanitize" the resulting mode we made up. 1369 needsScaling = true; 1370 } 1371 } else { 1372 TRACE("%s: Setting internal panel mode without VBT info generation, scaling may not work\n", 1373 __func__); 1374 // We don't have VBT data, try to set the requested mode directly 1375 // and hope for the best 1376 hardwareTarget = target->timing; 1377 } 1378 } 1379 1380 result = B_OK; 1381 if (PortIndex() != INTEL_PORT_A) 1382 result = _SetPortLinkGen6(hardwareTarget); 1383 1384 if (result == B_OK) { 1385 // Setup PanelFitter and Train FDI if it exists 1386 PanelFitter* fitter = fPipe->PFT(); 1387 if (fitter != NULL) 1388 fitter->Enable(hardwareTarget); 1389 // we should skip FDI if PORT_A, but need pipe M/N programming (is eDP link), so call always for now 1390 FDILink* link = fPipe->FDI(); 1391 if (link != NULL) { 1392 uint32 lanes = 0; 1393 uint32 linkBandwidth = 0; 1394 uint32 bitsPerPixel = 0; 1395 link->PreTrain(&hardwareTarget, &linkBandwidth, &lanes, &bitsPerPixel); 1396 fPipe->SetFDILink(hardwareTarget, linkBandwidth, lanes, bitsPerPixel); 1397 link->Train(&hardwareTarget, lanes); 1398 } 1399 1400 // Program general pipe config 1401 fPipe->Configure(target); 1402 1403 // Pll programming is not needed for (e)DP.. 1404 1405 // Program target display mode 1406 fPipe->ConfigureTimings(target, !needsScaling); 1407 } else { 1408 TRACE("%s: Setting display mode via fallback: using scaling!\n", __func__); 1409 // Keep monitor at native mode and scale image to that 1410 fPipe->ConfigureScalePos(target); 1411 } 1412 } 1413 1414 // Set fCurrentMode to our set display mode 1415 memcpy(&fCurrentMode, target, sizeof(display_mode)); 1416 1417 return result; 1418 } 1419 1420 1421 // #pragma mark - Embedded DisplayPort 1422 1423 1424 EmbeddedDisplayPort::EmbeddedDisplayPort() 1425 : 1426 DisplayPort(INTEL_PORT_A, "Embedded DisplayPort") 1427 { 1428 } 1429 1430 1431 bool 1432 EmbeddedDisplayPort::IsConnected() 1433 { 1434 addr_t portRegister = _PortRegister(); 1435 1436 TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(), 1437 portRegister); 1438 1439 if (!gInfo->shared_info->device_type.IsMobile()) { 1440 TRACE("%s: skipping eDP on non-mobile GPU\n", __func__); 1441 return false; 1442 } 1443 1444 if ((read32(portRegister) & DISPLAY_MONITOR_PORT_DETECTED) == 0) { 1445 TRACE("%s: %s link not detected\n", __func__, PortName()); 1446 return false; 1447 } 1448 1449 HasEDID(); 1450 1451 // If eDP has EDID, awesome. We use it. 1452 // No EDID? The modesetting code falls back to VBIOS panel_mode 1453 return true; 1454 } 1455 1456 1457 // #pragma mark - Digital Display Port 1458 1459 1460 DigitalDisplayInterface::DigitalDisplayInterface(port_index index, 1461 const char* baseName) 1462 : 1463 Port(index, baseName) 1464 { 1465 // As of Haswell, Intel decided to change eDP ports to a "DDI" bus... 1466 // on a dare because the hardware engineers were drunk one night. 1467 } 1468 1469 1470 addr_t 1471 DigitalDisplayInterface::_PortRegister() 1472 { 1473 // TODO: Linux does a DDI_BUF_CTL(INTEL_PORT_A) which is cleaner 1474 // (but we have to ensure the offsets + region base is correct) 1475 switch (PortIndex()) { 1476 case INTEL_PORT_A: 1477 return DDI_BUF_CTL_A; 1478 case INTEL_PORT_B: 1479 return DDI_BUF_CTL_B; 1480 case INTEL_PORT_C: 1481 return DDI_BUF_CTL_C; 1482 case INTEL_PORT_D: 1483 return DDI_BUF_CTL_D; 1484 case INTEL_PORT_E: 1485 return DDI_BUF_CTL_E; 1486 case INTEL_PORT_F: 1487 if ((gInfo->shared_info->device_type.Generation() > 8) && 1488 !gInfo->shared_info->device_type.InGroup(INTEL_GROUP_SKY)) 1489 return DDI_BUF_CTL_F; 1490 return 0; 1491 default: 1492 return 0; 1493 } 1494 return 0; 1495 } 1496 1497 1498 addr_t 1499 DigitalDisplayInterface::_DDCRegister() 1500 { 1501 switch (PortIndex()) { 1502 case INTEL_PORT_B: 1503 return INTEL_I2C_IO_E; 1504 case INTEL_PORT_C: 1505 return INTEL_I2C_IO_D; 1506 case INTEL_PORT_D: 1507 return INTEL_I2C_IO_F; 1508 default: 1509 return 0; 1510 } 1511 1512 return 0; 1513 } 1514 1515 1516 status_t 1517 DigitalDisplayInterface::Power(bool enabled) 1518 { 1519 if (fPipe == NULL) { 1520 ERROR("%s: Setting power without assigned pipe!\n", __func__); 1521 return B_ERROR; 1522 } 1523 TRACE("%s: %s DDI enabled: %s\n", __func__, PortName(), 1524 enabled ? "true" : "false"); 1525 1526 fPipe->Enable(enabled); 1527 1528 //nogo currently.. (kills output forever) 1529 #if 0 1530 addr_t portRegister = _PortRegister(); 1531 uint32 state = read32(portRegister); 1532 write32(portRegister, 1533 enabled ? (state | DDI_BUF_CTL_ENABLE) : (state & ~DDI_BUF_CTL_ENABLE)); 1534 read32(portRegister); 1535 #endif 1536 1537 return B_OK; 1538 } 1539 1540 1541 bool 1542 DigitalDisplayInterface::IsConnected() 1543 { 1544 addr_t portRegister = _PortRegister(); 1545 1546 TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(), 1547 portRegister); 1548 1549 // Please note: Skylake and up (Desktop) might use eDP for a seperate active VGA converter chip. 1550 if (portRegister == 0) { 1551 TRACE("%s: Port not implemented\n", __func__); 1552 return false; 1553 } 1554 1555 // newer chipsets support 4 lanes on all ports 1556 fMaxLanes = 4; 1557 if ((gInfo->shared_info->device_type.Generation() < 9) || 1558 gInfo->shared_info->device_type.InGroup(INTEL_GROUP_SKY)) { 1559 // Probe a little port info. 1560 if ((read32(DDI_BUF_CTL_A) & DDI_A_4_LANES) != 0) { 1561 switch (PortIndex()) { 1562 case INTEL_PORT_A: 1563 fMaxLanes = 4; 1564 break; 1565 case INTEL_PORT_E: 1566 fMaxLanes = 0; 1567 break; 1568 default: 1569 fMaxLanes = 4; 1570 break; 1571 } 1572 } else { 1573 switch (PortIndex()) { 1574 case INTEL_PORT_A: 1575 fMaxLanes = 2; 1576 break; 1577 case INTEL_PORT_E: 1578 fMaxLanes = 2; 1579 break; 1580 default: 1581 fMaxLanes = 4; 1582 break; 1583 } 1584 } 1585 } 1586 1587 TRACE("%s: %s Maximum Lanes: %" B_PRId8 "\n", __func__, 1588 PortName(), fMaxLanes); 1589 1590 // fetch EDID but determine 'in use' later (below) so we also catch screens that fail EDID 1591 HasEDID(); 1592 1593 // scan all our pipes to find the one connected to the current port and check it's enabled 1594 uint32 pipeState = 0; 1595 for (uint32 pipeCnt = 0; pipeCnt < 4; pipeCnt++) { 1596 switch (pipeCnt) { 1597 case 0: 1598 pipeState = read32(PIPE_DDI_FUNC_CTL_A); 1599 break; 1600 case 1: 1601 pipeState = read32(PIPE_DDI_FUNC_CTL_B); 1602 break; 1603 case 2: 1604 pipeState = read32(PIPE_DDI_FUNC_CTL_C); 1605 break; 1606 default: 1607 pipeState = read32(PIPE_DDI_FUNC_CTL_EDP); 1608 break; 1609 } 1610 1611 if ((((pipeState & PIPE_DDI_SELECT_MASK) >> PIPE_DDI_SELECT_SHIFT) + 1) == (uint32)PortIndex()) { 1612 // See if the BIOS enabled our output as it indicates it's in use 1613 if (pipeState & PIPE_DDI_FUNC_CTL_ENABLE) { 1614 TRACE("%s: Connected\n", __func__); 1615 return true; 1616 } 1617 } 1618 } 1619 1620 // On laptops we always have an internal panel.. (this is on the eDP port) 1621 if (gInfo->shared_info->device_type.IsMobile() && (PortIndex() == INTEL_PORT_E)) { 1622 if (gInfo->shared_info->has_vesa_edid_info) { 1623 TRACE("%s: Laptop. Using VESA edid info\n", __func__); 1624 memcpy(&fEDIDInfo, &gInfo->shared_info->vesa_edid_info, 1625 sizeof(edid1_info)); 1626 if (fEDIDState != B_OK) { 1627 fEDIDState = B_OK; 1628 // HasEDID now true 1629 edid_dump(&fEDIDInfo); 1630 } 1631 return true; 1632 } else if (gInfo->shared_info->got_vbt) { 1633 TRACE("%s: Laptop. No EDID, but force enabled as we have a VBT\n", __func__); 1634 return true; 1635 } 1636 } 1637 1638 TRACE("%s: Not connected\n", __func__); 1639 return false; 1640 } 1641 1642 status_t 1643 DigitalDisplayInterface::_SetPortLinkGen8(const display_timing& timing, uint32 pllSel) 1644 { 1645 //fixme: always so on pre gen 9? 1646 uint32 linkBandwidth = 270000; //khz 1647 1648 if (gInfo->shared_info->device_type.Generation() >= 9) { 1649 if (pllSel != 0xff) { 1650 linkBandwidth = (read32(SKL_DPLL_CTRL1) >> (1 + 6 * pllSel)) & SKL_DPLL_DP_LINKRATE_MASK; 1651 switch (linkBandwidth) { 1652 case SKL_DPLL_CTRL1_2700: 1653 linkBandwidth = 2700000 / 5; 1654 break; 1655 case SKL_DPLL_CTRL1_1350: 1656 linkBandwidth = 1350000 / 5; 1657 break; 1658 case SKL_DPLL_CTRL1_810: 1659 linkBandwidth = 810000 / 5; 1660 break; 1661 case SKL_DPLL_CTRL1_1620: 1662 linkBandwidth = 1620000 / 5; 1663 break; 1664 case SKL_DPLL_CTRL1_1080: 1665 linkBandwidth = 1080000 / 5; 1666 break; 1667 case SKL_DPLL_CTRL1_2160: 1668 linkBandwidth = 2160000 / 5; 1669 break; 1670 default: 1671 linkBandwidth = 270000; 1672 ERROR("%s: DDI No known DP-link reference clock selected, assuming default\n", __func__); 1673 break; 1674 } 1675 } else { 1676 ERROR("%s: DDI No known PLL selected, assuming default DP-link reference\n", __func__); 1677 } 1678 } 1679 TRACE("%s: DDI DP-link reference clock is %gMhz\n", __func__, linkBandwidth / 1000.0f); 1680 1681 uint32 fPipeOffset = 0; 1682 switch (fPipe->Index()) { 1683 case INTEL_PIPE_B: 1684 fPipeOffset = 0x1000; 1685 break; 1686 case INTEL_PIPE_C: 1687 fPipeOffset = 0x2000; 1688 break; 1689 case INTEL_PIPE_D: 1690 fPipeOffset = 0xf000; 1691 break; 1692 default: 1693 break; 1694 } 1695 1696 TRACE("%s: DDI M1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_DATA_M + fPipeOffset)); 1697 TRACE("%s: DDI N1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_DATA_N + fPipeOffset)); 1698 TRACE("%s: DDI M1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_LINK_M + fPipeOffset)); 1699 TRACE("%s: DDI N1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_LINK_N + fPipeOffset)); 1700 1701 uint32 pipeFunc = read32(PIPE_DDI_FUNC_CTL_A + fPipeOffset); 1702 uint32 bitsPerPixel = (pipeFunc & PIPE_DDI_BPC_MASK) >> PIPE_DDI_COLOR_SHIFT; 1703 switch (bitsPerPixel) { 1704 case PIPE_DDI_8BPC: 1705 bitsPerPixel = 24; 1706 break; 1707 case PIPE_DDI_10BPC: 1708 bitsPerPixel = 30; 1709 break; 1710 case PIPE_DDI_6BPC: 1711 bitsPerPixel = 18; 1712 break; 1713 case PIPE_DDI_12BPC: 1714 bitsPerPixel = 36; 1715 break; 1716 default: 1717 ERROR("%s: DDI illegal link colordepth set.\n", __func__); 1718 return B_ERROR; 1719 } 1720 TRACE("%s: DDI Link Colordepth: %" B_PRIu32 "\n", __func__, bitsPerPixel); 1721 1722 uint32 lanes = 4; 1723 // Only DP modes supports less than 4 lanes: read current config 1724 if (((pipeFunc & PIPE_DDI_MODESEL_MASK) >> PIPE_DDI_MODESEL_SHIFT) >= PIPE_DDI_MODE_DP_SST) { 1725 // On gen 9.5 IceLake 3x mode exists (DSI only), earlier models: reserved value. 1726 lanes = ((pipeFunc & PIPE_DDI_DP_WIDTH_MASK) >> PIPE_DDI_DP_WIDTH_SHIFT) + 1; 1727 TRACE("%s: DDI in DP mode with %" B_PRIx32 " lane(s) in use\n", __func__, lanes); 1728 } else { 1729 TRACE("%s: DDI in non-DP mode with %" B_PRIx32 " lane(s) in use\n", __func__, lanes); 1730 } 1731 1732 //Setup Data M/N 1733 uint64 linkspeed = lanes * linkBandwidth * 8; 1734 uint64 ret_n = 1; 1735 while(ret_n < linkspeed) { 1736 ret_n *= 2; 1737 } 1738 if (ret_n > 0x800000) { 1739 ret_n = 0x800000; 1740 } 1741 uint64 ret_m = timing.pixel_clock * ret_n * bitsPerPixel / linkspeed; 1742 while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) { 1743 ret_m >>= 1; 1744 ret_n >>= 1; 1745 } 1746 //Set TU size bits (to default, max) before link training so that error detection works 1747 write32(INTEL_DDI_PIPE_A_DATA_M + fPipeOffset, ret_m | FDI_PIPE_MN_TU_SIZE_MASK); 1748 write32(INTEL_DDI_PIPE_A_DATA_N + fPipeOffset, ret_n); 1749 1750 //Setup Link M/N 1751 linkspeed = linkBandwidth; 1752 ret_n = 1; 1753 while(ret_n < linkspeed) { 1754 ret_n *= 2; 1755 } 1756 if (ret_n > 0x800000) { 1757 ret_n = 0x800000; 1758 } 1759 ret_m = timing.pixel_clock * ret_n / linkspeed; 1760 while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) { 1761 ret_m >>= 1; 1762 ret_n >>= 1; 1763 } 1764 write32(INTEL_DDI_PIPE_A_LINK_M + fPipeOffset, ret_m); 1765 //Writing Link N triggers all four registers to be activated also (on next VBlank) 1766 write32(INTEL_DDI_PIPE_A_LINK_N + fPipeOffset, ret_n); 1767 1768 TRACE("%s: DDI M1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_DATA_M + fPipeOffset)); 1769 TRACE("%s: DDI N1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_DATA_N + fPipeOffset)); 1770 TRACE("%s: DDI M1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_LINK_M + fPipeOffset)); 1771 TRACE("%s: DDI N1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_LINK_N + fPipeOffset)); 1772 1773 return B_OK; 1774 } 1775 1776 status_t 1777 DigitalDisplayInterface::SetDisplayMode(display_mode* target, uint32 colorMode) 1778 { 1779 CALLED(); 1780 TRACE("%s: %s %dx%d\n", __func__, PortName(), target->timing.h_display, 1781 target->timing.v_display); 1782 1783 if (fPipe == NULL) { 1784 ERROR("%s: Setting display mode without assigned pipe!\n", __func__); 1785 return B_ERROR; 1786 } 1787 1788 display_timing hardwareTarget = target->timing; 1789 bool needsScaling = false; 1790 if ((PortIndex() == INTEL_PORT_E) && gInfo->shared_info->device_type.IsMobile()) { 1791 // For internal panels, we may need to set the timings according to the panel 1792 // native video mode, and let the panel fitter do the scaling. 1793 1794 if (gInfo->shared_info->got_vbt) { 1795 // Set vbios hardware panel mode as base 1796 hardwareTarget = gInfo->shared_info->panel_timing; 1797 1798 if (hardwareTarget.h_display == target->timing.h_display 1799 && hardwareTarget.v_display == target->timing.v_display) { 1800 // We are setting the native video mode, nothing special to do 1801 // Note: this means refresh and timing might vary according to requested mode. 1802 hardwareTarget = target->timing; 1803 TRACE("%s: Setting internal panel to native resolution at %" B_PRIu32 "Hz\n", __func__, 1804 hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * hardwareTarget.v_total)); 1805 } else { 1806 // We need to enable the panel fitter 1807 TRACE("%s: Hardware mode will actually be %dx%d at %" B_PRIu32 "Hz\n", __func__, 1808 hardwareTarget.h_display, hardwareTarget.v_display, 1809 hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * hardwareTarget.v_total)); 1810 1811 // FIXME we should also get the refresh frequency from the target 1812 // mode, and then "sanitize" the resulting mode we made up. 1813 needsScaling = true; 1814 } 1815 } else { 1816 TRACE("%s: Setting internal panel mode without VBT info generation, scaling may not work\n", 1817 __func__); 1818 // We don't have VBT data, try to set the requested mode directly 1819 // and hope for the best 1820 hardwareTarget = target->timing; 1821 } 1822 } 1823 1824 // Setup PanelFitter 1825 PanelFitter* fitter = fPipe->PFT(); 1826 if (fitter != NULL) 1827 fitter->Enable(hardwareTarget); 1828 1829 // skip FDI as it never applies to DDI (on gen7 and 8 only for the real analog VGA port) 1830 1831 // Program general pipe config 1832 fPipe->Configure(target); 1833 1834 uint32 pllSel = 0xff; // no PLL selected 1835 if (gInfo->shared_info->device_type.Generation() <= 8) { 1836 unsigned int r2_out, n2_out, p_out; 1837 hsw_ddi_calculate_wrpll( 1838 hardwareTarget.pixel_clock * 1000 /* in Hz */, 1839 &r2_out, &n2_out, &p_out); 1840 } else { 1841 skl_wrpll_params wrpll_params; 1842 skl_ddi_calculate_wrpll( 1843 hardwareTarget.pixel_clock * 1000 /* in Hz */, 1844 gInfo->shared_info->pll_info.reference_frequency, 1845 &wrpll_params); 1846 fPipe->ConfigureClocksSKL(wrpll_params, 1847 hardwareTarget.pixel_clock, 1848 PortIndex(), 1849 &pllSel); 1850 } 1851 1852 // Program target display mode 1853 fPipe->ConfigureTimings(target, !needsScaling); 1854 _SetPortLinkGen8(hardwareTarget, pllSel); 1855 1856 // Set fCurrentMode to our set display mode 1857 memcpy(&fCurrentMode, target, sizeof(display_mode)); 1858 1859 return B_OK; 1860 } 1861