diff options
-rw-r--r-- | src/radeon_atombios.c | 305 | ||||
-rw-r--r-- | src/radeon_output.c | 1 | ||||
-rw-r--r-- | src/radeon_probe.h | 3 |
3 files changed, 150 insertions, 159 deletions
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c index 1ca9f86f..717211e4 100644 --- a/src/radeon_atombios.c +++ b/src/radeon_atombios.c @@ -1562,7 +1562,7 @@ static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index) } } - /* BIOSes seem to report DAC on HDMI - they hurt me with their lies */ + /* some BIOSes seem to report DAC on HDMI - they hurt me with their lies */ if ((info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) || (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_B)) { info->BiosConnector[index].DACType = DAC_NONE; @@ -1577,8 +1577,9 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn) unsigned short size; atomDataTablesPtr atomDataPtr; ATOM_CONNECTOR_OBJECT_TABLE *con_obj; + ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj = NULL; - int i, j; + int i, j, path_size, device_support; Bool enable_tv = FALSE; if (xf86ReturnOptValBool(info->Options, OPTION_ATOM_TVOUT, FALSE)) @@ -1591,185 +1592,158 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn) if (crev < 2) return FALSE; + path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *) + ((char *)&atomDataPtr->Object_Header->sHeader + + le16_to_cpu(atomDataPtr->Object_Header->usDisplayPathTableOffset)); con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *) ((char *)&atomDataPtr->Object_Header->sHeader + le16_to_cpu(atomDataPtr->Object_Header->usConnectorObjectTableOffset)); - - for (i = 0; i < con_obj->ucNumberOfObjects; i++) { - ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *SrcDstTable; - ATOM_COMMON_RECORD_HEADER *Record; - uint8_t obj_id, num, obj_type; - int record_base; - uint16_t con_obj_id = le16_to_cpu(con_obj->asObjects[i].usObjectID); - - obj_id = (con_obj_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - num = (con_obj_id & ENUM_ID_MASK) >> ENUM_ID_SHIFT; - obj_type = (con_obj_id & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; - if (obj_type != GRAPH_OBJECT_TYPE_CONNECTOR) - continue; - - SrcDstTable = (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) - ((char *)&atomDataPtr->Object_Header->sHeader - + le16_to_cpu(con_obj->asObjects[i].usSrcDstTableOffset)); - - ErrorF("object id %04x %02x\n", obj_id, SrcDstTable->ucNumberOfSrc); - - if ((info->ChipFamily == CHIP_FAMILY_RS780) && - (obj_id == CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) { - uint32_t slot_config, ct; - - igp_obj = info->atomBIOS->atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2; - - if (!igp_obj) - info->BiosConnector[i].ConnectorType = object_connector_convert[obj_id]; - else { - if (num == 1) - slot_config = igp_obj->ulDDISlot1Config; - else - slot_config = igp_obj->ulDDISlot2Config; - - ct = (slot_config >> 16) & 0xff; - info->BiosConnector[i].ConnectorType = object_connector_convert[ct]; - info->BiosConnector[i].igp_lane_info = slot_config & 0xffff; + device_support = le16_to_cpu(atomDataPtr->Object_Header->usDeviceSupport); + + path_size = 0; + for (i = 0; i < path_obj->ucNumOfDispPath; i++) { + uint8_t *addr = (uint8_t *)path_obj->asDispPath; + ATOM_DISPLAY_OBJECT_PATH *path; + addr += path_size; + path = (ATOM_DISPLAY_OBJECT_PATH *)addr; + path_size += path->usSize; + + if (device_support & path->usDeviceTag) { + uint8_t con_obj_id, con_obj_num, con_obj_type; + + con_obj_id = (path->usConnObjectId & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; + con_obj_num = (path->usConnObjectId & ENUM_ID_MASK) >> ENUM_ID_SHIFT; + con_obj_type = (path->usConnObjectId & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; + + if ((path->usDeviceTag == ATOM_DEVICE_TV1_SUPPORT) || + (path->usDeviceTag == ATOM_DEVICE_TV2_SUPPORT) || + (path->usDeviceTag == ATOM_DEVICE_CV_SUPPORT)) { + if (!enable_tv) { + info->BiosConnector[i].valid = FALSE; + continue; + } } - } else - info->BiosConnector[i].ConnectorType = object_connector_convert[obj_id]; - - if (info->BiosConnector[i].ConnectorType == CONNECTOR_NONE) - info->BiosConnector[i].valid = FALSE; - else - info->BiosConnector[i].valid = TRUE; - info->BiosConnector[i].devices = 0; - for (j = 0; j < SrcDstTable->ucNumberOfSrc; j++) { - uint8_t sobj_id; + if ((info->ChipFamily == CHIP_FAMILY_RS780) && + (con_obj_id == CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) { + uint32_t slot_config, ct; - sobj_id = (le16_to_cpu(SrcDstTable->usSrcObjectID[j]) & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - ErrorF("src object id %04x %d\n", le16_to_cpu(SrcDstTable->usSrcObjectID[j]), sobj_id); + igp_obj = info->atomBIOS->atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2; - switch(sobj_id) { - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); - break; - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); - else { - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP1_INDEX); - info->BiosConnector[i].TMDSType = TMDS_INT; - } - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); - else { - if (num == 1) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP1_INDEX); - else - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP2_INDEX); - info->BiosConnector[i].TMDSType = TMDS_UNIPHY; - } - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); + if (!igp_obj) + info->BiosConnector[i].ConnectorType = object_connector_convert[con_obj_id]; else { - if (num == 1) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP3_INDEX); + if (con_obj_num == 1) + slot_config = igp_obj->ulDDISlot1Config; else - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP4_INDEX); - info->BiosConnector[i].TMDSType = TMDS_UNIPHY1; - } - break; + slot_config = igp_obj->ulDDISlot2Config; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); - else { - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP5_INDEX); - info->BiosConnector[i].TMDSType = TMDS_UNIPHY2; + ct = (slot_config >> 16) & 0xff; + info->BiosConnector[i].ConnectorType = object_connector_convert[ct]; + info->BiosConnector[i].igp_lane_info = slot_config & 0xffff; } - break; - case ENCODER_OBJECT_ID_INTERNAL_TMDS2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP2_INDEX); - info->BiosConnector[i].TMDSType = TMDS_EXT; - break; - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX); - else { - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP3_INDEX); - info->BiosConnector[i].TMDSType = TMDS_LVTMA; - } - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_A || - info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_B) - break; - if (info->BiosConnector[i].ConnectorType == CONNECTOR_DIN || - info->BiosConnector[i].ConnectorType == CONNECTOR_STV || - info->BiosConnector[i].ConnectorType == CONNECTOR_CTV) - if (enable_tv) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX); + } else + info->BiosConnector[i].ConnectorType = object_connector_convert[con_obj_id]; + + if (info->BiosConnector[i].ConnectorType == CONNECTOR_NONE) { + info->BiosConnector[i].valid = FALSE; + continue; + } else + info->BiosConnector[i].valid = TRUE; + info->BiosConnector[i].devices = path->usDeviceTag; + info->BiosConnector[i].connector_object = path->usConnObjectId; + + for (j = 0; j < ((path->usSize - 8) / 2); j++) { + uint8_t enc_obj_id, enc_obj_num, enc_obj_type; + + enc_obj_id = (path->usGraphicObjIds[j] & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; + enc_obj_num = (path->usGraphicObjIds[j] & ENUM_ID_MASK) >> ENUM_ID_SHIFT; + enc_obj_type = (path->usGraphicObjIds[j] & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; + + if (enc_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { + if (enc_obj_num == 2) + info->BiosConnector[i].linkb = TRUE; else - info->BiosConnector[i].valid = FALSE; - else - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT1_INDEX); - info->BiosConnector[i].DACType = DAC_PRIMARY; - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - if (info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_A || - info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_B) + info->BiosConnector[i].linkb = FALSE; + + /* dac/tmds type */ + if (path->usDeviceTag != ATOM_DEVICE_LCD1_SUPPORT) { + switch(enc_obj_id) { + case ENCODER_OBJECT_ID_INTERNAL_LVDS: + break; + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + info->BiosConnector[i].TMDSType = TMDS_INT; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + info->BiosConnector[i].TMDSType = TMDS_UNIPHY; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + info->BiosConnector[i].TMDSType = TMDS_UNIPHY1; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + info->BiosConnector[i].TMDSType = TMDS_UNIPHY2; + break; + case ENCODER_OBJECT_ID_INTERNAL_TMDS2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: + info->BiosConnector[i].TMDSType = TMDS_EXT; + break; + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + info->BiosConnector[i].TMDSType = TMDS_LVTMA; + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC1: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: + info->BiosConnector[i].DACType = DAC_PRIMARY; + break; + case ENCODER_OBJECT_ID_INTERNAL_DAC2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: + info->BiosConnector[i].DACType = DAC_TVDAC; + break; + } + } break; - if (info->BiosConnector[i].ConnectorType == CONNECTOR_DIN || - info->BiosConnector[i].ConnectorType == CONNECTOR_STV || - info->BiosConnector[i].ConnectorType == CONNECTOR_CTV) - if (enable_tv) - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX); - else - info->BiosConnector[i].valid = FALSE; - else - info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT2_INDEX); - info->BiosConnector[i].DACType = DAC_TVDAC; - break; + } } - } - - Record = (ATOM_COMMON_RECORD_HEADER *) - ((char *)&atomDataPtr->Object_Header->sHeader - + le16_to_cpu(con_obj->asObjects[i].usRecordOffset)); - - record_base = le16_to_cpu(con_obj->asObjects[i].usRecordOffset); - - while (Record->ucRecordType > 0 - && Record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER ) { - ErrorF("record type %d\n", Record->ucRecordType); - switch (Record->ucRecordType) { - case ATOM_I2C_RECORD_TYPE: - info->BiosConnector[i].ddc_i2c = rhdAtomParseI2CRecord(pScrn, info->atomBIOS, - (ATOM_I2C_RECORD *)Record, i); - break; - case ATOM_HPD_INT_RECORD_TYPE: - break; - case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE: - break; + /* look up gpio for ddc */ + if ((path->usDeviceTag & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) { + for (j = 0; j < con_obj->ucNumberOfObjects; j++) { + if (path->usConnObjectId == le16_to_cpu(con_obj->asObjects[j].usObjectID)) { + ATOM_COMMON_RECORD_HEADER *Record = (ATOM_COMMON_RECORD_HEADER *) + ((char *)&atomDataPtr->Object_Header->sHeader + + le16_to_cpu(con_obj->asObjects[j].usRecordOffset)); + + while (Record->ucRecordType > 0 + && Record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER ) { + + /*ErrorF("record type %d\n", Record->ucRecordType);*/ + switch (Record->ucRecordType) { + case ATOM_I2C_RECORD_TYPE: + info->BiosConnector[i].ddc_i2c = + rhdAtomParseI2CRecord(pScrn, info->atomBIOS, + (ATOM_I2C_RECORD *)Record, j); + break; + case ATOM_HPD_INT_RECORD_TYPE: + break; + case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE: + break; + } + + Record = (ATOM_COMMON_RECORD_HEADER*) + ((char *)Record + Record->ucRecordSize); + } + break; + } + } } - - Record = (ATOM_COMMON_RECORD_HEADER*) - ((char *)Record + Record->ucRecordSize); } - RADEONApplyATOMQuirks(pScrn, i); } for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { if (info->BiosConnector[i].valid) { + /* shared ddc */ for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) { if (info->BiosConnector[j].valid && (i != j) ) { if (info->BiosConnector[i].i2c_line_mux == info->BiosConnector[j].i2c_line_mux) { @@ -1778,6 +1752,19 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn) } } } + /* shared connectors */ + for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) { + if (info->BiosConnector[j].valid && (i != j) ) { + if (info->BiosConnector[i].connector_object == info->BiosConnector[j].connector_object) { + if (info->BiosConnector[i].devices & (ATOM_DEVICE_CRT_SUPPORT)) + info->BiosConnector[i].TMDSType = info->BiosConnector[j].TMDSType; + else + info->BiosConnector[i].DACType = info->BiosConnector[j].DACType; + info->BiosConnector[i].devices |= info->BiosConnector[j].devices; + info->BiosConnector[j].valid = FALSE; + } + } + } } } diff --git a/src/radeon_output.c b/src/radeon_output.c index 5924c814..4aa99d64 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -2858,6 +2858,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) radeon_output->igp_lane_info = info->BiosConnector[i].igp_lane_info; radeon_output->shared_ddc = info->BiosConnector[i].shared_ddc; radeon_output->load_detection = info->BiosConnector[i].load_detection; + radeon_output->linkb = info->BiosConnector[i].linkb; if (radeon_output->ConnectorType == CONNECTOR_DVI_D) radeon_output->DACType = DAC_NONE; diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 5cd610cc..1886b4e6 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -210,6 +210,8 @@ typedef struct { Bool shared_ddc; int i2c_line_mux; Bool load_detection; + Bool linkb; + uint16_t connector_object; } RADEONBIOSConnector; typedef struct _RADEONOutputPrivateRec { @@ -264,6 +266,7 @@ typedef struct _RADEONOutputPrivateRec { int transmitter_config; Bool coherent_mode; int igp_lane_info; + Bool linkb; char *name; int output_id; |