diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp b/src/add-ons/accelerants/intel_extreme/Ports.cpp index cca19d09d9..c5bb79dff8 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.cpp +++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp @@ -234,6 +234,13 @@ Port::GetEDID(edid1_info* edid, bool forceRead) if (fEDIDState == B_OK) { TRACE("%s: found EDID information!\n", PortName()); edid_dump(&fEDIDInfo); + } else if (SetupI2cFallback(&bus) == B_OK) { + fEDIDState = ddc2_read_edid1(&bus, &fEDIDInfo, NULL, NULL); + + if (fEDIDState == B_OK) { + TRACE("%s: found EDID information!\n", PortName()); + edid_dump(&fEDIDInfo); + } } } @@ -270,6 +277,13 @@ Port::SetupI2c(i2c_bus *bus) } +status_t +Port::SetupI2cFallback(i2c_bus *bus) +{ + return B_ERROR; +} + + status_t Port::GetPLLLimits(pll_limits& limits) { @@ -453,7 +467,19 @@ Port::_IsDisplayPortInVBT() if (!_IsPortInVBT(&foundIndex)) return false; child_device_config& config = gInfo->shared_info->device_configs[foundIndex]; - return config.aux_channel > 0; + return config.aux_channel > 0 && (config.device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT) != 0; +} + + +bool +Port::_IsHdmiInVBT() +{ + uint32 foundIndex = 0; + if (!_IsPortInVBT(&foundIndex)) + return false; + child_device_config& config = gInfo->shared_info->device_configs[foundIndex]; + return config.ddc_pin > 0 && ((config.device_type & DEVICE_TYPE_NOT_HDMI_OUTPUT) == 0 + || (config.device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING) != 0); } @@ -607,7 +633,7 @@ Port::_DpAuxSendReceiveHook(const struct i2c_bus *bus, uint32 slaveAddress, const uint8 *writeBuffer, size_t writeLength, uint8 *readBuffer, size_t readLength) { CALLED(); - DigitalDisplayInterface* port = (DigitalDisplayInterface*)bus->cookie; + Port* port = (Port*)bus->cookie; return port->_DpAuxSendReceive(slaveAddress, writeBuffer, writeLength, readBuffer, readLength); } @@ -693,9 +719,12 @@ Port::_DpAuxTransfer(dp_aux_msg* message) else if (result < B_OK) return result; - switch(message->reply & DP_AUX_NATIVE_REPLY_MASK) { + switch (message->reply & DP_AUX_NATIVE_REPLY_MASK) { case DP_AUX_NATIVE_REPLY_ACK: return B_OK; + case DP_AUX_NATIVE_REPLY_NACK: + TRACE("%s: aux native reply nack\n", __func__); + return B_IO_ERROR; case DP_AUX_NATIVE_REPLY_DEFER: TRACE("%s: aux reply defer received. Snoozing.\n", __func__); snooze(400); @@ -2181,6 +2210,21 @@ DigitalDisplayInterface::SetupI2c(i2c_bus *bus) } +status_t +DigitalDisplayInterface::SetupI2cFallback(i2c_bus *bus) +{ + CALLED(); + + const uint32 deviceConfigCount = gInfo->shared_info->device_config_count; + if (gInfo->shared_info->device_type.Generation() >= 6 && deviceConfigCount > 0 + && _IsDisplayPortInVBT() && _IsHdmiInVBT()) { + return Port::SetupI2c(bus); + } + + return B_ERROR; +} + + bool DigitalDisplayInterface::IsConnected() { @@ -2310,17 +2354,11 @@ DigitalDisplayInterface::IsConnected() break; } pipeState = read32(pipeReg); - if (!(pipeState & PIPE_DDI_FUNC_CTL_ENABLE)) { - TRACE("%s: Connected but port down: enabling port on pipe nr %" B_PRIx32 "\n", __func__, pipeCnt + 1); - //fixme: turn on port and power - pipeState |= PIPE_DDI_FUNC_CTL_ENABLE; - pipeState &= ~PIPE_DDI_SELECT_MASK; - pipeState |= (((uint32)PortIndex()) - 1) << PIPE_DDI_SELECT_SHIFT; - //fixme: set mode to DVI mode for now (b26..24 = %001) - write32(pipeReg, pipeState); - TRACE("%s: PIPE_DDI_FUNC_CTL after: 0x%" B_PRIx32 "\n", __func__, read32(pipeReg)); - return true; + if ((pipeState & PIPE_DDI_FUNC_CTL_ENABLE) == 0) { + TRACE("%s: Connected but port down\n", __func__); + return false; } + return true; } TRACE("%s: No pipe available, ignoring connected screen\n", __func__); } diff --git a/src/add-ons/accelerants/intel_extreme/Ports.h b/src/add-ons/accelerants/intel_extreme/Ports.h index e6c3ef69ba..6a4cf5e75f 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.h +++ b/src/add-ons/accelerants/intel_extreme/Ports.h @@ -60,6 +60,7 @@ virtual status_t Power(bool enabled); virtual status_t GetEDID(edid1_info* edid, bool forceRead = false); virtual status_t SetupI2c(struct i2c_bus *bus); +virtual status_t SetupI2cFallback(struct i2c_bus *bus); virtual status_t GetPLLLimits(pll_limits& limits); @@ -77,6 +78,7 @@ static status_t _SetI2CSignals(void* cookie, int clock, int data); bool _IsPortInVBT(uint32* foundIndex = NULL); bool _IsDisplayPortInVBT(); + bool _IsHdmiInVBT(); bool _IsEDPPort(); status_t _SetupDpAuxI2c(struct i2c_bus *bus); @@ -231,6 +233,7 @@ virtual status_t Power(bool enabled); virtual status_t SetPipe(Pipe* pipe); virtual status_t SetupI2c(i2c_bus *bus); +virtual status_t SetupI2cFallback(struct i2c_bus *bus); virtual bool IsConnected();