Add legacy card connectior detection using table method
* attempt AtomBIOS table probe first, then fallback to legacy method if no connectors found (or table version is too old) * add function to look up object info on older cards * dcc still needs some work on old cards * my X1200 IGP gets video now
This commit is contained in:
@@ -256,6 +256,12 @@ radeon_init_accelerant(int device)
|
|||||||
|
|
||||||
// detect physical connectors
|
// detect physical connectors
|
||||||
status = detect_connectors();
|
status = detect_connectors();
|
||||||
|
|
||||||
|
if (status != B_OK) {
|
||||||
|
TRACE("%s: falling back to legacy connector detection.\n", __func__);
|
||||||
|
status = detect_connectors_legacy();
|
||||||
|
}
|
||||||
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
TRACE("%s: couldn't detect supported connectors!\n", __func__);
|
TRACE("%s: couldn't detect supported connectors!\n", __func__);
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
@@ -237,8 +237,6 @@ detect_crt_ranges(uint32 crtid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: only used on r4xx, r5xx, and rs600/rs690/rs740
|
|
||||||
#if 0
|
|
||||||
union atom_supported_devices {
|
union atom_supported_devices {
|
||||||
struct _ATOM_SUPPORTED_DEVICES_INFO info;
|
struct _ATOM_SUPPORTED_DEVICES_INFO info;
|
||||||
struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2;
|
struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2;
|
||||||
@@ -261,21 +259,28 @@ detect_connectors_legacy()
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
union atom_supported_devices *supported_devices;
|
union atom_supported_devices *supportedDevices;
|
||||||
supported_devices
|
supportedDevices = (union atom_supported_devices *)
|
||||||
= (union atom_supported_devices *)
|
|
||||||
(gAtomContext->bios + tableOffset);
|
(gAtomContext->bios + tableOffset);
|
||||||
|
|
||||||
uint16 device_support
|
uint16 deviceSupport
|
||||||
= B_LENDIAN_TO_HOST_INT16(supported_devices->info.usDeviceSupport);
|
= B_LENDIAN_TO_HOST_INT16(supportedDevices->info.usDeviceSupport);
|
||||||
|
|
||||||
int32 i;
|
uint32 maxDevice;
|
||||||
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
|
|
||||||
|
|
||||||
gConnector[i]->valid = false;
|
if (tableMajor > 1)
|
||||||
|
maxDevice = ATOM_MAX_SUPPORTED_DEVICE;
|
||||||
|
else
|
||||||
|
maxDevice = ATOM_MAX_SUPPORTED_DEVICE_INFO;
|
||||||
|
|
||||||
|
uint32 i;
|
||||||
|
uint32 connectorIndex = 0;
|
||||||
|
for (i = 0; i < maxDevice; i++) {
|
||||||
|
|
||||||
|
gConnector[connectorIndex]->valid = false;
|
||||||
|
|
||||||
// check if this connector is used
|
// check if this connector is used
|
||||||
if ((device_support & (1 << i)) == 0)
|
if ((deviceSupport & (1 << i)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (i == ATOM_DEVICE_CV_INDEX) {
|
if (i == ATOM_DEVICE_CV_INDEX) {
|
||||||
@@ -285,57 +290,63 @@ detect_connectors_legacy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ATOM_CONNECTOR_INFO_I2C ci
|
ATOM_CONNECTOR_INFO_I2C ci
|
||||||
= supported_devices->info.asConnInfo[i];
|
= supportedDevices->info.asConnInfo[i];
|
||||||
|
|
||||||
gConnector[i]->type
|
gConnector[connectorIndex]->type = connector_convert_legacy[
|
||||||
= connector_convert_legacy[
|
ci.sucConnectorInfo.sbfAccess.bfConnectorType];
|
||||||
ci.sucConnectorInfo.sbfAccess.bfConnectorType];
|
|
||||||
|
|
||||||
if (gConnector[i]->type == VIDEO_CONNECTOR_UNKNOWN) {
|
if (gConnector[connectorIndex]->type == VIDEO_CONNECTOR_UNKNOWN) {
|
||||||
TRACE("%s: skipping unknown connector at %" B_PRId32
|
TRACE("%s: skipping unknown connector at %" B_PRId32
|
||||||
" of 0x%" B_PRIX8 "\n", __func__, i,
|
" of 0x%" B_PRIX8 "\n", __func__, i,
|
||||||
ci.sucConnectorInfo.sbfAccess.bfConnectorType);
|
ci.sucConnectorInfo.sbfAccess.bfConnectorType);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// uint8 dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;
|
|
||||||
// gConnector[i]->line_mux = ci.sucI2cId.ucAccess;
|
|
||||||
|
|
||||||
// TODO: give tv unique connector ids
|
// TODO: give tv unique connector ids
|
||||||
|
|
||||||
// Always set CRT1 and CRT2 as VGA, some cards incorrectly set
|
// Always set CRT1 and CRT2 as VGA, some cards incorrectly set
|
||||||
// VGA ports as DVI
|
// VGA ports as DVI
|
||||||
if (i == ATOM_DEVICE_CRT1_INDEX || i == ATOM_DEVICE_CRT2_INDEX)
|
if (i == ATOM_DEVICE_CRT1_INDEX || i == ATOM_DEVICE_CRT2_INDEX)
|
||||||
gConnector[i]->type = VIDEO_CONNECTOR_VGA;
|
gConnector[connectorIndex]->type = VIDEO_CONNECTOR_VGA;
|
||||||
|
|
||||||
gConnector[i]->valid = true;
|
uint8 dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;
|
||||||
gConnector[i]->encoder.flags = (1 << i);
|
uint32 encoderObject = encoder_object_lookup((1 << i), dac);
|
||||||
|
|
||||||
// TODO: add the encoder
|
gConnector[connectorIndex]->valid = true;
|
||||||
#if 0
|
gConnector[connectorIndex]->encoder.flags = (1 << i);
|
||||||
radeon_add_atom_encoder(dev,
|
gConnector[connectorIndex]->encoder.valid = true;
|
||||||
radeon_get_encoder_enum(dev,
|
gConnector[connectorIndex]->encoder.objectID
|
||||||
(1 << i),
|
= (encoderObject & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
|
||||||
dac),
|
|
||||||
(1 << i),
|
radeon_gpu_i2c_attach(connectorIndex, ci.sucI2cId.ucAccess);
|
||||||
0);
|
|
||||||
#endif
|
//gConnector[connectorIndex]->encoder.isExternal
|
||||||
|
// = encoderExternal;
|
||||||
|
|
||||||
|
pll_limit_probe(&gConnector[connectorIndex]->encoder.pll);
|
||||||
|
|
||||||
|
connectorIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: combine shared connectors
|
// TODO: combine shared connectors
|
||||||
|
|
||||||
// TODO: add connectors
|
// TODO: add connectors
|
||||||
|
|
||||||
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE_INFO; i++) {
|
for (i = 0; i < maxDevice; i++) {
|
||||||
if (gConnector[i]->valid == true) {
|
if (gConnector[i]->valid == true) {
|
||||||
TRACE("%s: connector #%" B_PRId32 " is %s\n", __func__, i,
|
TRACE("%s: connector #%" B_PRId32 " is %s\n", __func__, i,
|
||||||
get_connector_name(gConnector[i]->type));
|
get_connector_name(gConnector[i]->type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (connectorIndex == 0) {
|
||||||
|
TRACE("%s: zero connectors found using legacy detection\n", __func__);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// r600+
|
// r600+
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ const int connector_convert[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
status_t init_registers(register_info* reg, uint8 crtid);
|
status_t init_registers(register_info* reg, uint8 crtid);
|
||||||
// status_t detect_connectors_legacy();
|
status_t detect_connectors_legacy();
|
||||||
status_t detect_connectors();
|
status_t detect_connectors();
|
||||||
status_t detect_crt_ranges(uint32 crtid);
|
status_t detect_crt_ranges(uint32 crtid);
|
||||||
status_t detect_displays();
|
status_t detect_displays();
|
||||||
|
|||||||
@@ -929,3 +929,79 @@ encoder_output_lock(bool lock)
|
|||||||
|
|
||||||
Write32(OUT, R600_BIOS_6_SCRATCH, biosScratch6);
|
Write32(OUT, R600_BIOS_6_SCRATCH, biosScratch6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
encoder_object_lookup(uint32 encoderFlags, uint8 dacID)
|
||||||
|
{
|
||||||
|
// used on older cards to take a guess at the encoder
|
||||||
|
// objectID
|
||||||
|
|
||||||
|
radeon_shared_info &info = *gInfo->shared_info;
|
||||||
|
|
||||||
|
uint32 ret = 0;
|
||||||
|
|
||||||
|
switch (encoderFlags) {
|
||||||
|
case ATOM_DEVICE_CRT1_SUPPORT:
|
||||||
|
case ATOM_DEVICE_TV1_SUPPORT:
|
||||||
|
case ATOM_DEVICE_TV2_SUPPORT:
|
||||||
|
case ATOM_DEVICE_CRT2_SUPPORT:
|
||||||
|
case ATOM_DEVICE_CV_SUPPORT:
|
||||||
|
switch (dacID) {
|
||||||
|
case 1:
|
||||||
|
if ((info.chipsetID == RADEON_RS400)
|
||||||
|
|| (info.chipsetID == RADEON_RS480))
|
||||||
|
ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
|
||||||
|
else if (info.chipsetID >= RADEON_RS600)
|
||||||
|
ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;
|
||||||
|
else
|
||||||
|
ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (info.chipsetID >= RADEON_RS600)
|
||||||
|
ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;
|
||||||
|
else {
|
||||||
|
ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: // external dac
|
||||||
|
if (info.chipsetID >= RADEON_RS600)
|
||||||
|
ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
|
||||||
|
else
|
||||||
|
ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ATOM_DEVICE_LCD1_SUPPORT:
|
||||||
|
if (info.chipsetID >= RADEON_RS600)
|
||||||
|
ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
|
||||||
|
else
|
||||||
|
ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;
|
||||||
|
break;
|
||||||
|
case ATOM_DEVICE_DFP1_SUPPORT:
|
||||||
|
if ((info.chipsetID == RADEON_RS400)
|
||||||
|
|| (info.chipsetID == RADEON_RS480))
|
||||||
|
ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
|
||||||
|
else if (info.chipsetID >= RADEON_RS600)
|
||||||
|
ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;
|
||||||
|
else
|
||||||
|
ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;
|
||||||
|
break;
|
||||||
|
case ATOM_DEVICE_LCD2_SUPPORT:
|
||||||
|
case ATOM_DEVICE_DFP2_SUPPORT:
|
||||||
|
if ((info.chipsetID == RADEON_RS600)
|
||||||
|
|| (info.chipsetID == RADEON_RS690)
|
||||||
|
|| (info.chipsetID == RADEON_RS740))
|
||||||
|
ret = ENCODER_INTERNAL_DDI_ENUM_ID1;
|
||||||
|
else if (info.chipsetID >= RADEON_RS600)
|
||||||
|
ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
|
||||||
|
else
|
||||||
|
ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
|
||||||
|
break;
|
||||||
|
case ATOM_DEVICE_DFP3_SUPPORT:
|
||||||
|
ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ void encoder_output_lock(bool lock);
|
|||||||
void encoder_crtc_scratch(uint8 crtcID);
|
void encoder_crtc_scratch(uint8 crtcID);
|
||||||
void encoder_dpms_scratch(uint8 crtcID, bool power);
|
void encoder_dpms_scratch(uint8 crtcID, bool power);
|
||||||
void encoder_dpms_set(uint8 crtcID, uint8 encoderID, int mode);
|
void encoder_dpms_set(uint8 crtcID, uint8 encoderID, int mode);
|
||||||
|
uint32 encoder_object_lookup(uint32 encoderFlags, uint8 dacID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* RADEON_HD_ENCODER_H */
|
#endif /* RADEON_HD_ENCODER_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user