xref: /haiku/src/add-ons/accelerants/intel_extreme/Ports.cpp (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
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  *		Rudolf Cornelissen, ruud@highsand-juicylake.nl
10  */
11 
12 
13 #include "Ports.h"
14 
15 #include <ddc.h>
16 #include <dp_raw.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <Debug.h>
20 #include <KernelExport.h>
21 
22 #include "accelerant.h"
23 #include "accelerant_protos.h"
24 #include "FlexibleDisplayInterface.h"
25 #include "intel_extreme.h"
26 #include "PanelFitter.h"
27 
28 #include <new>
29 
30 
31 #undef TRACE
32 #define TRACE_PORTS
33 #ifdef TRACE_PORTS
34 #   define TRACE(x...) _sPrintf("intel_extreme: " x)
35 #else
36 #   define TRACE(x...)
37 #endif
38 
39 #define ERROR(x...) _sPrintf("intel_extreme: " x)
40 #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
41 
42 
43 static bool
44 wait_for_set(addr_t address, uint32 mask, uint32 timeout)
45 {
46 	int interval = 50;
47 	uint32 i = 0;
48 	for(i = 0; i <= timeout; i += interval) {
49 		spin(interval);
50 		if ((read32(address) & mask) != 0)
51 			return true;
52 	}
53 	return false;
54 }
55 
56 
57 static bool
58 wait_for_clear(addr_t address, uint32 mask, uint32 timeout)
59 {
60 	int interval = 50;
61 	uint32 i = 0;
62 	for(i = 0; i <= timeout; i += interval) {
63 		spin(interval);
64 		if ((read32(address) & mask) == 0)
65 			return true;
66 	}
67 	return false;
68 }
69 
70 
71 static uint32
72 wait_for_clear_status(addr_t address, uint32 mask, uint32 timeout)
73 {
74 	int interval = 50;
75 	uint32 i = 0;
76 	uint32 status = 0;
77 	for(i = 0; i <= timeout; i += interval) {
78 		spin(interval);
79 		status = read32(address);
80 		if ((status & mask) == 0)
81 			return status;
82 	}
83 	return status;
84 }
85 
86 
87 Port::Port(port_index index, const char* baseName)
88 	:
89 	fPipe(NULL),
90 	fEDIDState(B_NO_INIT),
91 	fPortIndex(index),
92 	fPortName(NULL)
93 {
94 	char portID[2];
95 	portID[0] = 'A' + index - INTEL_PORT_A;
96 	portID[1] = 0;
97 
98 	char buffer[32];
99 	buffer[0] = 0;
100 
101 	strlcat(buffer, baseName, sizeof(buffer));
102 	strlcat(buffer, " ", sizeof(buffer));
103 	strlcat(buffer, portID, sizeof(buffer));
104 	fPortName = strdup(buffer);
105 }
106 
107 
108 Port::~Port()
109 {
110 	free(fPortName);
111 }
112 
113 
114 bool
115 Port::HasEDID()
116 {
117 	if (fEDIDState == B_NO_INIT)
118 		GetEDID(NULL);
119 
120 	return fEDIDState == B_OK;
121 }
122 
123 
124 status_t
125 Port::SetPipe(Pipe* pipe)
126 {
127 	CALLED();
128 
129 	if (pipe == NULL) {
130 		ERROR("%s: Invalid pipe provided!\n", __func__);
131 		return B_ERROR;
132 	}
133 
134 	uint32 portRegister = _PortRegister();
135 	if (portRegister == 0) {
136 		ERROR("%s: Invalid PortRegister ((0x%" B_PRIx32 ") for %s\n", __func__,
137 			portRegister, PortName());
138 		return B_ERROR;
139 	}
140 
141 	// TODO: UnAssignPipe?  This likely needs reworked a little
142 	if (fPipe != NULL) {
143 		ERROR("%s: Can't reassign display pipe (yet)\n", __func__);
144 		return B_ERROR;
145 	}
146 
147 	switch (pipe->Index()) {
148 		case INTEL_PIPE_B:
149 			TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe B\n", __func__,
150 				PortName(), portRegister);
151 			break;
152 		case INTEL_PIPE_C:
153 			TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe C\n", __func__,
154 				PortName(), portRegister);
155 			break;
156 		case INTEL_PIPE_D:
157 			TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe D\n", __func__,
158 				PortName(), portRegister);
159 			break;
160 		default:
161 			TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe A\n", __func__,
162 				PortName(), portRegister);
163 			break;
164 	}
165 
166 	uint32 portState = read32(portRegister);
167 
168 	// generation 6 gfx SandyBridge/SNB non-DP use the same 2 bits on all ports (eDP = 1 bit).
169 	// generation 7 gfx IvyBridge/IVB non-DP use the same 2 bits on all ports (eDP = 2 bits).
170 	// DP ports/all DDI ports: Pipe selections works differently, via own SetPipe() implementation.
171 	if (gInfo->shared_info->pch_info == INTEL_PCH_CPT) {
172 		portState &= ~PORT_TRANS_SEL_MASK;
173 		switch (pipe->Index()) {
174 			case INTEL_PIPE_B:
175 				write32(portRegister, portState | PORT_TRANS_B_SEL_CPT);
176 				break;
177 			case INTEL_PIPE_C:
178 				write32(portRegister, portState | PORT_TRANS_C_SEL_CPT);
179 				break;
180 			default:
181 				write32(portRegister, portState | PORT_TRANS_A_SEL_CPT);
182 				break;
183 		}
184 	} else {
185 		// generation 3/4/5 gfx uses the same single bit on all ports
186 		if (pipe->Index() == INTEL_PIPE_A)
187 			write32(portRegister, portState & ~DISPLAY_MONITOR_PIPE_B);
188 		else
189 			write32(portRegister, portState | DISPLAY_MONITOR_PIPE_B);
190 	}
191 	fPipe = pipe;
192 
193 	if (fPipe == NULL)
194 		return B_NO_MEMORY;
195 
196 	// Disable display pipe until modesetting enables it
197 	if (fPipe->IsEnabled())
198 		fPipe->Enable(false);
199 
200 	read32(portRegister);
201 
202 	return B_OK;
203 }
204 
205 
206 status_t
207 Port::Power(bool enabled)
208 {
209 	if (fPipe == NULL) {
210 		ERROR("%s: Setting power mode without assigned pipe!\n", __func__);
211 		return B_ERROR;
212 	}
213 
214 	fPipe->Enable(enabled);
215 
216 	return B_OK;
217 }
218 
219 
220 status_t
221 Port::GetEDID(edid1_info* edid, bool forceRead)
222 {
223 	CALLED();
224 
225 	if (fEDIDState == B_NO_INIT || forceRead) {
226 		TRACE("%s: trying to read EDID\n", PortName());
227 
228 		i2c_bus bus;
229 		if (SetupI2c(&bus) != B_OK)
230 			return fEDIDState;
231 
232 		fEDIDState = ddc2_read_edid1(&bus, &fEDIDInfo, NULL, NULL);
233 
234 		if (fEDIDState == B_OK) {
235 			TRACE("%s: found EDID information!\n", PortName());
236 			edid_dump(&fEDIDInfo);
237 		} else if (SetupI2cFallback(&bus) == B_OK) {
238 			fEDIDState = ddc2_read_edid1(&bus, &fEDIDInfo, NULL, NULL);
239 
240 			if (fEDIDState == B_OK) {
241 				TRACE("%s: found EDID information!\n", PortName());
242 				edid_dump(&fEDIDInfo);
243 			}
244 		}
245 	}
246 
247 	if (fEDIDState != B_OK) {
248 		TRACE("%s: no EDID information found.\n", PortName());
249 		return fEDIDState;
250 	}
251 
252 	if (edid != NULL)
253 		memcpy(edid, &fEDIDInfo, sizeof(edid1_info));
254 
255 	return B_OK;
256 }
257 
258 
259 status_t
260 Port::SetupI2c(i2c_bus *bus)
261 {
262 	addr_t ddcRegister = _DDCRegister();
263 	if (ddcRegister == 0) {
264 		TRACE("%s: no DDC register found\n", PortName());
265 		fEDIDState = B_ERROR;
266 		return fEDIDState;
267 	}
268 
269 	TRACE("%s: using ddc @ 0x%" B_PRIxADDR "\n", PortName(), ddcRegister);
270 
271 	ddc2_init_timing(bus);
272 	bus->cookie = (void*)ddcRegister;
273 	bus->set_signals = &_SetI2CSignals;
274 	bus->get_signals = &_GetI2CSignals;
275 
276 	return B_OK;
277 }
278 
279 
280 status_t
281 Port::SetupI2cFallback(i2c_bus *bus)
282 {
283 	return B_ERROR;
284 }
285 
286 
287 status_t
288 Port::GetPLLLimits(pll_limits& limits)
289 {
290 	return B_ERROR;
291 }
292 
293 
294 pipe_index
295 Port::PipePreference()
296 {
297 	CALLED();
298 	// Ideally we could just return INTEL_PIPE_ANY for all devices by default, but
299 	// this doesn't quite work yet. We need to use the BIOS presetup pipes for now.
300 	if (gInfo->shared_info->device_type.Generation() < 4)
301 		return INTEL_PIPE_ANY;
302 
303 	// Notes:
304 	// - The BIOSes seen sofar do not use PIPE C by default.
305 	// - The BIOSes seen sofar program transcoder A to PIPE A, etc.
306 	// - Later devices add a pipe C alongside the added transcoder C.
307 
308 	if ((gInfo->shared_info->device_type.Generation() <= 7) &&
309 		(!gInfo->shared_info->device_type.HasDDI())) {
310 		uint32 portState = read32(_PortRegister());
311 		if (gInfo->shared_info->pch_info == INTEL_PCH_CPT) {
312 			portState &= PORT_TRANS_SEL_MASK;
313 			if (portState == PORT_TRANS_B_SEL_CPT)
314 				return INTEL_PIPE_B;
315 			else
316 				return INTEL_PIPE_A;
317 		} else {
318 			if (portState & DISPLAY_MONITOR_PIPE_B)
319 				return INTEL_PIPE_B;
320 			else
321 				return INTEL_PIPE_A;
322 		}
323 	}
324 
325 	if (gInfo->shared_info->device_type.HasDDI()) {
326 		// scan all our pipes to find the one connected to the current port
327 		uint32 pipeState = 0;
328 		for (uint32 pipeCnt = 0; pipeCnt < 4; pipeCnt++) {
329 			switch (pipeCnt) {
330 				case 0:
331 					pipeState = read32(PIPE_DDI_FUNC_CTL_A);
332 					break;
333 				case 1:
334 					pipeState = read32(PIPE_DDI_FUNC_CTL_B);
335 					break;
336 				case 2:
337 					pipeState = read32(PIPE_DDI_FUNC_CTL_C);
338 					break;
339 				default:
340 					pipeState = read32(PIPE_DDI_FUNC_CTL_EDP);
341 					break;
342 			}
343 
344 			if ((((pipeState & PIPE_DDI_SELECT_MASK) >> PIPE_DDI_SELECT_SHIFT) + 1)
345 				== (uint32)PortIndex()) {
346 				switch (pipeCnt) {
347 					case 0:
348 						return INTEL_PIPE_A;
349 					case 1:
350 						return INTEL_PIPE_B;
351 					case 2:
352 						return INTEL_PIPE_C;
353 					default:
354 						return INTEL_PIPE_D;
355 				}
356 			}
357 		}
358 	}
359 
360 	return INTEL_PIPE_ANY;
361 }
362 
363 
364 status_t
365 Port::_GetI2CSignals(void* cookie, int* _clock, int* _data)
366 {
367 	addr_t ioRegister = (addr_t)cookie;
368 	uint32 value = read32(ioRegister);
369 
370 	*_clock = (value & I2C_CLOCK_VALUE_IN) != 0;
371 	*_data = (value & I2C_DATA_VALUE_IN) != 0;
372 
373 	return B_OK;
374 }
375 
376 
377 status_t
378 Port::_SetI2CSignals(void* cookie, int clock, int data)
379 {
380 	addr_t ioRegister = (addr_t)cookie;
381 	uint32 value;
382 
383 	if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_83x)) {
384 		// on these chips, the reserved values are fixed
385 		value = 0;
386 	} else {
387 		// on all others, we have to preserve them manually
388 		value = read32(ioRegister) & I2C_RESERVED;
389 	}
390 
391 	// if we send clk or data, we always send low logic level;
392 	// if we want to send high level, we actually receive and let the
393 	// external pullup resistors create the high level on the bus.
394 	value |= I2C_DATA_VALUE_MASK;  //sets data = 0, always latch
395 	value |= I2C_CLOCK_VALUE_MASK; //sets clock = 0, always latch
396 
397 	if (data != 0)
398 		value |= I2C_DATA_DIRECTION_MASK;
399 	else {
400 		value |= I2C_DATA_DIRECTION_MASK | I2C_DATA_DIRECTION_OUT;
401 	}
402 
403 	if (clock != 0)
404 		value |= I2C_CLOCK_DIRECTION_MASK;
405 	else {
406 		value |= I2C_CLOCK_DIRECTION_MASK | I2C_CLOCK_DIRECTION_OUT;
407 	}
408 
409 	write32(ioRegister, value);
410 	read32(ioRegister);
411 		// make sure the PCI bus has flushed the write
412 
413 	return B_OK;
414 }
415 
416 
417 bool
418 Port::_IsPortInVBT(uint32* foundIndex)
419 {
420 	// check VBT mapping
421 	bool found = false;
422 	const uint32 deviceConfigCount = gInfo->shared_info->device_config_count;
423 	for (uint32 i = 0; i < deviceConfigCount; i++) {
424 		child_device_config& config = gInfo->shared_info->device_configs[i];
425 		if (config.dvo_port > DVO_PORT_HDMII) {
426 			ERROR("%s: DVO port unknown\n", __func__);
427 			continue;
428 		}
429 		dvo_port port = (dvo_port)config.dvo_port;
430 		switch (PortIndex()) {
431 			case INTEL_PORT_A:
432 				found = port == DVO_PORT_HDMIA || port == DVO_PORT_DPA;
433 				break;
434 			case INTEL_PORT_B:
435 				found = port == DVO_PORT_HDMIB || port == DVO_PORT_DPB;
436 				break;
437 			case INTEL_PORT_C:
438 				found = port == DVO_PORT_HDMIC || port == DVO_PORT_DPC;
439 				break;
440 			case INTEL_PORT_D:
441 				found = port == DVO_PORT_HDMID || port == DVO_PORT_DPD;
442 				break;
443 			case INTEL_PORT_E:
444 				found = port == DVO_PORT_HDMIE || port == DVO_PORT_DPE || port == DVO_PORT_CRT;
445 				break;
446 			case INTEL_PORT_F:
447 				found = port == DVO_PORT_HDMIF || port == DVO_PORT_DPF;
448 				break;
449 			default:
450 				ERROR("%s: DDI port unknown\n", __func__);
451 				break;
452 		}
453 		if (found) {
454 			if (foundIndex != NULL)
455 				*foundIndex = i;
456 			break;
457 		}
458 	}
459 	return found;
460 }
461 
462 
463 bool
464 Port::_IsDisplayPortInVBT()
465 {
466 	uint32 foundIndex = 0;
467 	if (!_IsPortInVBT(&foundIndex))
468 		return false;
469 	child_device_config& config = gInfo->shared_info->device_configs[foundIndex];
470 	return config.aux_channel > 0 && (config.device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT) != 0;
471 }
472 
473 
474 bool
475 Port::_IsHdmiInVBT()
476 {
477 	uint32 foundIndex = 0;
478 	if (!_IsPortInVBT(&foundIndex))
479 		return false;
480 	child_device_config& config = gInfo->shared_info->device_configs[foundIndex];
481 	return config.ddc_pin > 0 && ((config.device_type & DEVICE_TYPE_NOT_HDMI_OUTPUT) == 0
482 			|| (config.device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING) != 0);
483 }
484 
485 
486 bool
487 Port::_IsEDPPort()
488 {
489 	uint32 foundIndex = 0;
490 	if (!_IsPortInVBT(&foundIndex))
491 		return false;
492 	child_device_config& config = gInfo->shared_info->device_configs[foundIndex];
493 	return (config.device_type & (DEVICE_TYPE_INTERNAL_CONNECTOR | DEVICE_TYPE_DISPLAYPORT_OUTPUT))
494 		== (DEVICE_TYPE_INTERNAL_CONNECTOR | DEVICE_TYPE_DISPLAYPORT_OUTPUT);
495 }
496 
497 
498 status_t
499 Port::_SetupDpAuxI2c(i2c_bus *bus)
500 {
501 	CALLED();
502 
503 	ddc2_init_timing(bus);
504 	bus->cookie = this;
505 	bus->send_receive = &_DpAuxSendReceiveHook;
506 
507 	if (gInfo->shared_info->device_type.Generation() >= 11) {
508 		uint32 value = read32(ICL_PWR_WELL_CTL_AUX2);
509 		if ((value & HSW_PWR_WELL_CTL_STATE(0)) != 0)
510 			return B_OK;
511 
512 		write32(ICL_PWR_WELL_CTL_AUX2, value | HSW_PWR_WELL_CTL_REQ(0));
513 		if (!wait_for_set(ICL_PWR_WELL_CTL_AUX2, HSW_PWR_WELL_CTL_STATE(0), 1000))
514 			ERROR("%s: %s AUX didn't power on within 1000us!\n", __func__, PortName());
515 	}
516 	return B_OK;
517 }
518 
519 
520 status_t
521 Port::_DpAuxSendReceive(uint32 slaveAddress,
522 	const uint8 *writeBuffer, size_t writeLength, uint8 *readBuffer, size_t readLength)
523 {
524 	size_t transferLength = 16;
525 
526 	dp_aux_msg message;
527 	memset(&message, 0, sizeof(message));
528 
529 	if (writeBuffer != NULL) {
530 		message.address = slaveAddress;
531 		message.buffer = NULL;
532 		message.request = DP_AUX_I2C_WRITE;
533 		message.size = 0;
534 		ssize_t result = _DpAuxTransfer(&message);
535 		if (result < 0)
536 			return result;
537 
538 		for (size_t i = 0; i < writeLength;) {
539 			message.buffer = (void*)(writeBuffer + i);
540 			message.size = min_c(transferLength, writeLength - i);
541 			// Middle-Of-Transmission on final transaction
542 			if (writeLength - i > transferLength)
543 				message.request |= DP_AUX_I2C_MOT;
544 			else
545 				message.request &= ~DP_AUX_I2C_MOT;
546 
547 			for (int attempt = 0; attempt < 7; attempt++) {
548 				ssize_t result = _DpAuxTransfer(&message);
549 				if (result < 0) {
550 					ERROR("%s: aux_ch transaction failed!\n", __func__);
551 					return result;
552 				}
553 
554 				switch (message.reply & DP_AUX_I2C_REPLY_MASK) {
555 					case DP_AUX_I2C_REPLY_ACK:
556 						goto nextWrite;
557 					case DP_AUX_I2C_REPLY_NACK:
558 						TRACE("%s: aux i2c nack\n", __func__);
559 						return B_IO_ERROR;
560 					case DP_AUX_I2C_REPLY_DEFER:
561 						TRACE("%s: aux i2c defer\n", __func__);
562 						snooze(400);
563 						break;
564 					default:
565 						TRACE("%s: aux invalid I2C reply: 0x%02x\n",
566 							__func__, message.reply);
567 						return B_ERROR;
568 				}
569 			}
570 nextWrite:
571 			if (result < 0)
572 				return result;
573 			i += message.size;
574 		}
575 	}
576 
577 
578 	if (readBuffer != NULL) {
579 		message.address = slaveAddress;
580 		message.buffer = NULL;
581 		message.request = DP_AUX_I2C_READ;
582 		message.size = 0;
583 		ssize_t result = _DpAuxTransfer(&message);
584 		if (result < 0)
585 			return result;
586 
587 		for (size_t i = 0; i < readLength;) {
588 			message.buffer = readBuffer + i;
589 			message.size = min_c(transferLength, readLength - i);
590 			// Middle-Of-Transmission on final transaction
591 			if (readLength - i > transferLength)
592 				message.request |= DP_AUX_I2C_MOT;
593 			else
594 				message.request &= ~DP_AUX_I2C_MOT;
595 
596 			for (int attempt = 0; attempt < 7; attempt++) {
597 				result = _DpAuxTransfer(&message);
598 				if (result < 0) {
599 					ERROR("%s: aux_ch transaction failed!\n", __func__);
600 					return result;
601 				}
602 
603 				switch (message.reply & DP_AUX_I2C_REPLY_MASK) {
604 					case DP_AUX_I2C_REPLY_ACK:
605 						goto nextRead;
606 					case DP_AUX_I2C_REPLY_NACK:
607 						TRACE("%s: aux i2c nack\n", __func__);
608 						return B_IO_ERROR;
609 					case DP_AUX_I2C_REPLY_DEFER:
610 						TRACE("%s: aux i2c defer\n", __func__);
611 						snooze(400);
612 						break;
613 					default:
614 						TRACE("%s: aux invalid I2C reply: 0x%02x\n",
615 							__func__, message.reply);
616 						return B_ERROR;
617 				}
618 			}
619 nextRead:
620 			if (result < 0)
621 				return result;
622 			if (result == 0)
623 				i += message.size;
624 		}
625 	}
626 
627 	return B_OK;
628 }
629 
630 
631 status_t
632 Port::_DpAuxSendReceiveHook(const struct i2c_bus *bus, uint32 slaveAddress,
633 	const uint8 *writeBuffer, size_t writeLength, uint8 *readBuffer, size_t readLength)
634 {
635 	CALLED();
636 	Port* port = (Port*)bus->cookie;
637 	return port->_DpAuxSendReceive(slaveAddress, writeBuffer, writeLength, readBuffer, readLength);
638 }
639 
640 
641 ssize_t
642 Port::_DpAuxTransfer(dp_aux_msg* message)
643 {
644 	CALLED();
645 	if (message == NULL) {
646 		ERROR("%s: DP message is invalid!\n", __func__);
647 		return B_ERROR;
648 	}
649 
650 	if (message->size > 16) {
651 		ERROR("%s: Too many bytes! (%" B_PRIuSIZE ")\n", __func__,
652 			message->size);
653 		return B_ERROR;
654 	}
655 
656 	uint8 transmitSize = message->size > 0 ? 4 : 3;
657 	uint8 receiveSize;
658 
659 	switch(message->request & ~DP_AUX_I2C_MOT) {
660 		case DP_AUX_NATIVE_WRITE:
661 		case DP_AUX_I2C_WRITE:
662 		case DP_AUX_I2C_WRITE_STATUS_UPDATE:
663 			transmitSize += message->size;
664 			break;
665 	}
666 
667 	// If not bare address, check for buffer
668 	if (message->size > 0 && message->buffer == NULL) {
669 		ERROR("%s: DP message uninitalized buffer!\n", __func__);
670 		return B_ERROR;
671 	}
672 
673 	uint8 receiveBuffer[20];
674 	uint8 transmitBuffer[20];
675 	transmitBuffer[0] = (message->request << 4) | ((message->address >> 16) & 0xf);
676 	transmitBuffer[1] = (message->address >> 8) & 0xff;
677 	transmitBuffer[2] = message->address & 0xff;
678 	transmitBuffer[3] = message->size != 0 ? (message->size - 1) : 0;
679 
680 	uint8 retry;
681 	for (retry = 0; retry < 7; retry++) {
682 		ssize_t result = B_ERROR;
683 		switch(message->request & ~DP_AUX_I2C_MOT) {
684 			case DP_AUX_NATIVE_WRITE:
685 			case DP_AUX_I2C_WRITE:
686 			case DP_AUX_I2C_WRITE_STATUS_UPDATE:
687 				receiveSize = 2;
688 				if (message->buffer != NULL)
689 					memcpy(transmitBuffer + 4, message->buffer, message->size);
690 				result = _DpAuxTransfer(transmitBuffer,
691 					transmitSize, receiveBuffer, receiveSize);
692 				if (result > 0) {
693 					message->reply = receiveBuffer[0] >> 4;
694 					if (result > 1)
695 						result = min_c(receiveBuffer[1], message->size);
696 					else
697 						result = message->size;
698 				}
699 				break;
700 			case DP_AUX_NATIVE_READ:
701 			case DP_AUX_I2C_READ:
702 				receiveSize = message->size + 1;
703 				result = _DpAuxTransfer(transmitBuffer,
704 					transmitSize, receiveBuffer, receiveSize);
705 				if (result > 0) {
706 					message->reply = receiveBuffer[0] >> 4;
707 					result--;
708 					if (message->buffer != NULL)
709 						memcpy(message->buffer, receiveBuffer + 1, result);
710 				}
711 				break;
712 			default:
713 				ERROR("%s: Unknown dp_aux_msg request!\n", __func__);
714 				return B_ERROR;
715 		}
716 
717 		if (result == B_BUSY)
718 			continue;
719 		else if (result < B_OK)
720 			return result;
721 
722 		switch (message->reply & DP_AUX_NATIVE_REPLY_MASK) {
723 			case DP_AUX_NATIVE_REPLY_ACK:
724 				return B_OK;
725 			case DP_AUX_NATIVE_REPLY_NACK:
726 				TRACE("%s: aux native reply nack\n", __func__);
727 				return B_IO_ERROR;
728 			case DP_AUX_NATIVE_REPLY_DEFER:
729 				TRACE("%s: aux reply defer received. Snoozing.\n", __func__);
730 				snooze(400);
731 				break;
732 			default:
733 				TRACE("%s: aux invalid native reply: 0x%02x\n", __func__,
734 					message->reply);
735 				return B_IO_ERROR;
736 		}
737 	}
738 
739 	ERROR("%s: IO Error. %" B_PRIu8 " attempts\n", __func__, retry);
740 	return B_IO_ERROR;
741 }
742 
743 
744 ssize_t
745 Port::_DpAuxTransfer(uint8* transmitBuffer, uint8 transmitSize,
746 	uint8* receiveBuffer, uint8 receiveSize)
747 {
748 	addr_t channelControl;
749 	addr_t channelData[5];
750 	aux_channel channel = _DpAuxChannel();
751 	TRACE("%s: %s DpAuxChannel: 0x%x\n", __func__, PortName(), channel);
752 	if (gInfo->shared_info->device_type.Generation() >= 9
753 		|| (gInfo->shared_info->pch_info != INTEL_PCH_NONE && channel == AUX_CH_A)) {
754 		channelControl = DP_AUX_CH_CTL(channel);
755 		for (int i = 0; i < 5; i++)
756 			channelData[i] = DP_AUX_CH_DATA(channel, i);
757 	} else if (gInfo->shared_info->pch_info != INTEL_PCH_NONE) {
758 		channelControl = PCH_DP_AUX_CH_CTL(channel);
759 		for (int i = 0; i < 5; i++)
760 			channelData[i] = PCH_DP_AUX_CH_DATA(channel, i);
761 	} else {
762 		ERROR("Port::_DpAuxTransfer() unknown register config\n");
763 		return B_BUSY;
764 	}
765 	if (transmitSize > 20 || receiveSize > 20)
766 		return E2BIG;
767 
768 	int tries = 0;
769 	while ((read32(channelControl) & INTEL_DP_AUX_CTL_BUSY) != 0) {
770 		if (tries++ == 3) {
771 			ERROR("%s: %s AUX channel is busy!\n", __func__, PortName());
772 			return B_BUSY;
773 		}
774 		snooze(1000);
775 	}
776 
777 	uint32 sendControl = 0;
778 	if (gInfo->shared_info->device_type.Generation() >= 9) {
779 		sendControl = INTEL_DP_AUX_CTL_BUSY | INTEL_DP_AUX_CTL_DONE | INTEL_DP_AUX_CTL_INTERRUPT
780 			| INTEL_DP_AUX_CTL_TIMEOUT_ERROR | INTEL_DP_AUX_CTL_TIMEOUT_1600us | INTEL_DP_AUX_CTL_RECEIVE_ERROR
781 			| (transmitSize << INTEL_DP_AUX_CTL_MSG_SIZE_SHIFT) | INTEL_DP_AUX_CTL_FW_SYNC_PULSE_SKL(32)
782 			| INTEL_DP_AUX_CTL_SYNC_PULSE_SKL(32);
783 	} else {
784 		uint32 frequency = gInfo->shared_info->hw_cdclk;
785 		if (channel != AUX_CH_A)
786 			frequency = gInfo->shared_info->hraw_clock;
787 		uint32 aux_clock_divider = (frequency + 2000 / 2) / 2000;
788 		if (gInfo->shared_info->pch_info == INTEL_PCH_LPT && channel != AUX_CH_A)
789 			aux_clock_divider = 0x48; // or 0x3f
790 		uint32 timeout = INTEL_DP_AUX_CTL_TIMEOUT_400us;
791 		if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_BDW))
792 			timeout = INTEL_DP_AUX_CTL_TIMEOUT_600us;
793 		sendControl = INTEL_DP_AUX_CTL_BUSY | INTEL_DP_AUX_CTL_DONE | INTEL_DP_AUX_CTL_INTERRUPT
794 			| INTEL_DP_AUX_CTL_TIMEOUT_ERROR | timeout | INTEL_DP_AUX_CTL_RECEIVE_ERROR
795 			| (transmitSize << INTEL_DP_AUX_CTL_MSG_SIZE_SHIFT) | (3 << INTEL_DP_AUX_CTL_PRECHARGE_2US_SHIFT)
796 			| (aux_clock_divider << INTEL_DP_AUX_CTL_BIT_CLOCK_2X_SHIFT);
797 	}
798 
799 	uint8 retry;
800 	uint32 status = 0;
801 	for (retry = 0; retry < 5; retry++) {
802 		for (uint8 i = 0; i < transmitSize;) {
803 			uint8 index = i / 4;
804 			uint32 data = ((uint32)transmitBuffer[i++]) << 24;
805 			if (i < transmitSize)
806 				data |= ((uint32)transmitBuffer[i++]) << 16;
807 			if (i < transmitSize)
808 				data |= ((uint32)transmitBuffer[i++]) << 8;
809 			if (i < transmitSize)
810 				data |= transmitBuffer[i++];
811 			write32(channelData[index], data);
812 		}
813 		write32(channelControl, sendControl);
814 
815 		// wait 10 ms reading channelControl until INTEL_DP_AUX_CTL_BUSY
816 		status = wait_for_clear_status(channelControl, INTEL_DP_AUX_CTL_BUSY, 10000);
817 		if ((status & INTEL_DP_AUX_CTL_BUSY) != 0) {
818 			ERROR("%s: %s AUX channel stayed busy for 10000us!\n", __func__, PortName());
819 		}
820 
821 		write32(channelControl, status | INTEL_DP_AUX_CTL_DONE | INTEL_DP_AUX_CTL_TIMEOUT_ERROR
822 			| INTEL_DP_AUX_CTL_RECEIVE_ERROR);
823 		if ((status & INTEL_DP_AUX_CTL_TIMEOUT_ERROR) != 0)
824 			continue;
825 		if ((status & INTEL_DP_AUX_CTL_RECEIVE_ERROR) != 0) {
826 			snooze(400);
827 			continue;
828 		}
829 		if ((status & INTEL_DP_AUX_CTL_DONE) != 0)
830 			goto done;
831 	}
832 
833 	if ((status & INTEL_DP_AUX_CTL_DONE) == 0) {
834 		ERROR("%s: Busy Error. %" B_PRIu8 " attempts\n", __func__, retry);
835 		return B_BUSY;
836 	}
837 done:
838 	if ((status & INTEL_DP_AUX_CTL_RECEIVE_ERROR) != 0)
839 		return B_IO_ERROR;
840 	if ((status & INTEL_DP_AUX_CTL_TIMEOUT_ERROR) != 0)
841 		return B_TIMEOUT;
842 
843 	uint8 bytes = (status & INTEL_DP_AUX_CTL_MSG_SIZE_MASK) >> INTEL_DP_AUX_CTL_MSG_SIZE_SHIFT;
844 	if (bytes == 0 || bytes > 20) {
845 		ERROR("%s: Status byte count incorrect %u\n", __func__, bytes);
846 		return B_BUSY;
847 	}
848 	if (bytes > receiveSize)
849 		bytes = receiveSize;
850 	for (uint8 i = 0; i < bytes;) {
851 		uint32 data = read32(channelData[i / 4]);
852 		receiveBuffer[i++] = data >> 24;
853 		if (i < bytes)
854 			receiveBuffer[i++] = data >> 16;
855 		if (i < bytes)
856 			receiveBuffer[i++] = data >> 8;
857 		if (i < bytes)
858 			receiveBuffer[i++] = data;
859 	}
860 
861 	return bytes;
862 }
863 
864 
865 aux_channel
866 Port::_DpAuxChannel()
867 {
868 	uint32 foundIndex = 0;
869 	if (!_IsPortInVBT(&foundIndex))
870 		return AUX_CH_A;
871 	child_device_config& config = gInfo->shared_info->device_configs[foundIndex];
872 	switch (config.aux_channel) {
873 		case DP_AUX_B:
874 			return AUX_CH_B;
875 		case DP_AUX_C:
876 			return AUX_CH_C;
877 		case DP_AUX_D:
878 			return AUX_CH_D;
879 		case DP_AUX_E:
880 			return AUX_CH_E;
881 		case DP_AUX_F:
882 			return AUX_CH_F;
883 		default:
884 			return AUX_CH_A;
885 	}
886 }
887 
888 
889 // #pragma mark - Analog Port
890 
891 
892 AnalogPort::AnalogPort()
893 	:
894 	Port(INTEL_PORT_A, "Analog")
895 {
896 }
897 
898 
899 bool
900 AnalogPort::IsConnected()
901 {
902 	TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(),
903 		_PortRegister());
904 	return HasEDID();
905 }
906 
907 
908 addr_t
909 AnalogPort::_DDCRegister()
910 {
911 	// always fixed
912 	return INTEL_I2C_IO_A;
913 }
914 
915 
916 addr_t
917 AnalogPort::_PortRegister()
918 {
919 	// always fixed
920 	return INTEL_ANALOG_PORT;
921 }
922 
923 
924 status_t
925 AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode)
926 {
927 	CALLED();
928 	TRACE("%s: %s %dx%d\n", __func__, PortName(), target->timing.h_display,
929 		target->timing.v_display);
930 
931 	if (fPipe == NULL) {
932 		ERROR("%s: Setting display mode without assigned pipe!\n", __func__);
933 		return B_ERROR;
934 	}
935 
936 	// Setup PanelFitter and Train FDI if it exists
937 	PanelFitter* fitter = fPipe->PFT();
938 	if (fitter != NULL)
939 		fitter->Enable(target->timing);
940 	FDILink* link = fPipe->FDI();
941 	if (link != NULL) {
942 		uint32 lanes = 0;
943 		uint32 linkBandwidth = 0;
944 		uint32 bitsPerPixel = 0;
945 		link->PreTrain(&target->timing, &linkBandwidth, &lanes, &bitsPerPixel);
946 		fPipe->SetFDILink(target->timing, linkBandwidth, lanes, bitsPerPixel);
947 		link->Train(&target->timing, lanes);
948 	}
949 	pll_divisors divisors;
950 	compute_pll_divisors(&target->timing, &divisors, false);
951 
952 	uint32 extraPLLFlags = 0;
953 	if (gInfo->shared_info->device_type.Generation() >= 3)
954 		extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL;
955 
956 	// Program general pipe config
957 	fPipe->Configure(target);
958 
959 	// Program pipe PLL's
960 	fPipe->ConfigureClocks(divisors, target->timing.pixel_clock, extraPLLFlags);
961 
962 	write32(_PortRegister(), (read32(_PortRegister())
963 		& ~(DISPLAY_MONITOR_POLARITY_MASK | DISPLAY_MONITOR_VGA_POLARITY))
964 		| ((target->timing.flags & B_POSITIVE_HSYNC) != 0
965 			? DISPLAY_MONITOR_POSITIVE_HSYNC : 0)
966 		| ((target->timing.flags & B_POSITIVE_VSYNC) != 0
967 			? DISPLAY_MONITOR_POSITIVE_VSYNC : 0));
968 
969 	// Program target display mode
970 	fPipe->ConfigureTimings(target);
971 
972 	// Set fCurrentMode to our set display mode
973 	memcpy(&fCurrentMode, target, sizeof(display_mode));
974 
975 	return B_OK;
976 }
977 
978 
979 // #pragma mark - LVDS Panel
980 
981 
982 LVDSPort::LVDSPort()
983 	:
984 	Port(INTEL_PORT_C, "LVDS")
985 {
986 	// Always unlock LVDS port as soon as we start messing with it.
987 	uint32 panelControl = INTEL_PANEL_CONTROL;
988 	if (gInfo->shared_info->pch_info != INTEL_PCH_NONE) {
989 		// FIXME writing there results in black screen on SandyBridge
990 		return;
991 		// panelControl = PCH_PANEL_CONTROL;
992 	}
993 	write32(panelControl, read32(panelControl) | PANEL_REGISTER_UNLOCK);
994 }
995 
996 
997 pipe_index
998 LVDSPort::PipePreference()
999 {
1000 	CALLED();
1001 	// Older devices have hardcoded pipe/port mappings, so just use that
1002 	if (gInfo->shared_info->device_type.Generation() < 4)
1003 		return INTEL_PIPE_B;
1004 
1005 	// Ideally we could just return INTEL_PIPE_ANY for the newer devices, but
1006 	// this doesn't quite work yet.
1007 
1008 	// On SandyBridge and later, there is a transcoder C. On SandyBridge at least
1009 	// that can't be used by the LVDS port (but A and B would be fine).
1010 	// On Ibex Point, SandyBridge and IvyBridge (tested) changing pipes does not
1011 	// work yet.
1012 	// Notes:
1013 	// - Switching Pipes only works reliably when a 'full modeswitch' is executed
1014 	//   (FDI training) so we have to reuse the BIOS preset setup always for now.
1015 	// - The BIOSes seen sofar do not use PIPE C by default.
1016 	// - The BIOSes seen sofar program transcoder A to PIPE A, etc.
1017 	// - Later devices add a pipe C alongside the added transcoder C.
1018 
1019 	// FIXME How's this setup in newer gens? Currently return Pipe B fixed there..
1020 	if (gInfo->shared_info->device_type.Generation() <= 7) {
1021 		uint32 portState = read32(_PortRegister());
1022 		if (gInfo->shared_info->pch_info == INTEL_PCH_CPT) {
1023 			portState &= PORT_TRANS_SEL_MASK;
1024 			if (portState == PORT_TRANS_B_SEL_CPT)
1025 				return INTEL_PIPE_B;
1026 			else
1027 				return INTEL_PIPE_A;
1028 		} else {
1029 			if (portState & DISPLAY_MONITOR_PIPE_B)
1030 				return INTEL_PIPE_B;
1031 			else
1032 				return INTEL_PIPE_A;
1033 		}
1034 	}
1035 
1036 	return INTEL_PIPE_B;
1037 }
1038 
1039 
1040 bool
1041 LVDSPort::IsConnected()
1042 {
1043 	TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(),
1044 		_PortRegister());
1045 
1046 	if (gInfo->shared_info->pch_info != INTEL_PCH_NONE) {
1047 		uint32 registerValue = read32(_PortRegister());
1048 		// there's a detection bit we can use
1049 		if ((registerValue & PCH_LVDS_DETECTED) == 0) {
1050 			TRACE("LVDS: Not detected\n");
1051 			return false;
1052 		}
1053 		// TODO: Skip if eDP support
1054 	} else if (gInfo->shared_info->device_type.Generation() <= 4) {
1055 		// Older generations don't have LVDS detection. If not mobile skip.
1056 		if (!gInfo->shared_info->device_type.IsMobile()) {
1057 			TRACE("LVDS: Skipping LVDS detection due to gen and not mobile\n");
1058 			return false;
1059 		}
1060 		// If mobile, try to grab EDID
1061 		// Linux seems to look at lid status for LVDS port detection
1062 		// If we don't get EDID, we can use vbios native mode or vesa?
1063 		if (!HasEDID()) {
1064 			if (gInfo->shared_info->has_vesa_edid_info) {
1065 				TRACE("LVDS: Using VESA edid info\n");
1066 				memcpy(&fEDIDInfo, &gInfo->shared_info->vesa_edid_info,
1067 					sizeof(edid1_info));
1068 				if (fEDIDState != B_OK) {
1069 					fEDIDState = B_OK;
1070 					// HasEDID now true
1071 					edid_dump(&fEDIDInfo);
1072 				}
1073 			} else if (gInfo->shared_info->got_vbt) {
1074 				TRACE("LVDS: No EDID, but force enabled as we have a VBT\n");
1075 				return true;
1076 			} else {
1077 				TRACE("LVDS: Couldn't find any valid EDID!\n");
1078 				return false;
1079 			}
1080 		}
1081 	}
1082 
1083 	// Try getting EDID, as the LVDS port doesn't overlap with anything else,
1084 	// we don't run the risk of getting someone else's data.
1085 	return HasEDID();
1086 }
1087 
1088 
1089 addr_t
1090 LVDSPort::_DDCRegister()
1091 {
1092 	// always fixed
1093 	return INTEL_I2C_IO_C;
1094 }
1095 
1096 
1097 addr_t
1098 LVDSPort::_PortRegister()
1099 {
1100 	// always fixed
1101 	return INTEL_DIGITAL_LVDS_PORT;
1102 }
1103 
1104 
1105 status_t
1106 LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode)
1107 {
1108 	CALLED();
1109 	if (target == NULL) {
1110 		ERROR("%s: Invalid target mode passed!\n", __func__);
1111 		return B_ERROR;
1112 	}
1113 
1114 	TRACE("%s: %s-%d %dx%d\n", __func__, PortName(), PortIndex(),
1115 		target->timing.h_display, target->timing.v_display);
1116 
1117 	if (fPipe == NULL) {
1118 		ERROR("%s: Setting display mode without assigned pipe!\n", __func__);
1119 		return B_ERROR;
1120 	}
1121 
1122 	addr_t panelControl = INTEL_PANEL_CONTROL;
1123 	addr_t panelStatus = INTEL_PANEL_STATUS;
1124 	if (gInfo->shared_info->pch_info != INTEL_PCH_NONE) {
1125 		panelControl = PCH_PANEL_CONTROL;
1126 		panelStatus = PCH_PANEL_STATUS;
1127 	}
1128 
1129 	if (gInfo->shared_info->device_type.Generation() != 4) {
1130 		// TODO not needed on any generation if we are using the panel fitter
1131 		// Power off Panel
1132 		write32(panelControl,
1133 			read32(panelControl) & ~PANEL_CONTROL_POWER_TARGET_ON);
1134 		read32(panelControl);
1135 
1136 		if (!wait_for_clear(panelStatus, PANEL_STATUS_POWER_ON, 1000)) {
1137 			ERROR("%s: %s didn't power off within 1000ms!\n", __func__,
1138 				PortName());
1139 		}
1140 	}
1141 
1142 	// For LVDS panels, we may need to set the timings according to the panel
1143 	// native video mode, and let the panel fitter do the scaling. But the
1144 	// place where the scaling happens varies accross generations of devices.
1145 	display_timing hardwareTarget;
1146 	bool needsScaling = false;
1147 
1148 	// TODO figure out how it's done (or if we need to configure something at
1149 	// all) for other generations
1150 	if (gInfo->shared_info->device_type.Generation() <= 6
1151 		&& gInfo->shared_info->device_type.Generation() >= 3
1152 		&& gInfo->shared_info->got_vbt) {
1153 		// Set vbios hardware panel mode as base
1154 		hardwareTarget = gInfo->shared_info->panel_timing;
1155 
1156 		if (hardwareTarget.h_display == target->timing.h_display
1157 				&& hardwareTarget.v_display == target->timing.v_display) {
1158 			// We are setting the native video mode, nothing special to do
1159 			// Note: this means refresh and timing might vary according to requested mode.
1160 			hardwareTarget = target->timing;
1161 			TRACE("%s: Setting LVDS to native resolution at %" B_PRIu32 "Hz\n", __func__,
1162 				hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * hardwareTarget.v_total));
1163 		} else {
1164 			// We need to enable the panel fitter
1165 			TRACE("%s: Hardware mode will actually be %dx%d at %" B_PRIu32 "Hz\n", __func__,
1166 				hardwareTarget.h_display, hardwareTarget.v_display,
1167 				hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * hardwareTarget.v_total));
1168 
1169 			// FIXME we should also get the refresh frequency from the target
1170 			// mode, and then "sanitize" the resulting mode we made up.
1171 			needsScaling = true;
1172 		}
1173 	} else {
1174 		TRACE("Setting LVDS mode without VBT info or on unhandled hardware "
1175 			"generation, scaling may not work\n");
1176 		// We don't have VBT data, try to set the requested mode directly
1177 		// and hope for the best
1178 		hardwareTarget = target->timing;
1179 	}
1180 
1181 	// Setup PanelFitter and Train FDI if it exists
1182 	PanelFitter* fitter = fPipe->PFT();
1183 	if (fitter != NULL)
1184 		fitter->Enable(hardwareTarget);
1185 	FDILink* link = fPipe->FDI();
1186 	if (link != NULL) {
1187 		uint32 lanes = 0;
1188 		uint32 linkBandwidth = 0;
1189 		uint32 bitsPerPixel = 0;
1190 		link->PreTrain(&hardwareTarget, &linkBandwidth, &lanes, &bitsPerPixel);
1191 		fPipe->SetFDILink(hardwareTarget, linkBandwidth, lanes, bitsPerPixel);
1192 		link->Train(&hardwareTarget, lanes);
1193 	}
1194 
1195 	pll_divisors divisors;
1196 	compute_pll_divisors(&hardwareTarget, &divisors, true);
1197 
1198 	uint32 lvds = read32(_PortRegister())
1199 		| LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
1200 
1201 	if (gInfo->shared_info->device_type.Generation() == 4) {
1202 		// LVDS_A3_POWER_UP == 24bpp
1203 		// otherwise, 18bpp
1204 		if ((lvds & LVDS_A3_POWER_MASK) != LVDS_A3_POWER_UP)
1205 			lvds |= LVDS_18BIT_DITHER;
1206 	}
1207 
1208 	// LVDS on PCH needs set before display enable
1209 	if (gInfo->shared_info->pch_info == INTEL_PCH_CPT) {
1210 		lvds &= ~PORT_TRANS_SEL_MASK;
1211 		if (fPipe->Index() == INTEL_PIPE_A)
1212 			lvds |= PORT_TRANS_A_SEL_CPT;
1213 		else
1214 			lvds |= PORT_TRANS_B_SEL_CPT;
1215 	}
1216 
1217 	// Set the B0-B3 data pairs corresponding to whether we're going to
1218 	// set the DPLLs for dual-channel mode or not.
1219 	if (divisors.p2 == 5 || divisors.p2 == 7) {
1220 		TRACE("LVDS: dual channel\n");
1221 		lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
1222 	} else {
1223 		TRACE("LVDS: single channel\n");
1224 		lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
1225 	}
1226 
1227 	// LVDS port control moves polarity bits because Intel hates you.
1228 	// Set LVDS sync polarity
1229 	lvds &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
1230 
1231 	// set on - polarity.
1232 	if ((target->timing.flags & B_POSITIVE_HSYNC) == 0)
1233 		lvds |= LVDS_HSYNC_POLARITY;
1234 	if ((target->timing.flags & B_POSITIVE_VSYNC) == 0)
1235 		lvds |= LVDS_VSYNC_POLARITY;
1236 
1237 	TRACE("%s: LVDS Write: 0x%" B_PRIx32 "\n", __func__, lvds);
1238 	write32(_PortRegister(), lvds);
1239 	read32(_PortRegister());
1240 
1241 	uint32 extraPLLFlags = 0;
1242 
1243 	// DPLL mode LVDS for i915+
1244 	if (gInfo->shared_info->device_type.Generation() >= 3)
1245 		extraPLLFlags |= DISPLAY_PLL_MODE_LVDS | DISPLAY_PLL_2X_CLOCK;
1246 
1247 	// Program general pipe config
1248 	fPipe->Configure(target);
1249 
1250 	// Program pipe PLL's (using the hardware mode timings, since that's what
1251 	// the PLL is used for)
1252 	fPipe->ConfigureClocks(divisors, hardwareTarget.pixel_clock,
1253 		extraPLLFlags);
1254 
1255 	if (gInfo->shared_info->device_type.Generation() != 4) {
1256 		// G45: no need to power the panel off
1257 		// Power on Panel
1258 		write32(panelControl,
1259 			read32(panelControl) | PANEL_CONTROL_POWER_TARGET_ON);
1260 		read32(panelControl);
1261 
1262 		if (!wait_for_set(panelStatus, PANEL_STATUS_POWER_ON, 1000)) {
1263 			ERROR("%s: %s didn't power on within 1000us!\n", __func__,
1264 				PortName());
1265 		}
1266 	}
1267 
1268 	// Program target display mode
1269 	fPipe->ConfigureTimings(target, !needsScaling);
1270 
1271 	if (needsScaling) {
1272 		if (gInfo->shared_info->device_type.Generation() <= 4) {
1273 			// Enable panel fitter in automatic mode. It will figure out
1274 			// the scaling ratios automatically.
1275 			uint32 panelFitterControl = read32(INTEL_PANEL_FIT_CONTROL);
1276 			panelFitterControl |= PANEL_FITTER_ENABLED;
1277 			panelFitterControl &= ~(PANEL_FITTER_SCALING_MODE_MASK
1278 				| PANEL_FITTER_PIPE_MASK);
1279 			panelFitterControl |= PANEL_FITTER_PIPE_B;
1280 			// LVDS is always on pipe B.
1281 			write32(INTEL_PANEL_FIT_CONTROL, panelFitterControl);
1282 		}
1283 		// TODO do we need to do anything on later generations?
1284 	} else {
1285 		if (gInfo->shared_info->device_type.Generation() == 4
1286 			|| gInfo->shared_info->device_type.Generation() == 3) {
1287 			// Bypass the panel fitter
1288 			uint32 panelFitterControl = read32(INTEL_PANEL_FIT_CONTROL);
1289 			panelFitterControl &= ~PANEL_FITTER_ENABLED;
1290 			write32(INTEL_PANEL_FIT_CONTROL, panelFitterControl);
1291 		} else {
1292 			// We don't need to do anything more for later generations, the
1293 			// scaling is handled at the transcoder level. We may want to
1294 			// configure dithering, but the code below ignores the previous
1295 			// value in the register and may mess things up so we should do
1296 			// this in a safeer way. For now, assume the BIOS did the right
1297 			// thing.
1298 #if 0
1299 			// Disable panel fitting, but enable 8 to 6-bit dithering
1300 			write32(INTEL_PANEL_FIT_CONTROL, 0x4);
1301 				// TODO: do not do this if the connected panel is 24-bit
1302 				// (I don't know how to detect that)
1303 #endif
1304 		}
1305 	}
1306 
1307 	// Set fCurrentMode to our set display mode
1308 	memcpy(&fCurrentMode, target, sizeof(display_mode));
1309 
1310 	return B_OK;
1311 }
1312 
1313 
1314 // #pragma mark - DVI/SDVO/generic
1315 
1316 
1317 DigitalPort::DigitalPort(port_index index, const char* baseName)
1318 	:
1319 	Port(index, baseName)
1320 {
1321 }
1322 
1323 
1324 bool
1325 DigitalPort::IsConnected()
1326 {
1327 	TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(),
1328 		_PortRegister());
1329 
1330 	// As this port overlaps with pretty much everything, this must be called
1331 	// after having ruled out all other port types.
1332 	return HasEDID();
1333 }
1334 
1335 
1336 addr_t
1337 DigitalPort::_DDCRegister()
1338 {
1339 	//TODO: IS BROXTON, B = B, C = C, D = NIL
1340 	switch (PortIndex()) {
1341 		case INTEL_PORT_B:
1342 			return INTEL_I2C_IO_E;
1343 		case INTEL_PORT_C:
1344 			return INTEL_I2C_IO_D;
1345 		case INTEL_PORT_D:
1346 			return INTEL_I2C_IO_F;
1347 		default:
1348 			return 0;
1349 	}
1350 
1351 	return 0;
1352 }
1353 
1354 
1355 addr_t
1356 DigitalPort::_PortRegister()
1357 {
1358 	switch (PortIndex()) {
1359 		case INTEL_PORT_A:
1360 			return INTEL_DIGITAL_PORT_A;
1361 		case INTEL_PORT_B:
1362 			return INTEL_DIGITAL_PORT_B;
1363 		case INTEL_PORT_C:
1364 			return INTEL_DIGITAL_PORT_C;
1365 		default:
1366 			return 0;
1367 	}
1368 	return 0;
1369 }
1370 
1371 
1372 status_t
1373 DigitalPort::SetDisplayMode(display_mode* target, uint32 colorMode)
1374 {
1375 	CALLED();
1376 	TRACE("%s: %s %dx%d\n", __func__, PortName(), target->timing.h_display,
1377 		target->timing.v_display);
1378 
1379 	if (fPipe == NULL) {
1380 		ERROR("%s: Setting display mode without assigned pipe!\n", __func__);
1381 		return B_ERROR;
1382 	}
1383 
1384 	// Setup PanelFitter and Train FDI if it exists
1385 	PanelFitter* fitter = fPipe->PFT();
1386 	if (fitter != NULL)
1387 		fitter->Enable(target->timing);
1388 	FDILink* link = fPipe->FDI();
1389 	if (link != NULL) {
1390 		uint32 lanes = 0;
1391 		uint32 linkBandwidth = 0;
1392 		uint32 bitsPerPixel = 0;
1393 		link->PreTrain(&target->timing, &linkBandwidth, &lanes, &bitsPerPixel);
1394 		fPipe->SetFDILink(target->timing, linkBandwidth, lanes, bitsPerPixel);
1395 		link->Train(&target->timing, lanes);
1396 	}
1397 
1398 	pll_divisors divisors;
1399 	compute_pll_divisors(&target->timing, &divisors, false);
1400 
1401 	uint32 extraPLLFlags = 0;
1402 	if (gInfo->shared_info->device_type.Generation() >= 3)
1403 		extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL | DISPLAY_PLL_2X_CLOCK;
1404 
1405 	// Program general pipe config
1406 	fPipe->Configure(target);
1407 
1408 	// Program pipe PLL's
1409 	fPipe->ConfigureClocks(divisors, target->timing.pixel_clock, extraPLLFlags);
1410 
1411 	// Program target display mode
1412 	fPipe->ConfigureTimings(target);
1413 
1414 	// Set fCurrentMode to our set display mode
1415 	memcpy(&fCurrentMode, target, sizeof(display_mode));
1416 
1417 	return B_OK;
1418 }
1419 
1420 
1421 // #pragma mark - LVDS Panel
1422 // #pragma mark - HDMI
1423 
1424 
1425 HDMIPort::HDMIPort(port_index index)
1426 	:
1427 	DigitalPort(index, "HDMI")
1428 {
1429 }
1430 
1431 
1432 bool
1433 HDMIPort::IsConnected()
1434 {
1435 	if (!gInfo->shared_info->device_type.SupportsHDMI())
1436 		return false;
1437 
1438 	addr_t portRegister = _PortRegister();
1439 	TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(),
1440 		portRegister);
1441 
1442 	if (portRegister == 0)
1443 		return false;
1444 
1445 	const uint32 deviceConfigCount = gInfo->shared_info->device_config_count;
1446 	if (gInfo->shared_info->device_type.Generation() >= 6 && deviceConfigCount > 0) {
1447 		// check VBT mapping
1448 		if (!_IsPortInVBT()) {
1449 			TRACE("%s: %s: port not found in VBT\n", __func__, PortName());
1450 			return false;
1451 		} else
1452 			TRACE("%s: %s: port found in VBT\n", __func__, PortName());
1453 	}
1454 
1455 	//Notes:
1456 	//- DISPLAY_MONITOR_PORT_DETECTED does only tell you *some* sort of digital display is
1457 	//  connected to the port *if* you have the AUX channel stuff under power. It does not
1458 	//  tell you which -type- of digital display is connected.
1459 	//- Since we rely on the BIOS anyway, let's just use the conclusions it made for us :)
1460 	//  Beware though: set_display_power_mode() uses this DISPLAY_MONITOR_PORT_ENABLED bit
1461 	//  for DPMS as well. So we should better buffer our findings here for i.e. possible
1462 	//  accelerant clones starting up. For DPMS there's currently no problem as this bit
1463 	//  is only programmed for LVDS, DVI and VGA while we detect presence only for DP and HDMI.
1464 	//
1465 	//if ((read32(portRegister) & DISPLAY_MONITOR_PORT_DETECTED) == 0)
1466 	if ((read32(portRegister) & DISPLAY_MONITOR_PORT_ENABLED) == 0)
1467 		return false;
1468 
1469 	return HasEDID();
1470 }
1471 
1472 
1473 addr_t
1474 HDMIPort::_PortRegister()
1475 {
1476 	// on PCH there's an additional port sandwiched in
1477 	bool hasPCH = (gInfo->shared_info->pch_info != INTEL_PCH_NONE);
1478 	bool fourthGen = gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV);
1479 
1480 	switch (PortIndex()) {
1481 		case INTEL_PORT_B:
1482 			if (fourthGen)
1483 				return GEN4_HDMI_PORT_B;
1484 			return hasPCH ? PCH_HDMI_PORT_B : INTEL_HDMI_PORT_B;
1485 		case INTEL_PORT_C:
1486 			if (fourthGen)
1487 				return GEN4_HDMI_PORT_C;
1488 			return hasPCH ? PCH_HDMI_PORT_C : INTEL_HDMI_PORT_C;
1489 		case INTEL_PORT_D:
1490 			if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_CHV))
1491 				return CHV_HDMI_PORT_D;
1492 			return hasPCH ? PCH_HDMI_PORT_D : 0;
1493 		default:
1494 			return 0;
1495 		}
1496 
1497 	return 0;
1498 }
1499 
1500 
1501 // #pragma mark - DisplayPort
1502 
1503 
1504 DisplayPort::DisplayPort(port_index index, const char* baseName)
1505 	:
1506 	Port(index, baseName)
1507 {
1508 }
1509 
1510 
1511 pipe_index
1512 DisplayPort::PipePreference()
1513 {
1514 	CALLED();
1515 	if (gInfo->shared_info->device_type.Generation() <= 4)
1516 		return INTEL_PIPE_ANY;
1517 
1518 	// Notes:
1519 	// - The BIOSes seen sofar do not use PIPE C by default.
1520 	// - Looks like BIOS selected Transcoder (A,B,C) is not always same as selected Pipe (A,B,C)
1521 	//   so these should probably be handled seperately. For now this is OK as we don't touch
1522 	//   the pipe for DisplayPort, only the transcoder..
1523 	uint32 TranscoderPort = INTEL_TRANS_DP_PORT_NONE;
1524 	switch (PortIndex()) {
1525 		case INTEL_PORT_A:
1526 			if (gInfo->shared_info->device_type.Generation() == 6) {
1527 				if (((read32(INTEL_DISPLAY_PORT_A) & INTEL_DISP_PORTA_SNB_PIPE_MASK)
1528 					>> INTEL_DISP_PORTA_SNB_PIPE_SHIFT) == INTEL_DISP_PORTA_SNB_PIPE_A) {
1529 					return INTEL_PIPE_A;
1530 				} else {
1531 					return INTEL_PIPE_B;
1532 				}
1533 			}
1534 			if (gInfo->shared_info->device_type.Generation() == 7) {
1535 				uint32 Pipe = (read32(INTEL_DISPLAY_PORT_A) & INTEL_DISP_PORTA_IVB_PIPE_MASK)
1536 					>> INTEL_DISP_PORTA_IVB_PIPE_SHIFT;
1537 				switch (Pipe) {
1538 					case INTEL_DISP_PORTA_IVB_PIPE_A:
1539 						return INTEL_PIPE_A;
1540 					case INTEL_DISP_PORTA_IVB_PIPE_B:
1541 						return INTEL_PIPE_B;
1542 					case INTEL_DISP_PORTA_IVB_PIPE_C:
1543 						return INTEL_PIPE_C;
1544 					default:
1545 						return INTEL_PIPE_ANY;
1546 				}
1547 			}
1548 			return INTEL_PIPE_ANY;
1549 		case INTEL_PORT_B:
1550 			TranscoderPort = INTEL_TRANS_DP_PORT_B;
1551 			break;
1552 		case INTEL_PORT_C:
1553 			TranscoderPort = INTEL_TRANS_DP_PORT_C;
1554 			break;
1555 		case INTEL_PORT_D:
1556 			TranscoderPort = INTEL_TRANS_DP_PORT_D;
1557 			break;
1558 		default:
1559 			return INTEL_PIPE_ANY;
1560 	}
1561 
1562 	for (uint32 Transcoder = 0; Transcoder < 3; Transcoder++) {
1563 		if ((read32(INTEL_TRANSCODER_A_DP_CTL + (Transcoder << 12)) & INTEL_TRANS_DP_PORT_MASK) ==
1564 			INTEL_TRANS_DP_PORT(TranscoderPort)) {
1565 			switch (Transcoder) {
1566 				case 0:
1567 					return INTEL_PIPE_A;
1568 				case 1:
1569 					return INTEL_PIPE_B;
1570 				case 2:
1571 					return INTEL_PIPE_C;
1572 			}
1573 		}
1574 	}
1575 
1576 	return INTEL_PIPE_ANY;
1577 }
1578 
1579 
1580 status_t
1581 DisplayPort::SetPipe(Pipe* pipe)
1582 {
1583 	CALLED();
1584 
1585 	if (pipe == NULL) {
1586 		ERROR("%s: Invalid pipe provided!\n", __func__);
1587 		return B_ERROR;
1588 	}
1589 
1590 	// TODO: UnAssignPipe?  This likely needs reworked a little
1591 	if (fPipe != NULL) {
1592 		ERROR("%s: Can't reassign display pipe (yet)\n", __func__);
1593 		return B_ERROR;
1594 	}
1595 
1596 	// generation 3/4/5 gfx have no eDP ports.
1597 	// generation 6 gfx SandyBridge/SNB uses one bit (b30) on the eDP port.
1598 	// generation 7 gfx IvyBridge/IVB uses 2 bits (b29-30) on the eDP port.
1599 	// on all other DP ports pipe selections works differently (indirect).
1600 	// fixme: implement..
1601 	TRACE("%s: Assuming pipe is assigned by BIOS (fixme)\n", __func__);
1602 
1603 	fPipe = pipe;
1604 
1605 	if (fPipe == NULL)
1606 		return B_NO_MEMORY;
1607 
1608 	// Disable display pipe until modesetting enables it
1609 	if (fPipe->IsEnabled())
1610 		fPipe->Enable(false);
1611 
1612 	return B_OK;
1613 }
1614 
1615 
1616 status_t
1617 DisplayPort::SetupI2c(i2c_bus *bus)
1618 {
1619 	CALLED();
1620 
1621 	const uint32 deviceConfigCount = gInfo->shared_info->device_config_count;
1622 	if (gInfo->shared_info->device_type.Generation() >= 6 && deviceConfigCount > 0) {
1623 		if (!_IsDisplayPortInVBT())
1624 			return Port::SetupI2c(bus);
1625 	}
1626 
1627 	return _SetupDpAuxI2c(bus);
1628 }
1629 
1630 
1631 bool
1632 DisplayPort::IsConnected()
1633 {
1634 	addr_t portRegister = _PortRegister();
1635 
1636 	TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(),
1637 		portRegister);
1638 
1639 	if (portRegister == 0)
1640 		return false;
1641 
1642 	const uint32 deviceConfigCount = gInfo->shared_info->device_config_count;
1643 	if (gInfo->shared_info->device_type.Generation() >= 6 && deviceConfigCount > 0) {
1644 		// check VBT mapping
1645 		if (!_IsPortInVBT()) {
1646 			TRACE("%s: %s: port not found in VBT\n", __func__, PortName());
1647 			return false;
1648 		} else
1649 			TRACE("%s: %s: port found in VBT\n", __func__, PortName());
1650 	}
1651 
1652 	//Notes:
1653 	//- DISPLAY_MONITOR_PORT_DETECTED does only tell you *some* sort of digital display is
1654 	//  connected to the port *if* you have the AUX channel stuff under power. It does not
1655 	//  tell you which -type- of digital display is connected.
1656 	//- Since we rely on the BIOS anyway, let's just use the conclusions it made for us :)
1657 	//  Beware though: set_display_power_mode() uses this DISPLAY_MONITOR_PORT_ENABLED bit
1658 	//  for DPMS as well. So we should better buffer our findings here for i.e. possible
1659 	//  accelerant clones starting up. For DPMS there's currently no problem as this bit
1660 	//  is only programmed for LVDS, DVI and VGA while we detect presence only for DP and HDMI.
1661 	//
1662 	//if ((read32(portRegister) & DISPLAY_MONITOR_PORT_DETECTED) == 0) {
1663 	if ((read32(portRegister) & DISPLAY_MONITOR_PORT_ENABLED) == 0) {
1664 		TRACE("%s: %s link not detected\n", __func__, PortName());
1665 		return false;
1666 	}
1667 
1668 	TRACE("%s: %s link detected\n", __func__, PortName());
1669 	bool edidDetected = HasEDID();
1670 
1671 	// On laptops we always have an internal panel.. (this is on the eDP port)
1672 	if ((gInfo->shared_info->device_type.IsMobile() || _IsEDPPort())
1673 		&& (PortIndex() == INTEL_PORT_A) && !edidDetected) {
1674 		if (gInfo->shared_info->has_vesa_edid_info) {
1675 			TRACE("%s: Laptop. Using VESA edid info\n", __func__);
1676 			memcpy(&fEDIDInfo, &gInfo->shared_info->vesa_edid_info,
1677 				sizeof(edid1_info));
1678 			if (fEDIDState != B_OK) {
1679 				fEDIDState = B_OK;
1680 				// HasEDID now true
1681 				edid_dump(&fEDIDInfo);
1682 			}
1683 			return true;
1684 		} else if (gInfo->shared_info->got_vbt) {
1685 			TRACE("%s: Laptop. No EDID, but force enabled as we have a VBT\n", __func__);
1686 			return true;
1687 		}
1688 	}
1689 
1690 	//since EDID is not correctly implemented yet for this connection type we'll do without it for now
1691 	//return HasEDID();
1692 	return true;
1693 }
1694 
1695 
1696 addr_t
1697 DisplayPort::_DDCRegister()
1698 {
1699 	return 0;
1700 }
1701 
1702 
1703 addr_t
1704 DisplayPort::_PortRegister()
1705 {
1706 	// There are 6000 lines of intel linux code probing DP registers
1707 	// to properly detect DP vs eDP to then in-turn properly figure out
1708 	// what is DP and what is HDMI. It only takes 3 lines to
1709 	// ignore DisplayPort on ValleyView / CherryView
1710 
1711 	if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV)
1712 		|| gInfo->shared_info->device_type.InGroup(INTEL_GROUP_CHV)) {
1713 		ERROR("TODO: DisplayPort on ValleyView / CherryView");
1714 		return 0;
1715 	}
1716 
1717 	// Intel, are humans even involved anymore?
1718 	// This is a lot more complex than this code makes it look. (see defines)
1719 	// INTEL_DISPLAY_PORT_X moves around a lot based on PCH
1720 	// except on ValleyView and CherryView.
1721 	switch (PortIndex()) {
1722 		case INTEL_PORT_A:
1723 			return INTEL_DISPLAY_PORT_A;
1724 		case INTEL_PORT_B:
1725 			if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV))
1726 				return VLV_DISPLAY_PORT_B;
1727 			return INTEL_DISPLAY_PORT_B;
1728 		case INTEL_PORT_C:
1729 			if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV))
1730 				return VLV_DISPLAY_PORT_C;
1731 			return INTEL_DISPLAY_PORT_C;
1732 		case INTEL_PORT_D:
1733 			if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_CHV))
1734 				return CHV_DISPLAY_PORT_D;
1735 			else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV))
1736 				return 0;
1737 			return INTEL_DISPLAY_PORT_D;
1738 		default:
1739 			return 0;
1740 	}
1741 
1742 	return 0;
1743 }
1744 
1745 
1746 status_t
1747 DisplayPort::_SetPortLinkGen4(const display_timing& timing)
1748 {
1749 	// Khz / 10. ( each output octet encoded as 10 bits.
1750 	//fixme: always so?
1751 	uint32 linkBandwidth = 270000; //khz
1752 	uint32 fPipeOffset = 0;
1753 	if (fPipe->Index() == INTEL_PIPE_B)
1754 		fPipeOffset = 0x1000;
1755 
1756 	TRACE("%s: DP M1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_DATA_M + fPipeOffset));
1757 	TRACE("%s: DP N1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_DATA_N + fPipeOffset));
1758 	TRACE("%s: DP M1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_LINK_M + fPipeOffset));
1759 	TRACE("%s: DP N1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_LINK_N + fPipeOffset));
1760 
1761 	uint32 bitsPerPixel = 24;	//fixme: always so?
1762 	uint32 lanes = 4;			//fixme: always so?
1763 
1764 	//Setup Data M/N
1765 	uint64 linkspeed = lanes * linkBandwidth * 8;
1766 	uint64 ret_n = 1;
1767 	while(ret_n < linkspeed) {
1768 		ret_n *= 2;
1769 	}
1770 	if (ret_n > 0x800000) {
1771 		ret_n = 0x800000;
1772 	}
1773 	uint64 ret_m = timing.pixel_clock * ret_n * bitsPerPixel / linkspeed;
1774 	while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) {
1775 		ret_m >>= 1;
1776 		ret_n >>= 1;
1777 	}
1778 	//Set TU size bits (to default, max) before link training so that error detection works
1779 	write32(INTEL_PIPE_A_DATA_M + fPipeOffset, ret_m | FDI_PIPE_MN_TU_SIZE_MASK);
1780 	write32(INTEL_PIPE_A_DATA_N + fPipeOffset, ret_n);
1781 
1782 	//Setup Link M/N
1783 	linkspeed = linkBandwidth;
1784 	ret_n = 1;
1785 	while(ret_n < linkspeed) {
1786 		ret_n *= 2;
1787 	}
1788 	if (ret_n > 0x800000) {
1789 		ret_n = 0x800000;
1790 	}
1791 	ret_m = timing.pixel_clock * ret_n / linkspeed;
1792 	while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) {
1793 		ret_m >>= 1;
1794 		ret_n >>= 1;
1795 	}
1796 	write32(INTEL_PIPE_A_LINK_M + fPipeOffset, ret_m);
1797 	//Writing Link N triggers all four registers to be activated also (on next VBlank)
1798 	write32(INTEL_PIPE_A_LINK_N + fPipeOffset, ret_n);
1799 
1800 	TRACE("%s: DP M1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_DATA_M + fPipeOffset));
1801 	TRACE("%s: DP N1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_DATA_N + fPipeOffset));
1802 	TRACE("%s: DP M1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_LINK_M + fPipeOffset));
1803 	TRACE("%s: DP N1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_PIPE_A_LINK_N + fPipeOffset));
1804 
1805 	return B_OK;
1806 }
1807 
1808 
1809 status_t
1810 DisplayPort::_SetPortLinkGen6(const display_timing& timing)
1811 {
1812 	// Khz / 10. ( each output octet encoded as 10 bits.
1813 	//note: (fixme) eDP is fixed option 162 or 270Mc, other DPs go via DPLL programming to one of the same vals.
1814 	uint32 linkBandwidth = 270000; //khz
1815 	TRACE("%s: DP link reference clock is %gMhz\n", __func__, linkBandwidth / 1000.0f);
1816 
1817 	uint32 fPipeOffset = 0;
1818 	switch (fPipe->Index()) {
1819 		case INTEL_PIPE_B:
1820 			fPipeOffset = 0x1000;
1821 			break;
1822 		case INTEL_PIPE_C:
1823 			fPipeOffset = 0x2000;
1824 			break;
1825 		default:
1826 			break;
1827 	}
1828 
1829 	TRACE("%s: DP M1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_DATA_M1 + fPipeOffset));
1830 	TRACE("%s: DP N1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_DATA_N1 + fPipeOffset));
1831 	TRACE("%s: DP M1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_LINK_M1 + fPipeOffset));
1832 	TRACE("%s: DP N1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_LINK_N1 + fPipeOffset));
1833 
1834 	uint32 bitsPerPixel =
1835 		(read32(INTEL_TRANSCODER_A_DP_CTL + fPipeOffset) & INTEL_TRANS_DP_BPC_MASK) >> INTEL_TRANS_DP_COLOR_SHIFT;
1836 	switch (bitsPerPixel) {
1837 		case PIPE_DDI_8BPC:
1838 			bitsPerPixel = 24;
1839 			break;
1840 		case PIPE_DDI_10BPC:
1841 			bitsPerPixel = 30;
1842 			break;
1843 		case PIPE_DDI_6BPC:
1844 			bitsPerPixel = 18;
1845 			break;
1846 		case PIPE_DDI_12BPC:
1847 			bitsPerPixel = 36;
1848 			break;
1849 		default:
1850 			ERROR("%s: DP illegal link colordepth set.\n", __func__);
1851 			return B_ERROR;
1852 	}
1853 	TRACE("%s: DP link colordepth: %" B_PRIu32 "\n", __func__, bitsPerPixel);
1854 
1855 	uint32 lanes = ((read32(_PortRegister()) & INTEL_DISP_PORT_WIDTH_MASK) >> INTEL_DISP_PORT_WIDTH_SHIFT) + 1;
1856 	if (lanes > 4) {
1857 		ERROR("%s: DP illegal number of lanes set.\n", __func__);
1858 		return B_ERROR;
1859 	}
1860 	TRACE("%s: DP mode with %" B_PRIx32 " lane(s) in use\n", __func__, lanes);
1861 
1862 	//Reserving 5% bandwidth for possible spread spectrum clock use
1863 	uint32 bps = timing.pixel_clock * bitsPerPixel * 21 / 20;
1864 	//use DIV_ROUND_UP:
1865 	uint32 required_lanes = (bps + (linkBandwidth * 8) - 1) / (linkBandwidth * 8);
1866 	TRACE("%s: DP mode needs %" B_PRIx32 " lane(s) in use\n", __func__, required_lanes);
1867 	if (required_lanes > lanes) {
1868 		//Note that we *must* abort as otherwise the PIPE/DP-link hangs forever (without retraining!).
1869 		ERROR("%s: DP not enough lanes active for requested mode.\n", __func__);
1870 		return B_ERROR;
1871 	}
1872 
1873 	//Setup Data M/N
1874 	uint64 linkspeed = lanes * linkBandwidth * 8;
1875 	uint64 ret_n = 1;
1876 	while(ret_n < linkspeed) {
1877 		ret_n *= 2;
1878 	}
1879 	if (ret_n > 0x800000) {
1880 		ret_n = 0x800000;
1881 	}
1882 	uint64 ret_m = timing.pixel_clock * ret_n * bitsPerPixel / linkspeed;
1883 	while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) {
1884 		ret_m >>= 1;
1885 		ret_n >>= 1;
1886 	}
1887 	//Set TU size bits (to default, max) before link training so that error detection works
1888 	write32(INTEL_TRANSCODER_A_DATA_M1 + fPipeOffset, ret_m | INTEL_TRANSCODER_MN_TU_SIZE_MASK);
1889 	write32(INTEL_TRANSCODER_A_DATA_N1 + fPipeOffset, ret_n);
1890 
1891 	//Setup Link M/N
1892 	linkspeed = linkBandwidth;
1893 	ret_n = 1;
1894 	while(ret_n < linkspeed) {
1895 		ret_n *= 2;
1896 	}
1897 	if (ret_n > 0x800000) {
1898 		ret_n = 0x800000;
1899 	}
1900 	ret_m = timing.pixel_clock * ret_n / linkspeed;
1901 	while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) {
1902 		ret_m >>= 1;
1903 		ret_n >>= 1;
1904 	}
1905 	write32(INTEL_TRANSCODER_A_LINK_M1 + fPipeOffset, ret_m);
1906 	//Writing Link N triggers all four registers to be activated also (on next VBlank)
1907 	write32(INTEL_TRANSCODER_A_LINK_N1 + fPipeOffset, ret_n);
1908 
1909 	TRACE("%s: DP M1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_DATA_M1 + fPipeOffset));
1910 	TRACE("%s: DP N1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_DATA_N1 + fPipeOffset));
1911 	TRACE("%s: DP M1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_LINK_M1 + fPipeOffset));
1912 	TRACE("%s: DP N1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_TRANSCODER_A_LINK_N1 + fPipeOffset));
1913 
1914 	return B_OK;
1915 }
1916 
1917 
1918 status_t
1919 DisplayPort::SetDisplayMode(display_mode* target, uint32 colorMode)
1920 {
1921 	CALLED();
1922 	TRACE("%s: %s %dx%d\n", __func__, PortName(), target->timing.h_display,
1923 		target->timing.v_display);
1924 
1925 	if (fPipe == NULL) {
1926 		ERROR("%s: Setting display mode without assigned pipe!\n", __func__);
1927 		return B_ERROR;
1928 	}
1929 
1930 	status_t result = B_OK;
1931 	if (gInfo->shared_info->device_type.Generation() <= 4) {
1932 		fPipe->ConfigureTimings(target);
1933 		result = _SetPortLinkGen4(target->timing);
1934 	} else {
1935 		display_timing hardwareTarget = target->timing;
1936 		bool needsScaling = false;
1937 		if ((PortIndex() == INTEL_PORT_A)
1938 			&& (gInfo->shared_info->device_type.IsMobile() || _IsEDPPort())) {
1939 			// For internal panels, we may need to set the timings according to the panel
1940 			// native video mode, and let the panel fitter do the scaling.
1941 			// note: upto/including generation 5 laptop panels are still LVDS types, handled elsewhere.
1942 
1943 			if (gInfo->shared_info->got_vbt) {
1944 				// Set vbios hardware panel mode as base
1945 				hardwareTarget = gInfo->shared_info->panel_timing;
1946 
1947 				if (hardwareTarget.h_display == target->timing.h_display
1948 						&& hardwareTarget.v_display == target->timing.v_display) {
1949 					// We are feeding the native video mode, nothing to do: disable scaling
1950 					TRACE("%s: Requested mode is panel's native resolution: disabling scaling\n", __func__);
1951 				} else {
1952 					// We need to enable the panel fitter
1953 					TRACE("%s: Requested mode is not panel's native resolution: enabling scaling\n", __func__);
1954 					needsScaling = true;
1955 				}
1956 			} else {
1957 				//fixme: We should now first try for EDID info detailed timing, highest res in list: that's the
1958 				//native mode as well. If we also have no EDID, then fallback to setting mode directly as below.
1959 
1960 				TRACE("%s: Setting internal panel mode without VBT info generation, scaling may not work\n",
1961 					__func__);
1962 				// We don't have VBT data, try to set the requested mode directly
1963 				// and hope for the best
1964 				hardwareTarget = target->timing;
1965 			}
1966 		}
1967 
1968 		result = B_OK;
1969 		if (PortIndex() != INTEL_PORT_A)
1970 			result = _SetPortLinkGen6(hardwareTarget);
1971 
1972 		if (result == B_OK) {
1973 			// Setup PanelFitter and Train FDI if it exists
1974 			PanelFitter* fitter = fPipe->PFT();
1975 			if (fitter != NULL)
1976 				fitter->Enable(hardwareTarget);
1977 
1978 			uint32 lanes = 0;
1979 			uint32 linkBandwidth = 0;
1980 			uint32 bitsPerPixel = 0;
1981 			if (PortIndex() != INTEL_PORT_A) {
1982 				FDILink* link = fPipe->FDI();
1983 				if (link != NULL) {
1984 					link->PreTrain(&hardwareTarget, &linkBandwidth, &lanes, &bitsPerPixel);
1985 					fPipe->SetFDILink(hardwareTarget, linkBandwidth, lanes, bitsPerPixel);
1986 					link->Train(&hardwareTarget, lanes);
1987 				}
1988 			} else {
1989 				// 'local' eDP port is in use
1990 				linkBandwidth =
1991 					(read32(INTEL_DISPLAY_PORT_A) & INTEL_DISP_EDP_PLL_FREQ_MASK) >> INTEL_DISP_EDP_PLL_FREQ_SHIFT;
1992 				switch (linkBandwidth) {
1993 					case INTEL_DISP_EDP_PLL_FREQ_270:
1994 						linkBandwidth = 270000; //khz
1995 						break;
1996 					case INTEL_DISP_EDP_PLL_FREQ_162:
1997 						linkBandwidth = 162000; //khz
1998 						break;
1999 					default:
2000 						TRACE("%s: eDP illegal reference clock ID set, assuming 270Mhz.\n", __func__);
2001 						linkBandwidth = 270000; //khz
2002 				}
2003 
2004 				bitsPerPixel =
2005 					(read32(INTEL_DISPLAY_A_PIPE_CONTROL) & INTEL_PIPE_BPC_MASK) >> INTEL_PIPE_COLOR_SHIFT;
2006 				switch (bitsPerPixel) {
2007 					case INTEL_PIPE_8BPC:
2008 						bitsPerPixel = 24;
2009 						break;
2010 					case INTEL_PIPE_10BPC:
2011 						bitsPerPixel = 30;
2012 						break;
2013 					case INTEL_PIPE_6BPC:
2014 						bitsPerPixel = 18;
2015 						break;
2016 					case INTEL_PIPE_12BPC:
2017 						bitsPerPixel = 36;
2018 						break;
2019 					default:
2020 						bitsPerPixel = 0;
2021 				}
2022 
2023 				lanes =
2024 					((read32(INTEL_DISPLAY_PORT_A) & INTEL_DISP_PORT_WIDTH_MASK) >> INTEL_DISP_PORT_WIDTH_SHIFT) + 1;
2025 
2026 				fPipe->SetFDILink(hardwareTarget, linkBandwidth, lanes, bitsPerPixel);
2027 			}
2028 
2029 			// Program general pipe config
2030 			fPipe->Configure(target);
2031 
2032 			// Pll programming is not needed for (e)DP..
2033 
2034 			// Program target display mode
2035 			fPipe->ConfigureTimings(target, !needsScaling, PortIndex());
2036 		} else {
2037 			TRACE("%s: Setting display mode via fallback: using scaling!\n", __func__);
2038 			// Keep monitor at native mode and scale image to that
2039 			fPipe->ConfigureScalePos(target);
2040 		}
2041 	}
2042 
2043 	// Set fCurrentMode to our set display mode
2044 	memcpy(&fCurrentMode, target, sizeof(display_mode));
2045 
2046 	return result;
2047 }
2048 
2049 
2050 // #pragma mark - Embedded DisplayPort
2051 
2052 
2053 EmbeddedDisplayPort::EmbeddedDisplayPort()
2054 	:
2055 	DisplayPort(INTEL_PORT_A, "Embedded DisplayPort")
2056 {
2057 }
2058 
2059 
2060 bool
2061 EmbeddedDisplayPort::IsConnected()
2062 {
2063 	addr_t portRegister = _PortRegister();
2064 
2065 	TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(),
2066 		portRegister);
2067 
2068 	if (!gInfo->shared_info->device_type.IsMobile()) {
2069 		TRACE("%s: skipping eDP on non-mobile GPU\n", __func__);
2070 		return false;
2071 	}
2072 
2073 	if ((read32(portRegister) & DISPLAY_MONITOR_PORT_DETECTED) == 0) {
2074 		TRACE("%s: %s link not detected\n", __func__, PortName());
2075 		return false;
2076 	}
2077 
2078 	HasEDID();
2079 
2080 	// If eDP has EDID, awesome. We use it.
2081 	// No EDID? The modesetting code falls back to VBIOS panel_mode
2082 	return true;
2083 }
2084 
2085 
2086 // #pragma mark - Digital Display Port
2087 
2088 
2089 DigitalDisplayInterface::DigitalDisplayInterface(port_index index,
2090 		const char* baseName)
2091 	:
2092 	Port(index, baseName)
2093 {
2094 	// As of Haswell, Intel decided to change eDP ports to a "DDI" bus...
2095 	// on a dare because the hardware engineers were drunk one night.
2096 }
2097 
2098 
2099 addr_t
2100 DigitalDisplayInterface::_PortRegister()
2101 {
2102 	// TODO: Linux does a DDI_BUF_CTL(INTEL_PORT_A) which is cleaner
2103 	// (but we have to ensure the offsets + region base is correct)
2104 	switch (PortIndex()) {
2105 		case INTEL_PORT_A:
2106 			return DDI_BUF_CTL_A;
2107 		case INTEL_PORT_B:
2108 			return DDI_BUF_CTL_B;
2109 		case INTEL_PORT_C:
2110 			return DDI_BUF_CTL_C;
2111 		case INTEL_PORT_D:
2112 			return DDI_BUF_CTL_D;
2113 		case INTEL_PORT_E:
2114 			return DDI_BUF_CTL_E;
2115 		case INTEL_PORT_F:
2116 			if ((gInfo->shared_info->device_type.Generation() > 8) &&
2117 				!gInfo->shared_info->device_type.InGroup(INTEL_GROUP_SKY))
2118 				return DDI_BUF_CTL_F;
2119 			return 0;
2120 		default:
2121 			return 0;
2122 	}
2123 	return 0;
2124 }
2125 
2126 
2127 addr_t
2128 DigitalDisplayInterface::_DDCRegister()
2129 {
2130 	switch (PortIndex()) {
2131 		case INTEL_PORT_B:
2132 			return INTEL_I2C_IO_E;
2133 		case INTEL_PORT_C:
2134 			return INTEL_I2C_IO_D;
2135 		case INTEL_PORT_D:
2136 			return INTEL_I2C_IO_F;
2137 		default:
2138 			return 0;
2139 	}
2140 
2141 	return 0;
2142 }
2143 
2144 
2145 status_t
2146 DigitalDisplayInterface::Power(bool enabled)
2147 {
2148 	if (fPipe == NULL) {
2149 		ERROR("%s: Setting power without assigned pipe!\n", __func__);
2150 		return B_ERROR;
2151 	}
2152 	TRACE("%s: %s DDI enabled: %s\n", __func__, PortName(),
2153 		enabled ? "true" : "false");
2154 
2155 	fPipe->Enable(enabled);
2156 
2157 	//nogo currently.. (kills output forever)
2158 #if 0
2159 	addr_t portRegister = _PortRegister();
2160 	uint32 state = read32(portRegister);
2161 	write32(portRegister,
2162 		enabled ? (state | DDI_BUF_CTL_ENABLE) : (state & ~DDI_BUF_CTL_ENABLE));
2163 	read32(portRegister);
2164 #endif
2165 
2166 	return B_OK;
2167 }
2168 
2169 
2170 status_t
2171 DigitalDisplayInterface::SetPipe(Pipe* pipe)
2172 {
2173 	CALLED();
2174 
2175 	if (pipe == NULL) {
2176 		ERROR("%s: Invalid pipe provided!\n", __func__);
2177 		return B_ERROR;
2178 	}
2179 
2180 	// TODO: UnAssignPipe?  This likely needs reworked a little
2181 	if (fPipe != NULL) {
2182 		ERROR("%s: Can't reassign display pipe (yet)\n", __func__);
2183 		return B_ERROR;
2184 	}
2185 
2186 	// all DDI ports pipe selections works differently than on the old port types (indirect).
2187 	// fixme: implement..
2188 	TRACE("%s: Assuming pipe is assigned by BIOS (fixme)\n", __func__);
2189 
2190 	fPipe = pipe;
2191 
2192 	if (fPipe == NULL)
2193 		return B_NO_MEMORY;
2194 
2195 	// Disable display pipe until modesetting enables it
2196 	if (fPipe->IsEnabled())
2197 		fPipe->Enable(false);
2198 
2199 	return B_OK;
2200 }
2201 
2202 
2203 status_t
2204 DigitalDisplayInterface::SetupI2c(i2c_bus *bus)
2205 {
2206 	CALLED();
2207 
2208 	const uint32 deviceConfigCount = gInfo->shared_info->device_config_count;
2209 	if (gInfo->shared_info->device_type.Generation() >= 6 && deviceConfigCount > 0) {
2210 		if (!_IsDisplayPortInVBT())
2211 			return Port::SetupI2c(bus);
2212 	}
2213 
2214 	return _SetupDpAuxI2c(bus);
2215 }
2216 
2217 
2218 status_t
2219 DigitalDisplayInterface::SetupI2cFallback(i2c_bus *bus)
2220 {
2221 	CALLED();
2222 
2223 	const uint32 deviceConfigCount = gInfo->shared_info->device_config_count;
2224 	if (gInfo->shared_info->device_type.Generation() >= 6 && deviceConfigCount > 0
2225 		&& _IsDisplayPortInVBT() && _IsHdmiInVBT()) {
2226 		return Port::SetupI2c(bus);
2227 	}
2228 
2229 	return B_ERROR;
2230 }
2231 
2232 
2233 bool
2234 DigitalDisplayInterface::IsConnected()
2235 {
2236 	addr_t portRegister = _PortRegister();
2237 
2238 	TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(),
2239 		portRegister);
2240 
2241 	// Please note: Skylake and up (Desktop) might use eDP for a seperate active VGA converter chip.
2242 	if (portRegister == 0) {
2243 		TRACE("%s: Port not implemented\n", __func__);
2244 		return false;
2245 	}
2246 
2247 	// newer chipsets support 4 lanes on all ports
2248 	fMaxLanes = 4;
2249 	if ((gInfo->shared_info->device_type.Generation() < 9) ||
2250 		gInfo->shared_info->device_type.InGroup(INTEL_GROUP_SKY)) {
2251 		// Probe a little port info.
2252 		if ((read32(DDI_BUF_CTL_A) & DDI_A_4_LANES) != 0) {
2253 			switch (PortIndex()) {
2254 				case INTEL_PORT_A:
2255 					fMaxLanes = 4;
2256 					break;
2257 				case INTEL_PORT_E:
2258 					fMaxLanes = 0;
2259 					break;
2260 				default:
2261 					fMaxLanes = 4;
2262 					break;
2263 			}
2264 		} else {
2265 			switch (PortIndex()) {
2266 				case INTEL_PORT_A:
2267 					fMaxLanes = 2;
2268 					break;
2269 				case INTEL_PORT_E:
2270 					fMaxLanes = 2;
2271 					break;
2272 				default:
2273 					fMaxLanes = 4;
2274 					break;
2275 			}
2276 		}
2277 	}
2278 
2279 	const uint32 deviceConfigCount = gInfo->shared_info->device_config_count;
2280 	if (gInfo->shared_info->device_type.Generation() >= 6 && deviceConfigCount > 0) {
2281 		// check VBT mapping
2282 		if (!_IsPortInVBT()) {
2283 			TRACE("%s: %s: port not found in VBT\n", __func__, PortName());
2284 			return false;
2285 		} else
2286 			TRACE("%s: %s: port found in VBT\n", __func__, PortName());
2287 	}
2288 
2289 	TRACE("%s: %s Maximum Lanes: %" B_PRId8 "\n", __func__,
2290 		PortName(), fMaxLanes);
2291 
2292 	// fetch EDID but determine 'in use' later (below) so we also catch screens that fail EDID
2293 	bool edidDetected = HasEDID();
2294 
2295 	// On laptops we always have an internal panel.. (on the eDP port on DDI systems, fixed on eDP pipe)
2296 	uint32 pipeState = 0;
2297 	if ((gInfo->shared_info->device_type.IsMobile() || _IsEDPPort())
2298 		&& (PortIndex() == INTEL_PORT_A)) {
2299 		if (gInfo->shared_info->device_type.Generation() < 12) {
2300 			// TODO: the pipe state isn't reliable after gen11
2301 			pipeState = read32(PIPE_DDI_FUNC_CTL_EDP);
2302 			TRACE("%s: PIPE_DDI_FUNC_CTL_EDP: 0x%" B_PRIx32 "\n", __func__, pipeState);
2303 			if (!(pipeState & PIPE_DDI_FUNC_CTL_ENABLE)) {
2304 				TRACE("%s: Laptop, but eDP port down\n", __func__);
2305 				return false;
2306 			}
2307 		}
2308 		if (edidDetected)
2309 			return true;
2310 		else if (gInfo->shared_info->has_vesa_edid_info) {
2311 			TRACE("%s: Laptop. Using VESA edid info\n", __func__);
2312 			memcpy(&fEDIDInfo, &gInfo->shared_info->vesa_edid_info,	sizeof(edid1_info));
2313 			if (fEDIDState != B_OK) {
2314 				fEDIDState = B_OK;
2315 				// HasEDID now true
2316 				edid_dump(&fEDIDInfo);
2317 			}
2318 			return true;
2319 		} else if (gInfo->shared_info->got_vbt) {
2320 			TRACE("%s: Laptop. No VESA EDID, but force enabled as we have a VBT\n", __func__);
2321 			return true;
2322 		}
2323 		//should not happen:
2324 		TRACE("%s: No (panel) type info found, assuming not connected\n", __func__);
2325 		return false;
2326 	}
2327 
2328 	// scan all our non-eDP pipes to find the one connected to the current port and check it's enabled
2329 	for (uint32 pipeCnt = 0; pipeCnt < 3; pipeCnt++) {
2330 		switch (pipeCnt) {
2331 			case 1:
2332 				pipeState = read32(PIPE_DDI_FUNC_CTL_B);
2333 				break;
2334 			case 2:
2335 				pipeState = read32(PIPE_DDI_FUNC_CTL_C);
2336 				break;
2337 			default:
2338 				pipeState = read32(PIPE_DDI_FUNC_CTL_A);
2339 				break;
2340 		}
2341 		if ((((pipeState & PIPE_DDI_SELECT_MASK) >> PIPE_DDI_SELECT_SHIFT) + 1) == (uint32)PortIndex()) {
2342 			TRACE("%s: PIPE_DDI_FUNC_CTL nr %" B_PRIx32 ": 0x%" B_PRIx32 "\n", __func__, pipeCnt + 1, pipeState);
2343 			// See if the BIOS enabled our output as it indicates it's in use
2344 			if (pipeState & PIPE_DDI_FUNC_CTL_ENABLE) {
2345 				TRACE("%s: Connected\n", __func__);
2346 				return true;
2347 			}
2348 		}
2349 	}
2350 
2351 	if (edidDetected) {
2352 		for (uint32 pipeCnt = 0; pipeCnt < 3; pipeCnt++) {
2353 			uint32 pipeReg = 0;
2354 			switch (pipeCnt) {
2355 				case 1:
2356 					pipeReg = PIPE_DDI_FUNC_CTL_B;
2357 					break;
2358 				case 2:
2359 					pipeReg = PIPE_DDI_FUNC_CTL_C;
2360 					break;
2361 				default:
2362 					pipeReg = PIPE_DDI_FUNC_CTL_A;
2363 					break;
2364 			}
2365 			pipeState = read32(pipeReg);
2366 			if ((pipeState & PIPE_DDI_FUNC_CTL_ENABLE) == 0) {
2367 				TRACE("%s: Connected but port down\n", __func__);
2368 				return false;
2369 			}
2370 			return true;
2371 		}
2372 		TRACE("%s: No pipe available, ignoring connected screen\n", __func__);
2373 	}
2374 
2375 	TRACE("%s: Not connected\n", __func__);
2376 	return false;
2377 }
2378 
2379 status_t
2380 DigitalDisplayInterface::_SetPortLinkGen8(const display_timing& timing, uint32 pllSel)
2381 {
2382 	//fixme: always so on pre gen 9?
2383 	uint32 linkBandwidth = 270000; //khz
2384 
2385 	if (gInfo->shared_info->device_type.Generation() >= 9) {
2386 		if (pllSel != 0xff) {
2387 			linkBandwidth = (read32(SKL_DPLL_CTRL1) >> (1 + 6 * pllSel)) & SKL_DPLL_DP_LINKRATE_MASK;
2388 			switch (linkBandwidth) {
2389 				case SKL_DPLL_CTRL1_2700:
2390 					linkBandwidth = 2700000 / 5;
2391 					break;
2392 				case SKL_DPLL_CTRL1_1350:
2393 					linkBandwidth = 1350000 / 5;
2394 					break;
2395 				case SKL_DPLL_CTRL1_810:
2396 					linkBandwidth =  810000 / 5;
2397 					break;
2398 				case SKL_DPLL_CTRL1_1620:
2399 					linkBandwidth = 1620000 / 5;
2400 					break;
2401 				case SKL_DPLL_CTRL1_1080:
2402 					linkBandwidth = 1080000 / 5;
2403 					break;
2404 				case SKL_DPLL_CTRL1_2160:
2405 					linkBandwidth = 2160000 / 5;
2406 					break;
2407 				default:
2408 					linkBandwidth = 270000;
2409 					ERROR("%s: DDI No known DP-link reference clock selected, assuming default\n", __func__);
2410 					break;
2411 			}
2412 		} else {
2413 			ERROR("%s: DDI No known PLL selected, assuming default DP-link reference\n", __func__);
2414 		}
2415 	}
2416 	TRACE("%s: DDI DP-link reference clock is %gMhz\n", __func__, linkBandwidth / 1000.0f);
2417 
2418 	uint32 fPipeOffset = 0;
2419 	switch (fPipe->Index()) {
2420 		case INTEL_PIPE_B:
2421 			fPipeOffset = 0x1000;
2422 			break;
2423 		case INTEL_PIPE_C:
2424 			fPipeOffset = 0x2000;
2425 			break;
2426 		case INTEL_PIPE_D:
2427 			fPipeOffset = 0xf000;
2428 			break;
2429 		default:
2430 			break;
2431 	}
2432 
2433 	TRACE("%s: DDI M1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_DATA_M + fPipeOffset));
2434 	TRACE("%s: DDI N1 data before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_DATA_N + fPipeOffset));
2435 	TRACE("%s: DDI M1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_LINK_M + fPipeOffset));
2436 	TRACE("%s: DDI N1 link before: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_LINK_N + fPipeOffset));
2437 
2438 	uint32 pipeFunc = read32(PIPE_DDI_FUNC_CTL_A + fPipeOffset);
2439 	uint32 bitsPerPixel = (pipeFunc & PIPE_DDI_BPC_MASK) >> PIPE_DDI_COLOR_SHIFT;
2440 	switch (bitsPerPixel) {
2441 		case PIPE_DDI_8BPC:
2442 			bitsPerPixel = 24;
2443 			break;
2444 		case PIPE_DDI_10BPC:
2445 			bitsPerPixel = 30;
2446 			break;
2447 		case PIPE_DDI_6BPC:
2448 			bitsPerPixel = 18;
2449 			break;
2450 		case PIPE_DDI_12BPC:
2451 			bitsPerPixel = 36;
2452 			break;
2453 		default:
2454 			ERROR("%s: DDI illegal link colordepth set.\n", __func__);
2455 			return B_ERROR;
2456 	}
2457 	TRACE("%s: DDI Link Colordepth: %" B_PRIu32 "\n", __func__, bitsPerPixel);
2458 
2459 	uint32 lanes = 4;
2460 	// Only DP modes supports less than 4 lanes: read current config
2461 	if (((pipeFunc & PIPE_DDI_MODESEL_MASK) >> PIPE_DDI_MODESEL_SHIFT) >= PIPE_DDI_MODE_DP_SST) {
2462 		// On gen 9.5 IceLake 3x mode exists (DSI only), earlier models: reserved value.
2463 		lanes = ((pipeFunc & PIPE_DDI_DP_WIDTH_MASK) >> PIPE_DDI_DP_WIDTH_SHIFT) + 1;
2464 		TRACE("%s: DDI in DP mode with %" B_PRIx32 " lane(s) in use\n", __func__, lanes);
2465 	} else {
2466 		TRACE("%s: DDI in non-DP mode with %" B_PRIx32 " lane(s) in use\n", __func__, lanes);
2467 	}
2468 
2469 	//Setup Data M/N
2470 	uint64 linkspeed = lanes * linkBandwidth * 8;
2471 	uint64 ret_n = 1;
2472 	while(ret_n < linkspeed) {
2473 		ret_n *= 2;
2474 	}
2475 	if (ret_n > 0x800000) {
2476 		ret_n = 0x800000;
2477 	}
2478 	uint64 ret_m = timing.pixel_clock * ret_n * bitsPerPixel / linkspeed;
2479 	while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) {
2480 		ret_m >>= 1;
2481 		ret_n >>= 1;
2482 	}
2483 	//Set TU size bits (to default, max) before link training so that error detection works
2484 	write32(INTEL_DDI_PIPE_A_DATA_M + fPipeOffset, ret_m | FDI_PIPE_MN_TU_SIZE_MASK);
2485 	write32(INTEL_DDI_PIPE_A_DATA_N + fPipeOffset, ret_n);
2486 
2487 	//Setup Link M/N
2488 	linkspeed = linkBandwidth;
2489 	ret_n = 1;
2490 	while(ret_n < linkspeed) {
2491 		ret_n *= 2;
2492 	}
2493 	if (ret_n > 0x800000) {
2494 		ret_n = 0x800000;
2495 	}
2496 	ret_m = timing.pixel_clock * ret_n / linkspeed;
2497 	while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) {
2498 		ret_m >>= 1;
2499 		ret_n >>= 1;
2500 	}
2501 	write32(INTEL_DDI_PIPE_A_LINK_M + fPipeOffset, ret_m);
2502 	//Writing Link N triggers all four registers to be activated also (on next VBlank)
2503 	write32(INTEL_DDI_PIPE_A_LINK_N + fPipeOffset, ret_n);
2504 
2505 	TRACE("%s: DDI M1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_DATA_M + fPipeOffset));
2506 	TRACE("%s: DDI N1 data after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_DATA_N + fPipeOffset));
2507 	TRACE("%s: DDI M1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_LINK_M + fPipeOffset));
2508 	TRACE("%s: DDI N1 link after: 0x%" B_PRIx32 "\n", __func__, read32(INTEL_DDI_PIPE_A_LINK_N + fPipeOffset));
2509 
2510 	return B_OK;
2511 }
2512 
2513 status_t
2514 DigitalDisplayInterface::SetDisplayMode(display_mode* target, uint32 colorMode)
2515 {
2516 	CALLED();
2517 	TRACE("%s: %s %dx%d\n", __func__, PortName(), target->timing.h_display,
2518 		target->timing.v_display);
2519 
2520 	if (fPipe == NULL) {
2521 		ERROR("%s: Setting display mode without assigned pipe!\n", __func__);
2522 		return B_ERROR;
2523 	}
2524 
2525 	display_timing hardwareTarget = target->timing;
2526 	bool needsScaling = false;
2527 	if ((PortIndex() == INTEL_PORT_A)
2528 		&& (gInfo->shared_info->device_type.IsMobile() || _IsEDPPort())) {
2529 		// For internal panels, we may need to set the timings according to the panel
2530 		// native video mode, and let the panel fitter do the scaling.
2531 
2532 		if (gInfo->shared_info->got_vbt || HasEDID()) {
2533 			// Set vbios hardware panel mode as base
2534 			hardwareTarget = gInfo->shared_info->panel_timing;
2535 			if (HasEDID()) {
2536 				// the first detailed timing supposed to be the best supported one
2537 				int i;
2538 				for (i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) {
2539 					edid1_detailed_monitor *monitor = &fEDIDInfo.detailed_monitor[i];
2540 					if (monitor->monitor_desc_type == EDID1_IS_DETAILED_TIMING)
2541 						break;
2542 				}
2543 				if (i < EDID1_NUM_DETAILED_MONITOR_DESC) {
2544 					TRACE("%s: Using EDID detailed timing %d for the internal panel\n",
2545 						__func__, i);
2546 					const edid1_detailed_timing& timing
2547 						= fEDIDInfo.detailed_monitor[i].data.detailed_timing;
2548 					hardwareTarget.pixel_clock = timing.pixel_clock * 10;
2549 					hardwareTarget.h_display = timing.h_active;
2550 					hardwareTarget.h_sync_start = timing.h_active + timing.h_sync_off;
2551 					hardwareTarget.h_sync_end = hardwareTarget.h_sync_start + timing.h_sync_width;
2552 					hardwareTarget.h_total = timing.h_active + timing.h_blank;
2553 					hardwareTarget.v_display = timing.v_active;
2554 					hardwareTarget.v_sync_start = timing.v_active + timing.v_sync_off;
2555 					hardwareTarget.v_sync_end = hardwareTarget.v_sync_start + timing.v_sync_width;
2556 					hardwareTarget.v_total = timing.v_active + timing.v_blank;
2557 					hardwareTarget.flags = 0;
2558 					if (timing.sync == 3) {
2559 						if (timing.misc & 1)
2560 							hardwareTarget.flags |= B_POSITIVE_HSYNC;
2561 						if (timing.misc & 2)
2562 							hardwareTarget.flags |= B_POSITIVE_VSYNC;
2563 					}
2564 					if (timing.interlaced)
2565 						hardwareTarget.flags |= B_TIMING_INTERLACED;
2566 				}
2567 			}
2568 			if (hardwareTarget.h_display == target->timing.h_display
2569 					&& hardwareTarget.v_display == target->timing.v_display) {
2570 				// We are setting the native video mode, nothing special to do
2571 				// Note: this means refresh and timing might vary according to requested mode.
2572 				hardwareTarget = target->timing;
2573 				TRACE("%s: Setting internal panel to native resolution at %" B_PRIu32 "Hz\n", __func__,
2574 					hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * hardwareTarget.v_total));
2575 			} else {
2576 				// We need to enable the panel fitter
2577 				TRACE("%s: Hardware mode will actually be %dx%d at %" B_PRIu32 "Hz\n", __func__,
2578 					hardwareTarget.h_display, hardwareTarget.v_display,
2579 					hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * hardwareTarget.v_total));
2580 
2581 				// FIXME we should also get the refresh frequency from the target
2582 				// mode, and then "sanitize" the resulting mode we made up.
2583 				needsScaling = true;
2584 			}
2585 		} else {
2586 			TRACE("%s: Setting internal panel mode without VBT info generation, scaling may not work\n",
2587 				__func__);
2588 			// We don't have VBT data, try to set the requested mode directly
2589 			// and hope for the best
2590 			hardwareTarget = target->timing;
2591 		}
2592 	}
2593 
2594 	// Setup PanelFitter
2595 	PanelFitter* fitter = fPipe->PFT();
2596 	if (fitter != NULL)
2597 		fitter->Enable(hardwareTarget);
2598 
2599 	// skip FDI as it never applies to DDI (on gen7 and 8 only for the real analog VGA port)
2600 
2601 	// Program general pipe config
2602 	fPipe->Configure(target);
2603 
2604 	uint32 pllSel = 0xff; // no PLL selected
2605 	if (gInfo->shared_info->device_type.Generation() <= 8) {
2606 		unsigned int r2_out, n2_out, p_out;
2607 		hsw_ddi_calculate_wrpll(
2608 			hardwareTarget.pixel_clock * 1000 /* in Hz */,
2609 			&r2_out, &n2_out, &p_out);
2610 	} else {
2611 		skl_wrpll_params wrpll_params;
2612 		skl_ddi_calculate_wrpll(
2613 			hardwareTarget.pixel_clock * 1000 /* in Hz */,
2614 			gInfo->shared_info->pll_info.reference_frequency,
2615 			&wrpll_params);
2616 		fPipe->ConfigureClocksSKL(wrpll_params,
2617 			hardwareTarget.pixel_clock,
2618 			PortIndex(),
2619 			&pllSel);
2620 	}
2621 
2622 	// Program target display mode
2623 	fPipe->ConfigureTimings(target, !needsScaling);
2624 	_SetPortLinkGen8(hardwareTarget, pllSel);
2625 
2626 	// Set fCurrentMode to our set display mode
2627 	memcpy(&fCurrentMode, target, sizeof(display_mode));
2628 
2629 	return B_OK;
2630 }
2631