From a8b357c7477d541c2c6d39fcba245b64cd9107a4 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Thu, 8 Sep 2011 22:11:20 +0000 Subject: [PATCH] * run edid check on all connectors regardless of encoder * correction to output check (B_OK != true) * check for invalid gpio (prevents seg violation) * tab cleanup git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42727 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../accelerants/radeon_hd/accelerant.h | 53 ++++---- src/add-ons/accelerants/radeon_hd/display.cpp | 16 +-- src/add-ons/accelerants/radeon_hd/gpu.cpp | 120 ++++++++++-------- 3 files changed, 98 insertions(+), 91 deletions(-) diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.h b/src/add-ons/accelerants/radeon_hd/accelerant.h index 0cfd541149..ff4908744d 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.h +++ b/src/add-ons/accelerants/radeon_hd/accelerant.h @@ -139,40 +139,41 @@ struct pll_info { struct ddc_info { - uint8 gpio_id; + bool valid; + uint8 gpio_id; - uint16 mask_scl_reg; - uint16 mask_sda_reg; - uint16 mask_scl_shift; - uint16 mask_sda_shift; + uint16 mask_scl_reg; + uint16 mask_sda_reg; + uint16 mask_scl_shift; + uint16 mask_sda_shift; - uint16 gpio_en_scl_reg; - uint16 gpio_en_sda_reg; - uint16 gpio_en_scl_shift; - uint16 gpio_en_sda_shift; + uint16 gpio_en_scl_reg; + uint16 gpio_en_sda_reg; + uint16 gpio_en_scl_shift; + uint16 gpio_en_sda_shift; - uint16 gpio_y_scl_reg; - uint16 gpio_y_sda_reg; - uint16 gpio_y_scl_shift; - uint16 gpio_y_sda_shift; + uint16 gpio_y_scl_reg; + uint16 gpio_y_sda_reg; + uint16 gpio_y_scl_shift; + uint16 gpio_y_sda_shift; - uint16 gpio_a_scl_reg; - uint16 gpio_a_sda_reg; - uint16 gpio_a_scl_shift; - uint16 gpio_a_sda_shift; + uint16 gpio_a_scl_reg; + uint16 gpio_a_sda_reg; + uint16 gpio_a_scl_shift; + uint16 gpio_a_sda_shift; }; typedef struct { - bool valid; - uint16 line_mux; - uint16 connector_flags; - uint32 connector_type; - uint16 connector_object_id; - uint32 encoder_type; - uint16 encoder_object_id; - ddc_info connector_ddc_info; - i2c_bus connector_i2c; + bool valid; + uint16 line_mux; + uint16 connector_flags; + uint32 connector_type; + uint16 connector_object_id; + uint32 encoder_type; + uint16 encoder_object_id; + ddc_info connector_ddc_info; + i2c_bus connector_i2c; // TODO struct radeon_hpd hpd; } connector_info; diff --git a/src/add-ons/accelerants/radeon_hd/display.cpp b/src/add-ons/accelerants/radeon_hd/display.cpp index 04b81cc8e8..7d12624c1d 100644 --- a/src/add-ons/accelerants/radeon_hd/display.cpp +++ b/src/add-ons/accelerants/radeon_hd/display.cpp @@ -433,8 +433,8 @@ detect_connectors() = (B_LENDIAN_TO_HOST_INT16(path->usGraphicObjIds[j]) & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { + // Found an encoder int32 k; - TRACE("%s: Found encoder at #%" B_PRIu32 "\n", __func__, j); for (k = 0; k < enc_obj->ucNumberOfObjects; k++) { uint16 encoder_obj = B_LENDIAN_TO_HOST_INT16( @@ -533,7 +533,7 @@ detect_connectors() } } } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) { - ERROR("%s: TODO : Router object?\n", __func__); + ERROR("%s: TODO : Found router object?\n", __func__); } } @@ -630,20 +630,12 @@ detect_displays() if (displayIndex >= MAX_DISPLAY) continue; - bool found = false; - switch(gConnector[id]->encoder_type) { - case VIDEO_ENCODER_DAC: - found = radeon_gpu_read_edid(id, gDisplay[id]->edid_info); - break; - default: - found = false; - } - - if (found == true) { + if (radeon_gpu_read_edid(id, gDisplay[displayIndex]->edid_info)) { gDisplay[displayIndex]->active = true; // set this display as active gDisplay[displayIndex]->connector_index = id; // set physical connector index from gConnector + init_registers(gDisplay[displayIndex]->regs, displayIndex); if (detect_crt_ranges(displayIndex) == B_OK) diff --git a/src/add-ons/accelerants/radeon_hd/gpu.cpp b/src/add-ons/accelerants/radeon_hd/gpu.cpp index 15ad1df394..74769d012c 100644 --- a/src/add-ons/accelerants/radeon_hd/gpu.cpp +++ b/src/add-ons/accelerants/radeon_hd/gpu.cpp @@ -10,6 +10,7 @@ #include "accelerant_protos.h" #include "accelerant.h" +#include "bios.h" #include "gpu.h" #include "utility.h" @@ -286,6 +287,9 @@ get_i2c_signals(void* cookie, int* _clock, int* _data) *_clock = (value >> info->gpio_y_scl_shift) & 1; *_data = (value >> info->gpio_y_sda_shift) & 1; + TRACE("%s: GPIO 0x%" B_PRIX8 ", clock: %d, data: %d\n", + __func__, info->gpio_id, *_clock, *_data); + return B_OK; } @@ -304,6 +308,9 @@ set_i2c_signals(void* cookie, int clock, int data) Write32(OUT, info->gpio_id, value); + TRACE("%s: GPIO 0x%" B_PRIX8 ", clock: %d, data: %d\n", + __func__, info->gpio_id, clock, data); + return B_OK; } @@ -311,6 +318,11 @@ set_i2c_signals(void* cookie, int clock, int data) bool radeon_gpu_read_edid(uint32 connector, edid1_info *edid) { + // ensure things are sane + if (gConnector[connector]->connector_ddc_info.valid == false + || gConnector[connector]->connector_ddc_info.gpio_id == 0) + return false; + i2c_bus bus; ddc2_init_timing(&bus); @@ -339,74 +351,76 @@ radeon_gpu_i2c_setup(uint32 connector, uint8 gpio_id) TRACE("%s: Path #%" B_PRId32 ": GPIO Pin 0x%" B_PRIx8 "\n", __func__, connector, gpio_id); - ATOM_GPIO_I2C_ASSIGMENT *gpio; - struct _ATOM_GPIO_I2C_INFO *i2c_info; int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); + uint8 frev; + uint8 crev; uint16 offset; uint16 size; - if (atom_parse_data_header(gAtomContext, index, - &size, NULL, NULL, &offset)) { + if (atom_parse_data_header(gAtomContext, index, &size, &frev, &crev, + &offset) != B_OK) { + ERROR("%s: GPIO pin not within AtomBIOS!\n", __func__); + gConnector[connector]->connector_ddc_info.valid = false; + return B_ERROR; + } - i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(gAtomContext->bios + offset); + struct _ATOM_GPIO_I2C_INFO *i2c_info + = (struct _ATOM_GPIO_I2C_INFO *)(gAtomContext->bios + offset); - uint32 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) - / sizeof(ATOM_GPIO_I2C_ASSIGMENT); + uint32 num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) + / sizeof(ATOM_GPIO_I2C_ASSIGMENT); - for (uint32 i = 0; i < num_indices; i++) { - gpio = &i2c_info->asGPIO_Info[i]; + for (uint32 i = 0; i < num_indices; i++) { + ATOM_GPIO_I2C_ASSIGMENT *gpio = &i2c_info->asGPIO_Info[i]; - // TODO : if DCE 4 and i == 7 ... manual override for evergreen - // TODO : if DCE 3 and i == 4 ... manual override + // TODO : if DCE 4 and i == 7 ... manual override for evergreen + // TODO : if DCE 3 and i == 4 ... manual override - if (gpio->sucI2cId.ucAccess != gpio_id) - continue; + if (gpio->sucI2cId.ucAccess != gpio_id) + continue; - // successful lookup - TRACE("%s: found i2c gpio\n", __func__); + // successful lookup + TRACE("%s: successful AtomBIOS GPIO lookup\n", __func__); + // populate gpio information + gConnector[connector]->connector_ddc_info.valid = true; + gConnector[connector]->connector_ddc_info.gpio_id = gpio_id; - // populate gpio information - gConnector[connector]->connector_ddc_info.gpio_id = gpio_id; + gConnector[connector]->connector_ddc_info.mask_scl_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usClkMaskRegisterIndex) * 4; + gConnector[connector]->connector_ddc_info.mask_sda_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usDataMaskRegisterIndex) * 4; + gConnector[connector]->connector_ddc_info.mask_scl_shift + = (1 << gpio->ucClkMaskShift); + gConnector[connector]->connector_ddc_info.mask_sda_shift + = (1 << gpio->ucDataMaskShift); - gConnector[connector]->connector_ddc_info.mask_scl_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usClkMaskRegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.mask_sda_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usDataMaskRegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.mask_scl_shift - = (1 << gpio->ucClkMaskShift); - gConnector[connector]->connector_ddc_info.mask_sda_shift - = (1 << gpio->ucDataMaskShift); - - gConnector[connector]->connector_ddc_info.gpio_en_scl_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usClkEnRegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_en_sda_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usDataEnRegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_en_scl_shift - = (1 << gpio->ucClkEnShift); - gConnector[connector]->connector_ddc_info.gpio_en_sda_shift - = (1 << gpio->ucDataEnShift); - - gConnector[connector]->connector_ddc_info.gpio_y_scl_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usClkY_RegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_y_sda_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usDataY_RegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_y_scl_shift - = (1 << gpio->ucClkY_Shift); - gConnector[connector]->connector_ddc_info.gpio_y_sda_shift - = (1 << gpio->ucDataY_Shift); - - gConnector[connector]->connector_ddc_info.gpio_a_scl_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usClkA_RegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_a_sda_reg - = B_LENDIAN_TO_HOST_INT16(gpio->usDataA_RegisterIndex) * 4; - gConnector[connector]->connector_ddc_info.gpio_a_scl_shift - = (1 << gpio->ucClkA_Shift); - gConnector[connector]->connector_ddc_info.gpio_a_sda_shift - = (1 << gpio->ucDataA_Shift); - } + gConnector[connector]->connector_ddc_info.gpio_en_scl_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usClkEnRegisterIndex) * 4; + gConnector[connector]->connector_ddc_info.gpio_en_sda_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usDataEnRegisterIndex) * 4; + gConnector[connector]->connector_ddc_info.gpio_en_scl_shift + = (1 << gpio->ucClkEnShift); + gConnector[connector]->connector_ddc_info.gpio_en_sda_shift + = (1 << gpio->ucDataEnShift); + gConnector[connector]->connector_ddc_info.gpio_y_scl_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usClkY_RegisterIndex) * 4; + gConnector[connector]->connector_ddc_info.gpio_y_sda_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usDataY_RegisterIndex) * 4; + gConnector[connector]->connector_ddc_info.gpio_y_scl_shift + = (1 << gpio->ucClkY_Shift); + gConnector[connector]->connector_ddc_info.gpio_y_sda_shift + = (1 << gpio->ucDataY_Shift); + gConnector[connector]->connector_ddc_info.gpio_a_scl_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usClkA_RegisterIndex) * 4; + gConnector[connector]->connector_ddc_info.gpio_a_sda_reg + = B_LENDIAN_TO_HOST_INT16(gpio->usDataA_RegisterIndex) * 4; + gConnector[connector]->connector_ddc_info.gpio_a_scl_shift + = (1 << gpio->ucClkA_Shift); + gConnector[connector]->connector_ddc_info.gpio_a_sda_shift + = (1 << gpio->ucDataA_Shift); } return B_OK;