summaryrefslogtreecommitdiff
path: root/src/radeon_atombios.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-01-06 14:55:49 -0500
committerAlex Deucher <alexdeucher@gmail.com>2009-01-06 14:55:49 -0500
commit690999b682c0f954e27d9f1b3a3d8db4ef865c21 (patch)
treeb52b54c11d4a6dfdefa305181173b0b167ccd8e3 /src/radeon_atombios.c
parente23baa2fa8b25b68cd473aec7a3d8cf3ee7b0ea8 (diff)
ATOM: rework object table parsing
Diffstat (limited to 'src/radeon_atombios.c')
-rw-r--r--src/radeon_atombios.c305
1 files changed, 146 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;
+ }
+ }
+ }
}
}