intel_extreme: leverage VBT device type for internal panel
* also handle dp aux on PCH. * tested on Gen7, should work from Gen6. Change-Id: I8d99bcdc10c817e66441a6a644df490dd988a74d Reviewed-on: https://review.haiku-os.org/c/haiku/+/5290 Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
This commit is contained in:
parent
d98fcb7db6
commit
1c23e6bcf1
@ -289,6 +289,22 @@ struct ring_buffer {
|
||||
struct child_device_config {
|
||||
uint16 handle;
|
||||
uint16 device_type;
|
||||
#define DEVICE_TYPE_ANALOG_OUTPUT (1 << 0)
|
||||
#define DEVICE_TYPE_DIGITAL_OUTPUT (1 << 1)
|
||||
#define DEVICE_TYPE_DISPLAYPORT_OUTPUT (1 << 2)
|
||||
#define DEVICE_TYPE_VIDEO_SIGNALING (1 << 3)
|
||||
#define DEVICE_TYPE_TMDS_DVI_SIGNALING (1 << 4)
|
||||
#define DEVICE_TYPE_LVDS_SIGNALING (1 << 5)
|
||||
#define DEVICE_TYPE_HIGH_SPEED_LINK (1 << 6)
|
||||
#define DEVICE_TYPE_DUAL_CHANNEL (1 << 8)
|
||||
#define DEVICE_TYPE_COMPOSITE_OUTPUT (1 << 9)
|
||||
#define DEVICE_TYPE_MIPI_OUTPUT (1 << 10)
|
||||
#define DEVICE_TYPE_NOT_HDMI_OUTPUT (1 << 11)
|
||||
#define DEVICE_TYPE_INTERNAL_CONNECTOR (1 << 12)
|
||||
#define DEVICE_TYPE_HOTPLUG_SIGNALING (1 << 13)
|
||||
#define DEVICE_TYPE_POWER_MANAGEMENT (1 << 14)
|
||||
#define DEVICE_TYPE_CLASS_EXTENSION (1 << 15)
|
||||
|
||||
uint8 device_id[10];
|
||||
uint16 addin_offset;
|
||||
uint8 dvo_port;
|
||||
@ -1112,6 +1128,15 @@ struct intel_brightness_legacy {
|
||||
(_DPA_AUX_CH_CTL + (_DPB_AUX_CH_CTL - _DPA_AUX_CH_CTL) * aux)
|
||||
#define DP_AUX_CH_DATA(aux, i) \
|
||||
(_DPA_AUX_CH_DATA1 + (_DPB_AUX_CH_DATA1 - _DPA_AUX_CH_DATA1) * aux + i * 4)
|
||||
#define _PCH_DPB_AUX_CH_CTL (0x4110 | REGS_SOUTH_TRANSCODER_PORT)
|
||||
#define _PCH_DPB_AUX_CH_DATA1 (0x4114 | REGS_SOUTH_TRANSCODER_PORT)
|
||||
#define _PCH_DPC_AUX_CH_CTL (0x4210 | REGS_SOUTH_TRANSCODER_PORT)
|
||||
#define _PCH_DPC_AUX_CH_DATA1 (0x4214 | REGS_SOUTH_TRANSCODER_PORT)
|
||||
#define PCH_DP_AUX_CH_CTL(aux) \
|
||||
(_PCH_DPB_AUX_CH_CTL + (_PCH_DPC_AUX_CH_CTL - _PCH_DPB_AUX_CH_CTL) * (aux - AUX_CH_B))
|
||||
#define PCH_DP_AUX_CH_DATA(aux, i) \
|
||||
(_PCH_DPB_AUX_CH_DATA1 + (_PCH_DPC_AUX_CH_DATA1 - _PCH_DPB_AUX_CH_DATA1) * (aux - AUX_CH_B) \
|
||||
+ i * 4)
|
||||
|
||||
#define INTEL_DP_AUX_CTL_BUSY (1 << 31)
|
||||
#define INTEL_DP_AUX_CTL_DONE (1 << 30)
|
||||
|
@ -457,6 +457,17 @@ Port::_IsDisplayPortInVBT()
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Port::_IsInternalPanelPort()
|
||||
{
|
||||
uint32 foundIndex = 0;
|
||||
if (!_IsPortInVBT(&foundIndex))
|
||||
return false;
|
||||
child_device_config& config = gInfo->shared_info->device_configs[foundIndex];
|
||||
return (config.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR) == DEVICE_TYPE_INTERNAL_CONNECTOR;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Analog Port
|
||||
|
||||
|
||||
@ -1224,7 +1235,8 @@ DisplayPort::IsConnected()
|
||||
TRACE("%s: %s link detected\n", __func__, PortName());
|
||||
|
||||
// On laptops we always have an internal panel.. (this is on the eDP port)
|
||||
if (gInfo->shared_info->device_type.IsMobile() && (PortIndex() == INTEL_PORT_A)) {
|
||||
if ((gInfo->shared_info->device_type.IsMobile() || _IsInternalPanelPort())
|
||||
&& (PortIndex() == INTEL_PORT_A)) {
|
||||
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,
|
||||
@ -1260,7 +1272,7 @@ DigitalDisplayInterface::SetupI2c(i2c_bus *bus)
|
||||
CALLED();
|
||||
|
||||
const uint32 deviceConfigCount = gInfo->shared_info->device_config_count;
|
||||
if (gInfo->shared_info->device_type.Generation() >= 9 && deviceConfigCount > 0) {
|
||||
if (gInfo->shared_info->device_type.Generation() >= 6 && deviceConfigCount > 0) {
|
||||
if (!_IsDisplayPortInVBT())
|
||||
return Port::SetupI2c(bus);
|
||||
}
|
||||
@ -1510,11 +1522,16 @@ DigitalDisplayInterface::_DpAuxTransfer(uint8* transmitBuffer, uint8 transmitSiz
|
||||
{
|
||||
addr_t channelControl;
|
||||
addr_t channelData[5];
|
||||
if (gInfo->shared_info->device_type.Generation() >= 9) {
|
||||
// assume AUX channel 0
|
||||
channelControl = DP_AUX_CH_CTL(_DpAuxChannel());
|
||||
aux_channel channel = _DpAuxChannel();
|
||||
if (gInfo->shared_info->device_type.Generation() >= 9
|
||||
|| (gInfo->shared_info->pch_info != INTEL_PCH_NONE && channel == AUX_CH_A)) {
|
||||
channelControl = DP_AUX_CH_CTL(channel);
|
||||
for (int i = 0; i < 5; i++)
|
||||
channelData[i] = DP_AUX_CH_DATA(_DpAuxChannel(), i);
|
||||
channelData[i] = DP_AUX_CH_DATA(channel, i);
|
||||
} else if (gInfo->shared_info->pch_info != INTEL_PCH_NONE) {
|
||||
channelControl = PCH_DP_AUX_CH_CTL(channel);
|
||||
for (int i = 0; i < 5; i++)
|
||||
channelData[i] = PCH_DP_AUX_CH_DATA(channel, i);
|
||||
} else {
|
||||
ERROR("DigitalDisplayInterface::_DpAuxTransfer() unknown register config\n");
|
||||
return B_BUSY;
|
||||
@ -1537,6 +1554,15 @@ DigitalDisplayInterface::_DpAuxTransfer(uint8* transmitBuffer, uint8 transmitSiz
|
||||
| INTEL_DP_AUX_CTL_TIMEOUT_ERROR | INTEL_DP_AUX_CTL_TIMEOUT_1600us | INTEL_DP_AUX_CTL_RECEIVE_ERROR
|
||||
| (transmitSize << INTEL_DP_AUX_CTL_MSG_SIZE_SHIFT) | INTEL_DP_AUX_CTL_FW_SYNC_PULSE_SKL(32)
|
||||
| INTEL_DP_AUX_CTL_SYNC_PULSE_SKL(32);
|
||||
} else {
|
||||
uint32 aux_clock_divider = 0xe1; // TODO: value for 450Mhz
|
||||
uint32 timeout = INTEL_DP_AUX_CTL_TIMEOUT_400us;
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_BDW))
|
||||
timeout = INTEL_DP_AUX_CTL_TIMEOUT_600us;
|
||||
sendControl = INTEL_DP_AUX_CTL_BUSY | INTEL_DP_AUX_CTL_DONE | INTEL_DP_AUX_CTL_INTERRUPT
|
||||
| INTEL_DP_AUX_CTL_TIMEOUT_ERROR | timeout | INTEL_DP_AUX_CTL_RECEIVE_ERROR
|
||||
| (transmitSize << INTEL_DP_AUX_CTL_MSG_SIZE_SHIFT) | (3 << INTEL_DP_AUX_CTL_PRECHARGE_2US_SHIFT)
|
||||
| (aux_clock_divider << INTEL_DP_AUX_CTL_BIT_CLOCK_2X_SHIFT);
|
||||
}
|
||||
|
||||
uint8 retry;
|
||||
@ -1863,7 +1889,8 @@ DisplayPort::SetDisplayMode(display_mode* target, uint32 colorMode)
|
||||
} else {
|
||||
display_timing hardwareTarget = target->timing;
|
||||
bool needsScaling = false;
|
||||
if ((PortIndex() == INTEL_PORT_A) && gInfo->shared_info->device_type.IsMobile()) {
|
||||
if ((PortIndex() == INTEL_PORT_A)
|
||||
&& (gInfo->shared_info->device_type.IsMobile() || _IsInternalPanelPort())) {
|
||||
// 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.
|
||||
// note: upto/including generation 5 laptop panels are still LVDS types, handled elsewhere.
|
||||
@ -2175,7 +2202,7 @@ DigitalDisplayInterface::IsConnected()
|
||||
}
|
||||
|
||||
const uint32 deviceConfigCount = gInfo->shared_info->device_config_count;
|
||||
if (gInfo->shared_info->device_type.Generation() >= 9 && deviceConfigCount > 0) {
|
||||
if (gInfo->shared_info->device_type.Generation() >= 6 && deviceConfigCount > 0) {
|
||||
// check VBT mapping
|
||||
if (!_IsPortInVBT()) {
|
||||
TRACE("%s: %s: port not found in VBT\n", __func__, PortName());
|
||||
@ -2192,7 +2219,8 @@ DigitalDisplayInterface::IsConnected()
|
||||
|
||||
// On laptops we always have an internal panel.. (on the eDP port on DDI systems, fixed on eDP pipe)
|
||||
uint32 pipeState = 0;
|
||||
if (gInfo->shared_info->device_type.IsMobile() && (PortIndex() == INTEL_PORT_E)) {
|
||||
if ((gInfo->shared_info->device_type.IsMobile() || _IsInternalPanelPort())
|
||||
&& (PortIndex() == INTEL_PORT_E)) {
|
||||
pipeState = read32(PIPE_DDI_FUNC_CTL_EDP);
|
||||
TRACE("%s: PIPE_DDI_FUNC_CTL_EDP: 0x%" B_PRIx32 "\n", __func__, pipeState);
|
||||
if (!(pipeState & PIPE_DDI_FUNC_CTL_ENABLE)) {
|
||||
@ -2426,7 +2454,8 @@ DigitalDisplayInterface::SetDisplayMode(display_mode* target, uint32 colorMode)
|
||||
|
||||
display_timing hardwareTarget = target->timing;
|
||||
bool needsScaling = false;
|
||||
if ((PortIndex() == INTEL_PORT_E) && gInfo->shared_info->device_type.IsMobile()) {
|
||||
if ((PortIndex() == INTEL_PORT_E)
|
||||
&& (gInfo->shared_info->device_type.IsMobile() || _IsInternalPanelPort())) {
|
||||
// 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.
|
||||
|
||||
|
@ -77,6 +77,7 @@ static status_t _SetI2CSignals(void* cookie, int clock,
|
||||
int data);
|
||||
bool _IsPortInVBT(uint32* foundIndex = NULL);
|
||||
bool _IsDisplayPortInVBT();
|
||||
bool _IsInternalPanelPort();
|
||||
|
||||
display_mode fCurrentMode;
|
||||
Pipe* fPipe;
|
||||
|
Loading…
Reference in New Issue
Block a user