summaryrefslogtreecommitdiff
path: root/src/radeon_atombios.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2007-11-23 11:55:05 +1000
committerDave Airlie <airlied@redhat.com>2007-11-23 11:55:05 +1000
commitdbf6eae7e7a4bd1bc60fefdc7ab6276ed3f097c4 (patch)
treebd1865f92dfc35c73136d34a5d4f769bb30256b0 /src/radeon_atombios.c
parent6b103915c11fc79d2efc43c44fc2a00c3bc64ede (diff)
atombios: add initial object header parsing for r600 cards
Diffstat (limited to 'src/radeon_atombios.c')
-rw-r--r--src/radeon_atombios.c154
1 files changed, 153 insertions, 1 deletions
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 46ceea85..8cac15d8 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -565,7 +565,7 @@ rhdAtomInit(atomBiosHandlePtr unused1, AtomBiosRequestID unused2,
if (!(BIOSImageSize = RHDReadPCIBios(info, &ptr)))
return ATOM_FAILED;
} else*/ {
- int read_len;
+ int read_len;
unsigned char tmp[32];
xf86DrvMsg(scrnIndex,X_INFO,"Getting BIOS copy from legacy VBIOS location\n");
if (xf86ReadBIOS(legacyBIOSLocation, 0, tmp, 32) < 0) {
@@ -1270,6 +1270,158 @@ rhdAtomFirmwareInfoQuery(atomBiosHandlePtr handle,
return ATOM_SUCCESS;
}
+const int object_connector_convert[] =
+ { CONNECTOR_NONE,
+ CONNECTOR_DVI_I,
+ CONNECTOR_DVI_I,
+ CONNECTOR_DVI_D,
+ CONNECTOR_DVI_D,
+ CONNECTOR_VGA,
+ CONNECTOR_CTV,
+ CONNECTOR_STV,
+ CONNECTOR_NONE,
+ CONNECTOR_DIN,
+ CONNECTOR_SCART,
+ CONNECTOR_HDMI_TYPE_A,
+ CONNECTOR_HDMI_TYPE_B,
+ CONNECTOR_HDMI_TYPE_B,
+ CONNECTOR_LVDS,
+ CONNECTOR_DIN,
+ CONNECTOR_NONE,
+ CONNECTOR_NONE,
+ CONNECTOR_NONE,
+ CONNECTOR_NONE,
+ };
+
+static void
+rhdAtomParseI2CRecord(atomBiosHandlePtr handle,
+ ATOM_I2C_RECORD *Record, CARD32 *ddc_line)
+{
+ ErrorF(" %s: I2C Record: %s[%x] EngineID: %x I2CAddr: %x\n",
+ __func__,
+ Record->sucI2cId.bfHW_Capable ? "HW_Line" : "GPIO_ID",
+ Record->sucI2cId.bfI2C_LineMux,
+ Record->sucI2cId.bfHW_EngineID,
+ Record->ucI2CAddr);
+
+ if (!*(unsigned char *)&(Record->sucI2cId))
+ *ddc_line = 0;
+ else {
+
+ if (Record->ucI2CAddr != 0)
+ return;
+
+ if (Record->sucI2cId.bfHW_Capable) {
+ switch(Record->sucI2cId.bfI2C_LineMux) {
+ case 0: *ddc_line = 0x7e40; break;
+ case 1: *ddc_line = 0x7e50; break;
+ case 2: *ddc_line = 0x7e30; break;
+ default: break;
+ }
+ return;
+
+ } else {
+ /* add GPIO pin parsing */
+ }
+ }
+}
+
+Bool RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ int ret;
+ CARD8 crev, frev;
+ unsigned short size;
+ atomDataTablesPtr atomDataPtr;
+ ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
+ int i, j;
+
+ atomDataPtr = info->atomBIOS->atomDataPtr;
+ if (!rhdAtomGetTableRevisionAndSize((ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->Object_Header), &crev, &frev, &size))
+ return FALSE;
+
+ if (crev < 2)
+ return FALSE;
+
+ con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
+ ((char *)&atomDataPtr->Object_Header->sHeader +
+ 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;
+ CARD8 obj_id, num, obj_type;
+ int record_base;
+
+ obj_id = (con_obj->asObjects[i].usObjectID & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+ num = (con_obj->asObjects[i].usObjectID & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+ obj_type = (con_obj->asObjects[i].usObjectID & 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
+ + con_obj->asObjects[i].usSrcDstTableOffset);
+
+ ErrorF("object id %04x %02x\n", obj_id, SrcDstTable->ucNumberOfSrc);
+ info->BiosConnector[i].ConnectorType = object_connector_convert[obj_id];
+ info->BiosConnector[i].valid = TRUE;
+
+ for (j = 0; j < SrcDstTable->ucNumberOfSrc; j++) {
+ CARD8 sobj_id;
+
+ sobj_id = (SrcDstTable->usSrcObjectID[j] & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+ ErrorF("src object id %04x %d\n", SrcDstTable->usSrcObjectID[j], sobj_id);
+
+ switch(sobj_id) {
+ case 2:
+ info->BiosConnector[i].TMDSType = TMDS_INT;
+ break;
+ case 3:
+ case 15:
+ info->BiosConnector[i].TMDSType = TMDS_EXT;
+ break;
+ case 4:
+ case 21:
+ info->BiosConnector[i].DACType = DAC_PRIMARY;
+ break;
+ case 5:
+ case 22:
+ info->BiosConnector[i].DACType = DAC_TVDAC;
+ break;
+ }
+
+ }
+
+ Record = (ATOM_COMMON_RECORD_HEADER *)
+ ((char *)&atomDataPtr->Object_Header->sHeader
+ + con_obj->asObjects[i].usRecordOffset);
+
+ record_base = 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:
+ rhdAtomParseI2CRecord(&info->atomBIOS,
+ (ATOM_I2C_RECORD *)Record,
+ &info->BiosConnector[i].ddc_line);
+ 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);
+ }
+ }
+ return TRUE;
+}
+
#if 0
#define RHD_CONNECTORS_MAX 4
#define MAX_OUTPUTS_PER_CONNECTOR 2