diff --git a/atombios.h b/atombios.h index 9932b09..1f7fe14 100644 --- a/atombios.h +++ b/atombios.h @@ -2795,7 +2795,7 @@ typedef struct _ATOM_COMMON_RECORD_HEADER #define ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE 15 //Must be updated when new record type is added,equal to that record definition! -#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_CONNECTOR_CF_RECORD_TYPE +#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE typedef struct _ATOM_I2C_RECORD { diff --git a/atombios_tables.c b/atombios_tables.c index f87aba7..09c1309 100644 --- a/atombios_tables.c +++ b/atombios_tables.c @@ -62,6 +62,17 @@ char *connector_names[] = { "NONE", "DISPLAYPORT", }; +char *object_type_names[] = { "NONE", + "GPU", + "ENCODER", + "CONNECTOR", + "ROUTER", +}; + +char *router_object_names[] = { "NONE", + "I2C_EXTENDER_CNTL", +}; + void radeon_lookup_gpio(struct atom_context *ctx, uint8_t id) { ATOM_GPIO_I2C_ASSIGMENT gpio; @@ -75,7 +86,90 @@ void radeon_lookup_gpio(struct atom_context *ctx, uint8_t id) gpio = i2c_info->asGPIO_Info[id]; - printf("GPIO %d: %04x\n", id, gpio.usClkMaskRegisterIndex *4); + printf(" GPIO %d: %04x\n", id, gpio.usClkMaskRegisterIndex *4); +} + +static void radeon_print_object(uint16_t obj) +{ + uint8_t obj_id, num, obj_type; + + obj_id = (obj & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; + num = (obj & ENUM_ID_MASK) >> ENUM_ID_SHIFT; + obj_type = (obj & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; + + if (obj_type == GRAPH_OBJECT_TYPE_CONNECTOR) + printf("%s, %d, %s (0x%04x)\n", + object_type_names[obj_type], num, connector_names[obj_id], obj); + else if (obj_type == GRAPH_OBJECT_TYPE_ENCODER) + printf("%s, %d, %s (0x%04x)\n", + object_type_names[obj_type], num, object_names[obj_id], obj); + else if (obj_type == GRAPH_OBJECT_TYPE_ROUTER) + printf("%s, %d, %s (0x%04x)\n", + object_type_names[obj_type], num, router_object_names[obj_id], obj); + else + printf("%s, %d, 0x%02x (0x%04x)\n", + object_type_names[obj_type], num, obj_id, obj); + +} + +static void radeon_print_supported_devices(uint16_t sd) +{ + if (sd & ATOM_DEVICE_CRT1_SUPPORT) + printf("CRT1 "); + if (sd & ATOM_DEVICE_LCD1_SUPPORT) + printf("LCD1 "); + if (sd & ATOM_DEVICE_TV1_SUPPORT) + printf("TV1 "); + if (sd & ATOM_DEVICE_DFP1_SUPPORT) + printf("DFP1 "); + if (sd & ATOM_DEVICE_CRT2_SUPPORT) + printf("CRT2 "); + if (sd & ATOM_DEVICE_LCD2_SUPPORT) + printf("LCD2 "); + if (sd & ATOM_DEVICE_TV2_SUPPORT) + printf("TV2 "); + if (sd & ATOM_DEVICE_DFP2_SUPPORT) + printf("DFP2 "); + if (sd & ATOM_DEVICE_CV_SUPPORT) + printf("CV "); + if (sd & ATOM_DEVICE_DFP3_SUPPORT) + printf("DFP3 "); + if (sd & ATOM_DEVICE_DFP4_SUPPORT) + printf("DFP4 "); + if (sd & ATOM_DEVICE_DFP5_SUPPORT) + printf("DFP5 "); +} + +static void radeon_dump_bios_igp_slot_config(struct atom_context *ctx, uint16_t obj) +{ + uint16_t size, data_offset; + uint8_t frev, crev; + int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); + ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj = NULL; + uint8_t obj_id, num, obj_type; + + obj_id = (obj & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; + num = (obj & ENUM_ID_MASK) >> ENUM_ID_SHIFT; + obj_type = (obj & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; + + if (obj_id == CONNECTOR_OBJECT_ID_PCIE_CONNECTOR) { + uint32_t slot_config, ct; + + atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); + + igp_obj = (ATOM_INTEGRATED_SYSTEM_INFO_V2 *)(ctx->bios + data_offset); + + if (igp_obj) { + if (num == 1) + slot_config = igp_obj->ulDDISlot1Config; + else + slot_config = igp_obj->ulDDISlot2Config; + + ct = (slot_config >> 16) & 0xff; + printf("\tConnector: %s\n", connector_names[ct]); + printf("\tLane Config: 0x%04x\n", slot_config & 0xffff); + } + } } void radeon_dump_bios_object_table(struct atom_context *ctx) @@ -84,9 +178,12 @@ void radeon_dump_bios_object_table(struct atom_context *ctx) uint8_t frev, crev; int index = GetIndexIntoMasterTable(DATA, Object_Header); ATOM_CONNECTOR_OBJECT_TABLE *con_obj; + ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; + ATOM_ENCODER_OBJECT_TABLE *enc_obj; + ATOM_OBJECT_TABLE *router_obj; ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj = NULL; ATOM_OBJECT_HEADER *obj_header; - int i, j; + int i, j, k, path_size; atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); @@ -95,59 +192,216 @@ void radeon_dump_bios_object_table(struct atom_context *ctx) obj_header = (ATOM_OBJECT_HEADER *)(ctx->bios + data_offset); - con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)(ctx->bios + data_offset + obj_header->usConnectorObjectTableOffset); + printf("\nSupported Devices: "); + radeon_print_supported_devices(obj_header->usDeviceSupport); + printf("\n"); - printf("Num of objects %d\n", con_obj->ucNumberOfObjects); - - for (i = 0; i < con_obj->ucNumberOfObjects; i++) { - ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *src_dst_table; - 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; - - printf("object id %04x %02x %s\n", obj_id, src_dst_table->ucNumberOfSrc, connector_names[obj_id]); - src_dst_table = (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) - (ctx->bios + data_offset + le16_to_cpu(con_obj->asObjects[i].usSrcDstTableOffset)); - - for (j = 0; j < src_dst_table->ucNumberOfSrc; j++) { - uint8_t sobj_id; - sobj_id = (src_dst_table->usSrcObjectID[j] & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - printf("src object id %04x 0x%02x %s\n", src_dst_table->usSrcObjectID[j], sobj_id, object_names[sobj_id]); - } + path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)(ctx->bios + data_offset + obj_header->usDisplayPathTableOffset); + con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)(ctx->bios + data_offset + obj_header->usConnectorObjectTableOffset); + enc_obj = (ATOM_ENCODER_OBJECT_TABLE *)(ctx->bios + data_offset + obj_header->usEncoderObjectTableOffset); + router_obj = (ATOM_OBJECT_TABLE *)(ctx->bios + data_offset + obj_header->usRouterObjectTableOffset); + + 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; + + if (obj_header->usDeviceSupport & path->usDeviceTag) { + printf("\nDevice: "); + radeon_print_supported_devices(path->usDeviceTag); + printf("\n"); + // connector object + printf("==== Connector Info ====\n"); + radeon_print_object(path->usConnObjectId); + for (j = 0; j < con_obj->ucNumberOfObjects; j++) { + ATOM_COMMON_RECORD_HEADER *record; + int record_base; + uint16_t con_obj_id = le16_to_cpu(con_obj->asObjects[j].usObjectID); + + if (path->usConnObjectId == con_obj_id) { + record = (ATOM_COMMON_RECORD_HEADER *) + (ctx->bios + data_offset + le16_to_cpu(con_obj->asObjects[j].usRecordOffset)); + record_base = le16_to_cpu(con_obj->asObjects[j].usRecordOffset); + + while (record->ucRecordType > 0 && + record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { + //printf("record type %d\n", record->ucRecordType); + + switch(record->ucRecordType) { + case ATOM_I2C_RECORD_TYPE: + { + ATOM_I2C_RECORD *i2c_record = (ATOM_I2C_RECORD *)record; + printf(" ATOM_I2C_RECORD_TYPE\n"); + printf(" i2c mux:%d engine:%d hw_cap:%d\n", + i2c_record->sucI2cId.bfI2C_LineMux, + i2c_record->sucI2cId.bfHW_EngineID, + i2c_record->sucI2cId.bfHW_Capable); + radeon_lookup_gpio(ctx, i2c_record->sucI2cId.bfI2C_LineMux); + } + break; + case ATOM_HPD_INT_RECORD_TYPE: + { + ATOM_HPD_INT_RECORD *hdp = (ATOM_HPD_INT_RECORD *)record; + printf(" ATOM_HPD_INT_RECORD_TYPE\n"); + printf(" gpioid: %d, plugged pin state: 0x%x\n", + hdp->ucHPDIntGPIOID, hdp->ucPluggged_PinState); + } + break; + case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE: + { + ATOM_CONNECTOR_DEVICE_TAG_RECORD *dev_tag_rec = + (ATOM_CONNECTOR_DEVICE_TAG_RECORD *)record; + printf(" ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE\n"); + printf(" Devices: "); + for (k = 0; k < dev_tag_rec->ucNumberOfDevice; k++) { + ATOM_CONNECTOR_DEVICE_TAG *dev_tag = + &dev_tag_rec->asDeviceTag[k]; + radeon_print_supported_devices(dev_tag->usDeviceID); + } + printk("\n"); + } + break; + case ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD_TYPE: + { + ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD *cvtv = + (ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD *)record; + printf(" ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD_TYPE\n"); + printf(" gpioid: %d, tv active state: %d\n", + cvtv->ucGPIOID, cvtv->ucTVActiveState); + } + break; + case ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE: + { + ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD *pcie = + (ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD *)record; + printf(" ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE\n"); + printf(" %s\n", connector_names[pcie->ucSubConnectorType]); + } + break; + case ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE: + printf(" ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE\n"); + break; + case ATOM_CONNECTOR_CF_RECORD_TYPE: + printf(" ATOM_CONNECTOR_CF_RECORD_TYPE\n"); + break; - record = (ATOM_COMMON_RECORD_HEADER *) - (ctx->bios + data_offset + 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) { - printf("record type %d\n", record->ucRecordType); - - switch(record->ucRecordType) { - case ATOM_I2C_RECORD_TYPE: - { - ATOM_I2C_RECORD *i2c_record = (ATOM_I2C_RECORD *)record; - printf("i2c mux:%d engine:%d hw_cap:%d\n", - i2c_record->sucI2cId.bfI2C_LineMux, - i2c_record->sucI2cId.bfHW_EngineID, - i2c_record->sucI2cId.bfHW_Capable); - radeon_lookup_gpio(ctx, i2c_record->sucI2cId.bfI2C_LineMux); + } + record = (ATOM_COMMON_RECORD_HEADER *)((char *)record + record->ucRecordSize); } break; - case ATOM_HPD_INT_RECORD_TYPE: - break; - case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE: + } + } + radeon_dump_bios_igp_slot_config(ctx, path->usConnObjectId); + printf("==== GPU Info ====\n"); + radeon_print_object(path->usGPUObjectId); + printf("==== Encoder info ====\n"); + for (k = 0; k < ((path->usSize - 8) / 2); k++) { + uint8_t obj_type = (path->usGraphicObjIds[k] & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; + + if (obj_type == GRAPH_OBJECT_TYPE_ENCODER) { + radeon_print_object(path->usGraphicObjIds[k]); + for (j = 0; j < enc_obj->ucNumberOfObjects; j++) { + ATOM_COMMON_RECORD_HEADER *record; + int record_base; + uint16_t enc_obj_id = le16_to_cpu(enc_obj->asObjects[j].usObjectID); + + if (path->usGraphicObjIds[k] == enc_obj_id) { + record = (ATOM_COMMON_RECORD_HEADER *) + (ctx->bios + data_offset + le16_to_cpu(enc_obj->asObjects[j].usRecordOffset)); + record_base = le16_to_cpu(enc_obj->asObjects[j].usRecordOffset); + + while (record->ucRecordType > 0 && + record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { + //printf("record type %d\n", record->ucRecordType); + + switch(record->ucRecordType) { + case ATOM_ENCODER_FPGA_CONTROL_RECORD_TYPE: + printf(" ATOM_ENCODER_FPGA_CONTROL_RECORD_TYPE\n"); + break; + case ATOM_ENCODER_DVO_CF_RECORD_TYPE: + printf(" ATOM_ENCODER_DVO_CF_RECORD_TYPE\n"); + break; + case ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE: + printf(" ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE\n"); + break; + } + record = (ATOM_COMMON_RECORD_HEADER *)((char *)record + record->ucRecordSize); + } break; + } } - record = (ATOM_COMMON_RECORD_HEADER *)((char *)record + record->ucRecordSize); + } } + printf("==== Router Info ====\n"); + for (k = 0; k < ((path->usSize - 8) / 2); k++) { + uint8_t obj_type = (path->usGraphicObjIds[k] & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; + + if (obj_type == GRAPH_OBJECT_TYPE_ROUTER) { + radeon_print_object(path->usGraphicObjIds[k]); + for (j = 0; j < router_obj->ucNumberOfObjects; j++) { + ATOM_COMMON_RECORD_HEADER *record; + int record_base; + uint16_t router_obj_id = le16_to_cpu(router_obj->asObjects[j].usObjectID); + + if (path->usGraphicObjIds[k] == router_obj_id) { + record = (ATOM_COMMON_RECORD_HEADER *) + (ctx->bios + data_offset + le16_to_cpu(router_obj->asObjects[j].usRecordOffset)); + record_base = le16_to_cpu(router_obj->asObjects[j].usRecordOffset); + + while (record->ucRecordType > 0 && + record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { + //printf("record type %d\n", record->ucRecordType); + + switch(record->ucRecordType) { + case ATOM_I2C_RECORD_TYPE: + { + ATOM_I2C_RECORD *i2c_record = (ATOM_I2C_RECORD *)record; + printf(" ATOM_I2C_RECORD_TYPE\n"); + printf(" i2c mux:%d engine:%d hw_cap:%d\n", + i2c_record->sucI2cId.bfI2C_LineMux, + i2c_record->sucI2cId.bfHW_EngineID, + i2c_record->sucI2cId.bfHW_Capable); + radeon_lookup_gpio(ctx, i2c_record->sucI2cId.bfI2C_LineMux); + } + break; + case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE: + { + ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path = + (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *)record; + printf(" ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE\n"); + printf(" mux type: %d, mux cntl pin: %d, mux state: %d\n", + ddc_path->ucMuxType, + ddc_path->ucMuxControlPin, + ddc_path->ucMuxState[0]); + } + break; + case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE: + { + ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *clk_data_path = + (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *)record; + printf(" ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE\n"); + printf(" mux type: %d, mux cntl pin: %d, mux state: %d\n", + clk_data_path->ucMuxType, + clk_data_path->ucMuxControlPin, + clk_data_path->ucMuxState[0]); + } + break; + case ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE: + printf(" ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE\n"); + break; + } + record = (ATOM_COMMON_RECORD_HEADER *)((char *)record + record->ucRecordSize); + } + break; + } + } + } + } + } + path_size += path->usSize; } } @@ -260,7 +514,7 @@ struct atom_context *atom_init(void *bios) ctx = atom_parse(&my_card_info, bios); - atom_asic_init(ctx); + //atom_asic_init(ctx); return ctx; } @@ -271,8 +525,8 @@ void atom_dump(struct atom_context *ctx) radeon_dump_bios_object_table(ctx); - dump_vram_table(ctx); + //dump_vram_table(ctx); - radeon_execute_aux_channel_table(ctx); + //radeon_execute_aux_channel_table(ctx); } diff --git a/radeontool.c b/radeontool.c index 0ee80b5..7db461d 100644 --- a/radeontool.c +++ b/radeontool.c @@ -947,8 +947,8 @@ static void radeon_rom_legacy_clocks(unsigned char *bios, int hdr) printf("revision %d\n", rev); printf("Clock info block:\n"); - printf(" SCLK : %f\n", BIOS16(pll_info_block + 0x08) / 100.0); - printf(" MCLK : %f\n", BIOS16(pll_info_block + 0x0a) / 100.0); + printf(" SCLK : %f\n", BIOS16(pll_info_block + 0x0a) / 100.0); + printf(" MCLK : %f\n", BIOS16(pll_info_block + 0x08) / 100.0); printf(" RefClk : %f\n", BIOS16(pll_info_block + 0x0e) / 100.0); printf(" RefDiv : %d\n", BIOS16(pll_info_block + 0x10)); printf(" VCO Min: %f\n", BIOS32(pll_info_block + 0x12) / 100.0); @@ -961,6 +961,16 @@ static void radeon_rom_legacy_clocks(unsigned char *bios, int hdr) printf(" VCO out Max: %f\n", BIOS32(pll_info_block + 0x42) / 100.0); } + printf(" SPLL RefClk : %f\n", BIOS16(pll_info_block + 0x1a) / 100.0); + printf(" SPLL ref div : %d\n", BIOS16(pll_info_block + 0x1c)); + printf(" VCO Min: %f\n", BIOS32(pll_info_block + 0x1e) / 100.0); + printf(" VCO Max: %f\n", BIOS32(pll_info_block + 0x22) / 100.0); + + printf(" MPLL RefClk : %f\n", BIOS16(pll_info_block + 0x26) / 100.0); + printf(" MPLL ref div : %d\n", BIOS16(pll_info_block + 0x28)); + printf(" VCO Min: %f\n", BIOS32(pll_info_block + 0x2a) / 100.0); + printf(" VCO Max: %f\n", BIOS32(pll_info_block + 0x2e) / 100.0); + printf("\n"); } @@ -1174,7 +1184,7 @@ static void radeon_rom_atom_connectors(unsigned char *bios, int master) else if (i==7) printf(" TMDS: External\n"); else if (i==9) - printf(" TMDS: External\n"); + printf(" TMDS: LVTMA\n"); else printf("\n");