xref: /haiku/src/add-ons/accelerants/intel_extreme/Ports.cpp (revision fce7f3a748cd57bb62fcdd32c84bf013d88ea351)
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