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