* 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 git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42718 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -138,16 +138,41 @@ struct pll_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
typedef struct {
|
||||||
bool valid;
|
bool valid;
|
||||||
uint16 line_mux;
|
uint16 line_mux;
|
||||||
uint16 connector_flags;
|
uint16 connector_flags;
|
||||||
uint32 connector_type;
|
uint32 connector_type;
|
||||||
uint16 connector_object_id;
|
uint16 connector_object_id;
|
||||||
i2c_bus connector_i2c;
|
|
||||||
uint32 encoder_type;
|
uint32 encoder_type;
|
||||||
uint16 encoder_object_id;
|
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;
|
// TODO struct radeon_hpd hpd;
|
||||||
} connector_info;
|
} connector_info;
|
||||||
|
|
||||||
@@ -162,6 +187,7 @@ typedef struct {
|
|||||||
uint32 hfreq_max;
|
uint32 hfreq_max;
|
||||||
uint32 hfreq_min;
|
uint32 hfreq_min;
|
||||||
pll_info pll;
|
pll_info pll;
|
||||||
|
edid1_info *edid_info;
|
||||||
} display_info;
|
} display_info;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -564,7 +564,7 @@ detect_connectors()
|
|||||||
= (ATOM_I2C_ID_CONFIG_ACCESS *)
|
= (ATOM_I2C_ID_CONFIG_ACCESS *)
|
||||||
&i2c_record->sucI2cId;
|
&i2c_record->sucI2cId;
|
||||||
|
|
||||||
// set up i2c bus for connector
|
// set up i2c gpio information for connector
|
||||||
radeon_gpu_i2c_setup(connector_index,
|
radeon_gpu_i2c_setup(connector_index,
|
||||||
i2c_config->ucAccess);
|
i2c_config->ucAccess);
|
||||||
break;
|
break;
|
||||||
@@ -633,7 +633,7 @@ detect_displays()
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
switch(gConnector[id]->encoder_type) {
|
switch(gConnector[id]->encoder_type) {
|
||||||
case VIDEO_ENCODER_DAC:
|
case VIDEO_ENCODER_DAC:
|
||||||
found = dac_sense(id);
|
found = radeon_gpu_read_edid(id, gDisplay[id]->edid_info);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
found = false;
|
found = false;
|
||||||
|
|||||||
@@ -279,13 +279,12 @@ radeon_gpu_irq_setup()
|
|||||||
static status_t
|
static status_t
|
||||||
get_i2c_signals(void* cookie, int* _clock, int* _data)
|
get_i2c_signals(void* cookie, int* _clock, int* _data)
|
||||||
{
|
{
|
||||||
#if 0
|
ddc_info *info = (ddc_info*)cookie;
|
||||||
uint32 ioRegister = (uint32)cookie;
|
|
||||||
uint32 value = read32(ioRegister);
|
|
||||||
|
|
||||||
*_clock = (value & I2C_CLOCK_VALUE_IN) != 0;
|
uint32 value = Read32(OUT, info->gpio_id);
|
||||||
*_data = (value & I2C_DATA_VALUE_IN) != 0;
|
|
||||||
#endif
|
*_clock = (value >> info->gpio_y_scl_shift) & 1;
|
||||||
|
*_data = (value >> info->gpio_y_sda_shift) & 1;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -294,34 +293,45 @@ get_i2c_signals(void* cookie, int* _clock, int* _data)
|
|||||||
static status_t
|
static status_t
|
||||||
set_i2c_signals(void* cookie, int clock, int data)
|
set_i2c_signals(void* cookie, int clock, int data)
|
||||||
{
|
{
|
||||||
#if 0
|
ddc_info* info = (ddc_info*)cookie;
|
||||||
uint32 ioRegister = (uint32)cookie;
|
|
||||||
uint32 value = read32(OUT, ioRegister) & I2C_RESERVED;
|
|
||||||
|
|
||||||
if (data != 0)
|
uint32 value = Read32(OUT, info->gpio_id);
|
||||||
value |= I2C_DATA_DIRECTION_MASK;
|
|
||||||
else {
|
|
||||||
value |= I2C_DATA_DIRECTION_MASK
|
|
||||||
| I2C_DATA_DIRECTION_OUT
|
|
||||||
| I2C_DATA_VALUE_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clock != 0)
|
value &= ~(info->gpio_a_scl_reg | info->gpio_a_sda_reg);
|
||||||
value |= I2C_CLOCK_DIRECTION_MASK;
|
value &= ~(info->gpio_en_sda_reg | info->gpio_en_scl_reg);
|
||||||
else
|
value |= ((1 - clock) << info->gpio_en_scl_shift)
|
||||||
value |= I2C_CLOCK_DIRECTION_MASK
|
| ((1 - data) << info->gpio_en_sda_shift);
|
||||||
| I2C_CLOCK_DIRECTION_OUT
|
|
||||||
| I2C_CLOCK_VALUE_MASK;
|
|
||||||
|
|
||||||
write32(OUT, ioRegister, value);
|
Write32(OUT, info->gpio_id, value);
|
||||||
read32(OUT, ioRegister);
|
|
||||||
// make sure the PCI bus has flushed the write
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return B_OK;
|
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
|
status_t
|
||||||
radeon_gpu_i2c_setup(uint32 connector, uint8 gpio_id)
|
radeon_gpu_i2c_setup(uint32 connector, uint8 gpio_id)
|
||||||
{
|
{
|
||||||
@@ -349,33 +359,54 @@ radeon_gpu_i2c_setup(uint32 connector, uint8 gpio_id)
|
|||||||
// TODO : if DCE 4 and i == 7 ... manual override for evergreen
|
// TODO : if DCE 4 and i == 7 ... manual override for evergreen
|
||||||
// TODO : if DCE 3 and i == 4 ... manual override
|
// TODO : if DCE 3 and i == 4 ... manual override
|
||||||
|
|
||||||
if (gpio->sucI2cId.ucAccess == gpio_id) {
|
if (gpio->sucI2cId.ucAccess != gpio_id)
|
||||||
i2c_bus bus;
|
continue;
|
||||||
|
|
||||||
// successful lookup
|
// successful lookup
|
||||||
TRACE("%s: successful i2c gpio lookup\n", __func__);
|
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
|
// populate gpio information
|
||||||
bus.cookie = (void*)analogDataReg;
|
gConnector[connector]->connector_ddc_info.gpio_id = gpio_id;
|
||||||
bus.set_signals = &set_i2c_signals;
|
|
||||||
bus.get_signals = &get_i2c_signals;
|
|
||||||
|
|
||||||
ddc2_init_timing(&bus);
|
gConnector[connector]->connector_ddc_info.mask_scl_reg
|
||||||
// TODO : check for valid analog edid
|
= B_LENDIAN_TO_HOST_INT16(gpio->usClkMaskRegisterIndex) * 4;
|
||||||
// TODO : check for valid digital edid no results on analog
|
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;
|
return B_OK;
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ void radeon_gpu_mc_resume();
|
|||||||
uint32 radeon_gpu_mc_idlecheck();
|
uint32 radeon_gpu_mc_idlecheck();
|
||||||
status_t radeon_gpu_mc_setup();
|
status_t radeon_gpu_mc_setup();
|
||||||
status_t radeon_gpu_irq_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);
|
status_t radeon_gpu_i2c_setup(uint32 connector, uint8 gpio_id);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user