[prev in list] [next in list] [prev in thread] [next in thread] 

List:       haiku-commits
Subject:    [haiku-commits] haiku: hrev55669 - src/add-ons/accelerants/intel_extreme
From:       Rudolf Cornelissen <rudhaiku () gmail ! com>
Date:       2021-11-29 11:30:20
Message-ID: 20211129113020.F0DD53FC1F () turing ! freelists ! org
[Download RAW message or body]

hrev55669 adds 1 changeset to branch 'master'
old head: 6ed123e532b52755d018320aba2da84679b6c6e2
new head: c199501e81ac47cd8fcc3201ebf4863d7652af88
overview: https://git.haiku-os.org/haiku/log/?qt=range&q=c199501e81ac+%5E6ed123e532b5

----------------------------------------------------------------------------

c199501e81ac: intel_extreme: add laptop panel detection and mode scaling for DDI \
systems

                                 [ Rudolf Cornelissen <rudhaiku@gmail.com> ]

----------------------------------------------------------------------------

Revision:    hrev55669
Commit:      c199501e81ac47cd8fcc3201ebf4863d7652af88
URL:         https://git.haiku-os.org/haiku/commit/?id=c199501e81ac
Author:      Rudolf Cornelissen <rudhaiku@gmail.com>
Date:        Mon Nov 29 13:30:27 2021 UTC

----------------------------------------------------------------------------

2 files changed, 75 insertions(+), 33 deletions(-)
src/add-ons/accelerants/intel_extreme/Ports.cpp | 104 ++++++++++++++------
src/add-ons/accelerants/intel_extreme/Ports.h   |   4 +-

----------------------------------------------------------------------------

diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp \
b/src/add-ons/accelerants/intel_extreme/Ports.cpp index 41c91e5eea..01ad74fef5 100644
--- a/src/add-ons/accelerants/intel_extreme/Ports.cpp
+++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp
@@ -626,12 +626,15 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 \
colorMode)  if (hardwareTarget.h_display == target->timing.h_display
 				&& hardwareTarget.v_display == target->timing.v_display) {
 			// We are setting the native video mode, nothing special to do
-			TRACE("Setting LVDS to native mode\n");
+			// Note: this means refresh and timing might vary according to requested mode.
 			hardwareTarget = target->timing;
+			TRACE("%s: Setting LVDS to native resolution at %" B_PRIu32 "Hz\n", __func__,
+				hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * \
hardwareTarget.v_total));  } else {
 			// We need to enable the panel fitter
-			TRACE("%s: hardware mode will actually be %dx%d\n", __func__,
-				hardwareTarget.h_display, hardwareTarget.v_display);
+			TRACE("%s: Hardware mode will actually be %dx%d at %" B_PRIu32 "Hz\n", __func__,
+				hardwareTarget.h_display, hardwareTarget.v_display,
+				hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * \
hardwareTarget.v_total));  
 			// FIXME we should also get the refresh frequency from the target
 			// mode, and then "sanitize" the resulting mode we made up.
@@ -1107,7 +1110,7 @@ DisplayPort::_PortRegister()
 
 
 status_t
-DisplayPort::_SetPortLinkGen4(display_mode* target)
+DisplayPort::_SetPortLinkGen4(const display_timing& timing)
 {
 	// Khz / 10. ( each output octet encoded as 10 bits. 
 	//uint32 linkBandwidth = gInfo->shared_info->fdi_link_frequency * 1000 / 10; \
//=270000 khz @@ -1134,7 +1137,7 @@ DisplayPort::_SetPortLinkGen4(display_mode* \
target)  if (ret_n > 0x800000) {
 		ret_n = 0x800000;
 	}
-	uint64 ret_m = target->timing.pixel_clock * ret_n * bitsPerPixel / linkspeed;
+	uint64 ret_m = timing.pixel_clock * ret_n * bitsPerPixel / linkspeed;
 	while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) {
 		ret_m >>= 1;
 		ret_n >>= 1;
@@ -1152,7 +1155,7 @@ DisplayPort::_SetPortLinkGen4(display_mode* target)
 	if (ret_n > 0x800000) {
 		ret_n = 0x800000;
 	}
-	ret_m = target->timing.pixel_clock * ret_n / linkspeed;
+	ret_m = timing.pixel_clock * ret_n / linkspeed;
 	while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) {
 		ret_m >>= 1;
 		ret_n >>= 1;
@@ -1185,7 +1188,7 @@ DisplayPort::SetDisplayMode(display_mode* target, uint32 \
colorMode)  status_t result = B_OK;
 	if (gInfo->shared_info->device_type.Generation() <= 4) {
 		fPipe->ConfigureTimings(target);
-		result = _SetPortLinkGen4(target);
+		result = _SetPortLinkGen4(target->timing);
 	} else {
 		//fixme: doesn't work yet. For now just scale to native mode.
 #if 0
@@ -1411,11 +1414,21 @@ DigitalDisplayInterface::IsConnected()
 				TRACE("%s: Connected\n", __func__);
 				return true;
 			}
-			// On laptops we always have an internal panel.. (this is on the eDP port)
-			if ((gInfo->shared_info->device_type.IsMobile()) && (PortIndex() == \
                INTEL_PORT_E)) {
-				TRACE("%s: Laptop. Assuming internal panel is connected here\n", __func__);
-				return true;
-			}
+		}
+	}
+
+	// On laptops we always have an internal panel.. (this is on the eDP port)
+	if (gInfo->shared_info->device_type.IsMobile() && (PortIndex() == INTEL_PORT_E)) {
+		if (gInfo->shared_info->has_vesa_edid_info) {
+			TRACE("%s: Laptop. Using VESA edid info\n", __func__);
+			memcpy(&fEDIDInfo, &gInfo->shared_info->vesa_edid_info,
+				sizeof(edid1_info));
+			fEDIDState = B_OK;
+			// HasEDID now true
+			return true;
+		} else if (gInfo->shared_info->got_vbt) {
+			TRACE("%s: Laptop. No EDID, but force enabled as we have a VBT\n", __func__);
+			return true;
 		}
 	}
 
@@ -1424,7 +1437,7 @@ DigitalDisplayInterface::IsConnected()
 }
 
 status_t
-DigitalDisplayInterface::_SetPortLinkGen8(display_mode* target)
+DigitalDisplayInterface::_SetPortLinkGen8(const display_timing& timing)
 {
 	// Khz / 10. ( each output octet encoded as 10 bits.
 	//uint32 linkBandwidth = gInfo->shared_info->fdi_link_frequency * 1000 / 10; \
//=270000 khz @@ -1470,7 +1483,7 @@ \
DigitalDisplayInterface::_SetPortLinkGen8(display_mode* target)  if (ret_n > \
0x800000) {  ret_n = 0x800000;
 	}
-	uint64 ret_m = target->timing.pixel_clock * ret_n * bitsPerPixel / linkspeed;
+	uint64 ret_m = timing.pixel_clock * ret_n * bitsPerPixel / linkspeed;
 	while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) {
 		ret_m >>= 1;
 		ret_n >>= 1;
@@ -1488,7 +1501,7 @@ DigitalDisplayInterface::_SetPortLinkGen8(display_mode* target)
 	if (ret_n > 0x800000) {
 		ret_n = 0x800000;
 	}
-	ret_m = target->timing.pixel_clock * ret_n / linkspeed;
+	ret_m = timing.pixel_clock * ret_n / linkspeed;
 	while ((ret_n > 0xffffff) || (ret_m > 0xffffff)) {
 		ret_m >>= 1;
 		ret_n >>= 1;
@@ -1517,42 +1530,71 @@ DigitalDisplayInterface::SetDisplayMode(display_mode* target, \
uint32 colorMode)  return B_ERROR;
 	}
 
-	// Setup PanelFitter and Train FDI if it exists
-	PanelFitter* fitter = fPipe->PFT();
-	if (fitter != NULL)
-		fitter->Enable(target->timing);
-	// skip FDI if it doesn't exist
-	if (gInfo->shared_info->device_type.Generation() <= 8) {
-		// Skip FDI if we have a CPU connected display
-		if (PortIndex() != INTEL_PORT_A) {
-			FDILink* link = fPipe->FDI();
-			if (link != NULL)
-				link->Train(&target->timing);
+	display_timing hardwareTarget = target->timing;
+	bool needsScaling = false;
+	if ((PortIndex() == INTEL_PORT_E) && gInfo->shared_info->device_type.IsMobile()) {
+		// For internal panels, we may need to set the timings according to the panel
+		// native video mode, and let the panel fitter do the scaling.
+
+		if (gInfo->shared_info->got_vbt) {
+			// Set vbios hardware panel mode as base
+			hardwareTarget = gInfo->shared_info->panel_timing;
+
+			if (hardwareTarget.h_display == target->timing.h_display
+					&& hardwareTarget.v_display == target->timing.v_display) {
+				// We are setting the native video mode, nothing special to do
+				// Note: this means refresh and timing might vary according to requested mode.
+				hardwareTarget = target->timing;
+				TRACE("%s: Setting internal panel to native resolution at %" B_PRIu32 "Hz\n", \
__func__, +					hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * \
hardwareTarget.v_total)); +			} else {
+				// We need to enable the panel fitter
+				TRACE("%s: Hardware mode will actually be %dx%d at %" B_PRIu32 "Hz\n", __func__,
+					hardwareTarget.h_display, hardwareTarget.v_display,
+					hardwareTarget.pixel_clock * 1000 / (hardwareTarget.h_total * \
hardwareTarget.v_total)); +
+				// FIXME we should also get the refresh frequency from the target
+				// mode, and then "sanitize" the resulting mode we made up.
+				needsScaling = true;
+			}
+		} else {
+			TRACE("%s: Setting internal panel mode without VBT info generation, scaling may \
not work\n", +				__func__);
+			// We don't have VBT data, try to set the requested mode directly
+			// and hope for the best
+			hardwareTarget = target->timing;
 		}
 	}
 
+	// Setup PanelFitter
+	PanelFitter* fitter = fPipe->PFT();
+	if (fitter != NULL)
+		fitter->Enable(hardwareTarget);
+
+	// skip FDI as it never applies to DDI (on gen7 and 8 only for the real analog VGA \
port) +
 	// Program general pipe config
 	fPipe->Configure(target);
 
 	if (gInfo->shared_info->device_type.Generation() <= 8) {
 		unsigned int r2_out, n2_out, p_out;
 		hsw_ddi_calculate_wrpll(
-			target->timing.pixel_clock * 1000 /* in Hz */,
+			hardwareTarget.pixel_clock * 1000 /* in Hz */,
 			&r2_out, &n2_out, &p_out);
 	} else {
 		skl_wrpll_params wrpll_params;
 		skl_ddi_calculate_wrpll(
-			target->timing.pixel_clock * 1000 /* in Hz */,
+			hardwareTarget.pixel_clock * 1000 /* in Hz */,
 			gInfo->shared_info->pll_info.reference_frequency,
 			&wrpll_params);
 		fPipe->ConfigureClocksSKL(wrpll_params,
-			target->timing.pixel_clock,
+			hardwareTarget.pixel_clock,
 			PortIndex());
 	}
 
 	// Program target display mode
-	fPipe->ConfigureTimings(target);
-	_SetPortLinkGen8(target);
+	fPipe->ConfigureTimings(target, !needsScaling);
+	_SetPortLinkGen8(hardwareTarget);
 
 	// Set fCurrentMode to our set display mode
 	memcpy(&fCurrentMode, target, sizeof(display_mode));
diff --git a/src/add-ons/accelerants/intel_extreme/Ports.h \
b/src/add-ons/accelerants/intel_extreme/Ports.h index de4ac1eb1d..4f4673a712 100644
--- a/src/add-ons/accelerants/intel_extreme/Ports.h
+++ b/src/add-ons/accelerants/intel_extreme/Ports.h
@@ -181,7 +181,7 @@ virtual	addr_t						_DDCRegister();
 virtual	addr_t						_PortRegister();
 
 private:
-		status_t					_SetPortLinkGen4(display_mode* target);
+		status_t					_SetPortLinkGen4(const display_timing& timing);
 };
 
 
@@ -218,7 +218,7 @@ virtual addr_t						_PortRegister();
 private:
 		uint8						fMaxLanes;
 
-		status_t					_SetPortLinkGen8(display_mode* target);
+		status_t					_SetPortLinkGen8(const display_timing& timing);
 };
 
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic