Add early support for external encoders
* detect and attempt setup on external encoders * improve encoder tracing
This commit is contained in:
@@ -39,6 +39,7 @@ union crtc_source_param {
|
|||||||
void
|
void
|
||||||
encoder_assign_crtc(uint8 crtcID)
|
encoder_assign_crtc(uint8 crtcID)
|
||||||
{
|
{
|
||||||
|
TRACE("%s\n", __func__);
|
||||||
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
|
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
|
||||||
union crtc_source_param args;
|
union crtc_source_param args;
|
||||||
|
|
||||||
@@ -176,6 +177,7 @@ encoder_assign_crtc(uint8 crtcID)
|
|||||||
void
|
void
|
||||||
encoder_apply_quirks(uint8 crtcID)
|
encoder_apply_quirks(uint8 crtcID)
|
||||||
{
|
{
|
||||||
|
TRACE("%s\n", __func__);
|
||||||
radeon_shared_info &info = *gInfo->shared_info;
|
radeon_shared_info &info = *gInfo->shared_info;
|
||||||
register_info* regs = gDisplay[crtcID]->regs;
|
register_info* regs = gDisplay[crtcID]->regs;
|
||||||
uint32 connectorIndex = gDisplay[crtcID]->connectorIndex;
|
uint32 connectorIndex = gDisplay[crtcID]->connectorIndex;
|
||||||
@@ -194,6 +196,7 @@ encoder_apply_quirks(uint8 crtcID)
|
|||||||
void
|
void
|
||||||
encoder_mode_set(uint8 id, uint32 pixelClock)
|
encoder_mode_set(uint8 id, uint32 pixelClock)
|
||||||
{
|
{
|
||||||
|
TRACE("%s\n", __func__);
|
||||||
radeon_shared_info &info = *gInfo->shared_info;
|
radeon_shared_info &info = *gInfo->shared_info;
|
||||||
uint32 connectorIndex = gDisplay[id]->connectorIndex;
|
uint32 connectorIndex = gDisplay[id]->connectorIndex;
|
||||||
uint16 encoderFlags = gConnector[connectorIndex]->encoder.flags;
|
uint16 encoderFlags = gConnector[connectorIndex]->encoder.flags;
|
||||||
@@ -256,6 +259,23 @@ encoder_mode_set(uint8 id, uint32 pixelClock)
|
|||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
||||||
TRACE("%s: TODO for DVO encoder setup\n", __func__);
|
TRACE("%s: TODO for DVO encoder setup\n", __func__);
|
||||||
break;
|
break;
|
||||||
|
case ENCODER_OBJECT_ID_SI170B:
|
||||||
|
case ENCODER_OBJECT_ID_CH7303:
|
||||||
|
case ENCODER_OBJECT_ID_EXTERNAL_SDVOA:
|
||||||
|
case ENCODER_OBJECT_ID_EXTERNAL_SDVOB:
|
||||||
|
case ENCODER_OBJECT_ID_TITFP513:
|
||||||
|
case ENCODER_OBJECT_ID_VT1623:
|
||||||
|
case ENCODER_OBJECT_ID_HDMI_SI1930:
|
||||||
|
case ENCODER_OBJECT_ID_TRAVIS:
|
||||||
|
case ENCODER_OBJECT_ID_NUTMEG:
|
||||||
|
if (info.dceMajor >= 4 && info.dceMinor >= 1) {
|
||||||
|
encoder_external_setup(id, pixelClock,
|
||||||
|
EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
|
||||||
|
} else {
|
||||||
|
encoder_external_setup(id, pixelClock,
|
||||||
|
ATOM_ENABLE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE("%s: TODO for unknown encoder setup!\n", __func__);
|
TRACE("%s: TODO for unknown encoder setup!\n", __func__);
|
||||||
}
|
}
|
||||||
@@ -330,8 +350,10 @@ encoder_digital_setup(uint8 id, uint32 pixelClock, int command)
|
|||||||
uint8 tableMinor;
|
uint8 tableMinor;
|
||||||
|
|
||||||
if (atom_parse_cmd_header(gAtomContext, index, &tableMajor, &tableMinor)
|
if (atom_parse_cmd_header(gAtomContext, index, &tableMajor, &tableMinor)
|
||||||
!= B_OK)
|
!= B_OK) {
|
||||||
|
ERROR("%s: cannot parse command table\n", __func__);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
switch (tableMajor) {
|
switch (tableMajor) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -437,6 +459,7 @@ encoder_dig_setup(uint8 id, uint32 pixelClock, int command)
|
|||||||
union dig_encoder_control args;
|
union dig_encoder_control args;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
|
// Table verson
|
||||||
uint8 tableMajor;
|
uint8 tableMajor;
|
||||||
uint8 tableMinor;
|
uint8 tableMinor;
|
||||||
|
|
||||||
@@ -576,6 +599,164 @@ encoder_dig_setup(uint8 id, uint32 pixelClock, int command)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
union external_encoder_control {
|
||||||
|
EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1;
|
||||||
|
EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
encoder_external_setup(uint8 id, uint32 pixelClock, int command)
|
||||||
|
{
|
||||||
|
TRACE("%s\n", __func__);
|
||||||
|
|
||||||
|
int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
|
||||||
|
union external_encoder_control args;
|
||||||
|
memset(&args, 0, sizeof(args));
|
||||||
|
|
||||||
|
uint32 connectorIndex = gDisplay[id]->connectorIndex;
|
||||||
|
int connectorObjectID
|
||||||
|
= (gConnector[connectorIndex]->objectID & OBJECT_ID_MASK)
|
||||||
|
>> OBJECT_ID_SHIFT;
|
||||||
|
|
||||||
|
uint8 tableMajor;
|
||||||
|
uint8 tableMinor;
|
||||||
|
|
||||||
|
if (atom_parse_cmd_header(gAtomContext, index, &tableMajor, &tableMinor)
|
||||||
|
!= B_OK) {
|
||||||
|
ERROR("%s: Error parsing ExternalEncoderControl table\n", __func__);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tableMajor) {
|
||||||
|
case 1:
|
||||||
|
// no options needed on table 1.x
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
switch (tableMinor) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
args.v1.sDigEncoder.ucAction = command;
|
||||||
|
args.v1.sDigEncoder.usPixelClock
|
||||||
|
= B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
|
||||||
|
args.v1.sDigEncoder.ucEncoderMode
|
||||||
|
= display_get_encoder_mode(connectorIndex);
|
||||||
|
#if 0
|
||||||
|
if (0) { // ENCODER_MODE_IS_DP(v1.sDigEncoder.ucEncoderMode)
|
||||||
|
if (dp_clock == 270000) {
|
||||||
|
args.v1.sDigEncoder.ucConfig
|
||||||
|
|= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
|
||||||
|
}
|
||||||
|
args.v1.sDigEncoder.ucLaneNum = dp_lane_count;
|
||||||
|
} else if (pixelClock > 165000) {
|
||||||
|
#endif
|
||||||
|
if (pixelClock > 165000) {
|
||||||
|
args.v1.sDigEncoder.ucLaneNum = 8;
|
||||||
|
} else {
|
||||||
|
args.v1.sDigEncoder.ucLaneNum = 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
args.v3.sExtEncoder.ucAction = command;
|
||||||
|
if (command == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) {
|
||||||
|
args.v3.sExtEncoder.usConnectorId
|
||||||
|
= B_HOST_TO_LENDIAN_INT16(connectorObjectID);
|
||||||
|
} else {
|
||||||
|
args.v3.sExtEncoder.usPixelClock
|
||||||
|
= B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
args.v3.sExtEncoder.ucEncoderMode
|
||||||
|
= display_get_encoder_mode(connectorIndex);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (ENCODER_MODE_IS_DP(args.v3.sExtEncoder.ucEncoderMode)) {
|
||||||
|
if (dp_clock == 270000) {
|
||||||
|
args.v3.sExtEncoder.ucConfig
|
||||||
|
|=EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
|
||||||
|
} else if (dp_clock == 540000) {
|
||||||
|
args.v3.sExtEncoder.ucConfig
|
||||||
|
|=EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ;
|
||||||
|
}
|
||||||
|
args.v3.sExtEncoder.ucLaneNum = dp_lane_count;
|
||||||
|
} else if (pixelClock > 165000) {
|
||||||
|
#endif
|
||||||
|
if (pixelClock > 165000) {
|
||||||
|
args.v3.sExtEncoder.ucLaneNum = 8;
|
||||||
|
} else {
|
||||||
|
args.v3.sExtEncoder.ucLaneNum = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 encoderFlags
|
||||||
|
= gConnector[connectorIndex]->encoder.flags;
|
||||||
|
switch ((encoderFlags & ENUM_ID_MASK) >> ENUM_ID_SHIFT) {
|
||||||
|
case GRAPH_OBJECT_ENUM_ID1:
|
||||||
|
TRACE("%s: external encoder 1\n", __func__);
|
||||||
|
args.v3.sExtEncoder.ucConfig
|
||||||
|
|= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1;
|
||||||
|
break;
|
||||||
|
case GRAPH_OBJECT_ENUM_ID2:
|
||||||
|
TRACE("%s: external encoder 2\n", __func__);
|
||||||
|
args.v3.sExtEncoder.ucConfig
|
||||||
|
|= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2;
|
||||||
|
break;
|
||||||
|
case GRAPH_OBJECT_ENUM_ID3:
|
||||||
|
TRACE("%s: external encoder 3\n", __func__);
|
||||||
|
args.v3.sExtEncoder.ucConfig
|
||||||
|
|= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: don't set statically
|
||||||
|
uint32 bitsPerColor = 8;
|
||||||
|
switch (bitsPerColor) {
|
||||||
|
case 0:
|
||||||
|
args.v3.sExtEncoder.ucBitPerColor
|
||||||
|
= PANEL_BPC_UNDEFINE;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
args.v3.sExtEncoder.ucBitPerColor
|
||||||
|
= PANEL_6BIT_PER_COLOR;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
default:
|
||||||
|
args.v3.sExtEncoder.ucBitPerColor
|
||||||
|
= PANEL_8BIT_PER_COLOR;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
args.v3.sExtEncoder.ucBitPerColor
|
||||||
|
= PANEL_10BIT_PER_COLOR;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
args.v3.sExtEncoder.ucBitPerColor
|
||||||
|
= PANEL_12BIT_PER_COLOR;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
args.v3.sExtEncoder.ucBitPerColor
|
||||||
|
= PANEL_16BIT_PER_COLOR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ERROR("%s: Unknown table minor version: "
|
||||||
|
"%" B_PRIu8 ".%" B_PRIu8 "\n", __func__,
|
||||||
|
tableMajor, tableMinor);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERROR("%s: Unknown table major version: "
|
||||||
|
"%" B_PRIu8 ".%" B_PRIu8 "\n", __func__,
|
||||||
|
tableMajor, tableMinor);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return atom_execute_table(gAtomContext, index, (uint32*)&args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
encoder_analog_setup(uint8 id, uint32 pixelClock, int command)
|
encoder_analog_setup(uint8 id, uint32 pixelClock, int command)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
void encoder_assign_crtc(uint8 crt_id);
|
void encoder_assign_crtc(uint8 crt_id);
|
||||||
void encoder_apply_quirks(uint8 crtcID);
|
void encoder_apply_quirks(uint8 crtcID);
|
||||||
void encoder_mode_set(uint8 id, uint32 pixelClock);
|
void encoder_mode_set(uint8 id, uint32 pixelClock);
|
||||||
status_t encoder_digital_setup(uint8 id, uint32 pixelClock, int command);
|
|
||||||
status_t encoder_analog_setup(uint8 id, uint32 pixelClock, int command);
|
status_t encoder_analog_setup(uint8 id, uint32 pixelClock, int command);
|
||||||
|
status_t encoder_digital_setup(uint8 id, uint32 pixelClock, int command);
|
||||||
status_t encoder_dig_setup(uint8 id, uint32 pixelClock, int command);
|
status_t encoder_dig_setup(uint8 id, uint32 pixelClock, int command);
|
||||||
|
status_t encoder_external_setup(uint8 id, uint32 pixelClock, int command);
|
||||||
status_t encoder_tv_setup(uint8 id, uint32 pixelClock, int command);
|
status_t encoder_tv_setup(uint8 id, uint32 pixelClock, int command);
|
||||||
bool encoder_analog_load_detect(uint8 connectorIndex);
|
bool encoder_analog_load_detect(uint8 connectorIndex);
|
||||||
void encoder_output_lock(bool lock);
|
void encoder_output_lock(bool lock);
|
||||||
|
|||||||
Reference in New Issue
Block a user