Author: kallisti5 Date: 2011-09-07 01:00:07 +0200 (Wed, 07 Sep 2011) New Revision: 42718 Changeset: https://dev.haiku-os.org/changeset/42718 Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h haiku/trunk/src/add-ons/accelerants/radeon_hd/display.cpp haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.cpp haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.h Log: * add i2c/ddc info storage to connector * add edid info storage to display * pass i2c/ddc information to common i2c code * add code to read/write i2c/ddc * i2c/ddc read/write code works 'in theory', needs tested * detect monitors based on presence of edid on connector Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h 2011-09-06 16:01:33 UTC (rev 42717) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h 2011-09-06 23:00:07 UTC (rev 42718) @@ -138,16 +138,41 @@ }; +struct ddc_info { + uint8 gpio_id; + + 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_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; +}; + + typedef struct { bool valid; uint16 line_mux; uint16 connector_flags; uint32 connector_type; uint16 connector_object_id; - i2c_bus connector_i2c; uint32 encoder_type; uint16 encoder_object_id; - // TODO struct radeon_i2c_bus_rec ddc_bus; + ddc_info connector_ddc_info; + i2c_bus connector_i2c; // TODO struct radeon_hpd hpd; } connector_info; @@ -162,6 +187,7 @@ uint32 hfreq_max; uint32 hfreq_min; pll_info pll; + edid1_info *edid_info; } display_info; Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/display.cpp =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/display.cpp 2011-09-06 16:01:33 UTC (rev 42717) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/display.cpp 2011-09-06 23:00:07 UTC (rev 42718) @@ -564,7 +564,7 @@ = (ATOM_I2C_ID_CONFIG_ACCESS *) &i2c_record->sucI2cId; - // set up i2c bus for connector + // set up i2c gpio information for connector radeon_gpu_i2c_setup(connector_index, i2c_config->ucAccess); break; @@ -633,7 +633,7 @@ bool found = false; switch(gConnector[id]->encoder_type) { case VIDEO_ENCODER_DAC: - found = dac_sense(id); + found = radeon_gpu_read_edid(id, gDisplay[id]->edid_info); break; default: found = false; Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.cpp =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.cpp 2011-09-06 16:01:33 UTC (rev 42717) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.cpp 2011-09-06 23:00:07 UTC (rev 42718) @@ -279,14 +279,13 @@ static status_t get_i2c_signals(void* cookie, int* _clock, int* _data) { - #if 0 - uint32 ioRegister = (uint32)cookie; - uint32 value = read32(ioRegister); + ddc_info *info = (ddc_info*)cookie; - *_clock = (value & I2C_CLOCK_VALUE_IN) != 0; - *_data = (value & I2C_DATA_VALUE_IN) != 0; - #endif + uint32 value = Read32(OUT, info->gpio_id); + *_clock = (value >> info->gpio_y_scl_shift) & 1; + *_data = (value >> info->gpio_y_sda_shift) & 1; + return B_OK; } @@ -294,34 +293,45 @@ static status_t set_i2c_signals(void* cookie, int clock, int data) { - #if 0 - uint32 ioRegister = (uint32)cookie; - uint32 value = read32(OUT, ioRegister) & I2C_RESERVED; + ddc_info* info = (ddc_info*)cookie; - if (data != 0) - value |= I2C_DATA_DIRECTION_MASK; - else { - value |= I2C_DATA_DIRECTION_MASK - | I2C_DATA_DIRECTION_OUT - | I2C_DATA_VALUE_MASK; - } + uint32 value = Read32(OUT, info->gpio_id); - if (clock != 0) - value |= I2C_CLOCK_DIRECTION_MASK; - else - value |= I2C_CLOCK_DIRECTION_MASK - | I2C_CLOCK_DIRECTION_OUT - | I2C_CLOCK_VALUE_MASK; + value &= ~(info->gpio_a_scl_reg | info->gpio_a_sda_reg); + value &= ~(info->gpio_en_sda_reg | info->gpio_en_scl_reg); + value |= ((1 - clock) << info->gpio_en_scl_shift) + | ((1 - data) << info->gpio_en_sda_shift); - write32(OUT, ioRegister, value); - read32(OUT, ioRegister); - // make sure the PCI bus has flushed the write - #endif + Write32(OUT, info->gpio_id, value); return B_OK; } +bool +radeon_gpu_read_edid(uint32 connector, edid1_info *edid) +{ + i2c_bus bus; + + ddc2_init_timing(&bus); + bus.cookie = (void*)&gConnector[connector]->connector_ddc_info; + bus.set_signals = &set_i2c_signals; + bus.get_signals = &get_i2c_signals; + + void *vdif; + size_t vdifLength; + + if (ddc2_read_edid1(&bus, edid, &vdif, &vdifLength) != B_OK) + return false; + + TRACE("%s: found edid monitor on connector #%" B_PRId32 "\n", + __func__, connector); + + free(vdif); + return true; +} + + status_t radeon_gpu_i2c_setup(uint32 connector, uint8 gpio_id) { @@ -349,33 +359,54 @@ // 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) { - i2c_bus bus; + if (gpio->sucI2cId.ucAccess != gpio_id) + continue; - // successful lookup - TRACE("%s: successful i2c gpio lookup\n", __func__); + // successful lookup + TRACE("%s: found i2c gpio\n", __func__); - // pull registers for data and clock... - uint16 analogDataReg - = B_LENDIAN_TO_HOST_INT16(gpio->usDataA_RegisterIndex) * 4; - //uint16 analogClockReg - // = B_LENDIAN_TO_HOST_INT16(gpio->usClkA_RegisterIndex) * 4; - //uint16 digitalDataReg - // = B_LENDIAN_TO_HOST_INT16(gpio->usDataY_RegisterIndex) * 4; - //uint16 digitalClockReg - // = B_LENDIAN_TO_HOST_INT16(gpio->usClkY_RegisterIndex) * 4; - // populate cookie with analog data register - bus.cookie = (void*)analogDataReg; - bus.set_signals = &set_i2c_signals; - bus.get_signals = &get_i2c_signals; + // populate gpio information + gConnector[connector]->connector_ddc_info.gpio_id = gpio_id; - ddc2_init_timing(&bus); - // TODO : check for valid analog edid - // TODO : check for valid digital edid no results on analog - } + 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); } + } return B_OK; Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.h =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.h 2011-09-06 16:01:33 UTC (rev 42717) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.h 2011-09-06 23:00:07 UTC (rev 42718) @@ -168,6 +168,7 @@ uint32 radeon_gpu_mc_idlecheck(); status_t radeon_gpu_mc_setup(); status_t radeon_gpu_irq_setup(); +bool radeon_gpu_read_edid(uint32 connector, edid1_info *edid); status_t radeon_gpu_i2c_setup(uint32 connector, uint8 gpio_id);