radeon_hd: AtomBIOS version bump. Encoder work.

* Now pulling in latest amdgpu atombios.h headers
* Lots of DisplayPort cleanup and removal of legacy stuff
* Add obsolete atombios header for things that disappear
  (amdgpu doesn't support older cards like we do)
* Introduce new code to support later encoder tables
* Drop radeon-specific encoder service from common dp_info
* Tested on HD 5450 hdmi
This commit is contained in:
Alexander von Gluck IV
2016-10-05 13:54:24 -05:00
parent 878f147950
commit 25a087bc7c
8 changed files with 3630 additions and 2302 deletions
-2
View File
@@ -28,8 +28,6 @@ typedef struct {
// Internal State information // Internal State information
uint8 linkStatus[DP_LINK_STATUS_SIZE]; uint8 linkStatus[DP_LINK_STATUS_SIZE];
bool trainingUseEncoder;
uint8 trainingAttempts; uint8 trainingAttempts;
uint8 trainingSet[4]; uint8 trainingSet[4];
int trainingReadInterval; int trainingReadInterval;
@@ -69,6 +69,8 @@
#define ENCODER_OBJECT_ID_ALMOND 0x22 #define ENCODER_OBJECT_ID_ALMOND 0x22
#define ENCODER_OBJECT_ID_TRAVIS 0x23 #define ENCODER_OBJECT_ID_TRAVIS 0x23
#define ENCODER_OBJECT_ID_NUTMEG 0x22 #define ENCODER_OBJECT_ID_NUTMEG 0x22
#define ENCODER_OBJECT_ID_HDMI_ANX9805 0x26
/* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */ /* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14
@@ -86,6 +88,8 @@
#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 0x20 #define ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 0x20
#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 0x21 #define ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 0x21
#define ENCODER_OBJECT_ID_INTERNAL_VCE 0x24 #define ENCODER_OBJECT_ID_INTERNAL_VCE 0x24
#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 0x25
#define ENCODER_OBJECT_ID_INTERNAL_AMCLK 0x27
#define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO 0xFF #define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO 0xFF
@@ -364,6 +368,14 @@
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT)
#define ENCODER_INTERNAL_UNIPHY3_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 << OBJECT_ID_SHIFT)
#define ENCODER_INTERNAL_UNIPHY3_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 << OBJECT_ID_SHIFT)
#define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ #define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT) ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT)
@@ -388,10 +400,14 @@
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
ENCODER_OBJECT_ID_NUTMEG << OBJECT_ID_SHIFT) ENCODER_OBJECT_ID_NUTMEG << OBJECT_ID_SHIFT)
#define ENCODER_VCE_ENUM_ID1 ( GRAPH_OBHECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ #define ENCODER_VCE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
ENCODER_OBJECT_ID_INTERNAL_VCE << OBJECT_ID_SHIFT) ENCODER_OBJECT_ID_INTERNAL_VCE << OBJECT_ID_SHIFT)
#define ENCODER_HDMI_ANX9805_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
ENCODER_OBJECT_ID_HDMI_ANX9805 << OBJECT_ID_SHIFT)
/****************************************************/ /****************************************************/
/* Connector Object ID definition - Shared with BIOS */ /* Connector Object ID definition - Shared with BIOS */
/****************************************************/ /****************************************************/
@@ -461,6 +477,14 @@
GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ #define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
@@ -473,6 +497,10 @@
GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
#define CONNECTOR_VGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ #define CONNECTOR_VGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
@@ -541,6 +569,18 @@
GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
#define CONNECTOR_HDMI_TYPE_A_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
#define CONNECTOR_HDMI_TYPE_A_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
#define CONNECTOR_HDMI_TYPE_A_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ #define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT) CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT)
@@ -0,0 +1,24 @@
/*
* Copyright 2016, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Alexander von Gluck, [email protected]
*/
#ifndef _ATOMBIOS_OBSOLETE_H
#define _ATOMBIOS_OBSOLETE_H
// atombios.h in radeon linux has some older obsolete things.
// atombios.h in amdgpu has these obsolete things removed.
// This file contains things removed from amdgpu that we still need.
#define ATOM_S2_CV_DPMS_STATE 0x01000000L
#define ATOM_S2_DFP2_DPMS_STATE 0x00800000L
#define ATOM_S2_DFP3_DPMS_STATE 0x02000000L
#define ATOM_S2_DFP4_DPMS_STATE 0x04000000L
#define ATOM_S2_DFP5_DPMS_STATE 0x08000000L
#endif /* _ATOMBIOS_OBSOLETE_H */
File diff suppressed because it is too large Load Diff
+43 -108
View File
@@ -405,6 +405,33 @@ dp_get_link_rate(uint32 connectorIndex, display_mode* mode)
} }
static uint8
dp_encoder_service(int action, int linkRate, uint8 lane, uint8 config)
{
DP_ENCODER_SERVICE_PARAMETERS args;
int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
memset(&args, 0, sizeof(args));
args.ucLinkClock = linkRate / 10;
args.ucConfig = config;
args.ucAction = action;
args.ucLaneNum = lane;
args.ucStatus = 0;
atom_execute_table(gAtomContext, index, (uint32*)&args);
return args.ucStatus;
}
uint8
dp_get_sink_type(uint32 connectorIndex)
{
dp_info* dpInfo = &gConnector[connectorIndex]->dpInfo;
return dp_encoder_service(ATOM_DP_ACTION_GET_SINK_TYPE, 0, 0,
dpInfo->auxPin);
}
void void
dp_setup_connectors() dp_setup_connectors()
{ {
@@ -616,80 +643,28 @@ dp_get_adjust_train(dp_info* dp)
} }
static uint8
dp_encoder_service(uint32 connectorIndex, int action, int linkRate,
uint8 lane)
{
DP_ENCODER_SERVICE_PARAMETERS args;
int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
memset(&args, 0, sizeof(args));
args.ucLinkClock = linkRate;
args.ucAction = action;
args.ucLaneNum = lane;
args.ucConfig = 0;
args.ucStatus = 0;
// We really can't do ATOM_DP_ACTION_GET_SINK_TYPE with the
// way I designed this below. Not used though.
// Calculate encoder_id config
if (encoder_pick_dig(connectorIndex))
args.ucConfig |= ATOM_DP_CONFIG_DIG2_ENCODER;
else
args.ucConfig |= ATOM_DP_CONFIG_DIG1_ENCODER;
if (gConnector[connectorIndex]->encoder.linkEnumeration
== GRAPH_OBJECT_ENUM_ID2) {
args.ucConfig |= ATOM_DP_CONFIG_LINK_B;
} else
args.ucConfig |= ATOM_DP_CONFIG_LINK_A;
atom_execute_table(gAtomContext, index, (uint32*)&args);
return args.ucStatus;
}
static void static void
dp_set_tp(uint32 connectorIndex, int trainingPattern) dp_set_tp(uint32 connectorIndex, int trainingPattern)
{ {
TRACE("%s\n", __func__); TRACE("%s\n", __func__);
radeon_shared_info &info = *gInfo->shared_info;
dp_info* dp = &gConnector[connectorIndex]->dpInfo;
pll_info* pll = &gConnector[connectorIndex]->encoder.pll; pll_info* pll = &gConnector[connectorIndex]->encoder.pll;
int rawTrainingPattern = 0; int rawTrainingPattern = 0;
/* set training pattern on the source */ /* set training pattern on the source */
if (info.dceMajor >= 4 || !dp->trainingUseEncoder) { TRACE("%s: Training with encoder...\n", __func__);
TRACE("%s: Training with encoder...\n", __func__); switch (trainingPattern) {
switch (trainingPattern) { case DP_TRAIN_PATTERN_1:
case DP_TRAIN_PATTERN_1: rawTrainingPattern = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1;
rawTrainingPattern = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1; break;
break; case DP_TRAIN_PATTERN_2:
case DP_TRAIN_PATTERN_2: rawTrainingPattern = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2;
rawTrainingPattern = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2; break;
break; case DP_TRAIN_PATTERN_3:
case DP_TRAIN_PATTERN_3: rawTrainingPattern = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN3;
rawTrainingPattern = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN3; break;
break;
}
encoder_dig_setup(connectorIndex, pll->pixelClock, rawTrainingPattern);
} else {
TRACE("%s: Training with encoder service...\n", __func__);
switch (trainingPattern) {
case DP_TRAIN_PATTERN_1:
rawTrainingPattern = 0;
break;
case DP_TRAIN_PATTERN_2:
rawTrainingPattern = 1;
break;
}
dp_encoder_service(connectorIndex, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
dp->linkRate, rawTrainingPattern);
} }
encoder_dig_setup(connectorIndex, pll->pixelClock, rawTrainingPattern);
// Enable training pattern on the sink // Enable training pattern on the sink
dpcd_reg_write(connectorIndex, DP_TRAIN, trainingPattern); dpcd_reg_write(connectorIndex, DP_TRAIN, trainingPattern);
@@ -839,34 +814,6 @@ dp_link_train(uint8 crtcID)
return B_ERROR; return B_ERROR;
} }
int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
// Table version
uint8 tableMajor;
uint8 tableMinor;
dp->trainingUseEncoder = true;
if (atom_parse_cmd_header(gAtomContext, index, &tableMajor, &tableMinor)
== B_OK) {
if (tableMinor > 1) {
// The AtomBIOS DPEncoderService greater then 1.1 can't program the
// training pattern properly.
dp->trainingUseEncoder = false;
}
}
uint32 linkEnumeration
= gConnector[connectorIndex]->encoder.linkEnumeration;
uint32 dpEncoderID = 0;
if (encoder_pick_dig(connectorIndex) > 0)
dpEncoderID |= ATOM_DP_CONFIG_DIG2_ENCODER;
else
dpEncoderID |= ATOM_DP_CONFIG_DIG1_ENCODER;
if (linkEnumeration == GRAPH_OBJECT_ENUM_ID2)
dpEncoderID |= ATOM_DP_CONFIG_LINK_B;
else
dpEncoderID |= ATOM_DP_CONFIG_LINK_A;
dp->trainingReadInterval dp->trainingReadInterval
= dpcd_reg_read(connectorIndex, DP_TRAINING_AUX_RD_INTERVAL); = dpcd_reg_read(connectorIndex, DP_TRAINING_AUX_RD_INTERVAL);
@@ -905,13 +852,8 @@ dp_link_train(uint8 crtcID)
dpcd_reg_write(connectorIndex, DP_LINK_RATE, sandbox); dpcd_reg_write(connectorIndex, DP_LINK_RATE, sandbox);
// Start link training on source // Start link training on source
if (info.dceMajor >= 4 || !dp->trainingUseEncoder) { encoder_dig_setup(connectorIndex, mode->timing.pixel_clock,
encoder_dig_setup(connectorIndex, mode->timing.pixel_clock, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START);
ATOM_ENCODER_CMD_DP_LINK_TRAINING_START);
} else {
dp_encoder_service(connectorIndex, ATOM_DP_ACTION_TRAINING_START,
dp->linkRate, 0);
}
// Disable the training pattern on the sink // Disable the training pattern on the sink
dpcd_reg_write(connectorIndex, DP_TRAIN, DP_TRAIN_PATTERN_DISABLED); dpcd_reg_write(connectorIndex, DP_TRAIN, DP_TRAIN_PATTERN_DISABLED);
@@ -926,13 +868,8 @@ dp_link_train(uint8 crtcID)
dpcd_reg_write(connectorIndex, DP_TRAIN, DP_TRAIN_PATTERN_DISABLED); dpcd_reg_write(connectorIndex, DP_TRAIN, DP_TRAIN_PATTERN_DISABLED);
// Disable the training pattern on the source // Disable the training pattern on the source
if (info.dceMajor >= 4 || !dp->trainingUseEncoder) { encoder_dig_setup(connectorIndex, mode->timing.pixel_clock,
encoder_dig_setup(connectorIndex, mode->timing.pixel_clock, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
} else {
dp_encoder_service(connectorIndex, ATOM_DP_ACTION_TRAINING_COMPLETE,
dp->linkRate, 0);
}
return B_OK; return B_OK;
} }
@@ -1055,8 +992,6 @@ debug_dp_info()
dp->config[DP_DOWNSTREAMPORT_COUNT] dp->config[DP_DOWNSTREAMPORT_COUNT]
& DP_DOWNSTREAMPORT_COUNT_MASK); & DP_DOWNSTREAMPORT_COUNT_MASK);
ERROR(" + Training\n"); ERROR(" + Training\n");
ERROR(" - use encoder: %s\n",
dp->trainingUseEncoder ? "true" : "false");
ERROR(" - attempts: %" B_PRIu8 "\n", ERROR(" - attempts: %" B_PRIu8 "\n",
dp->trainingAttempts); dp->trainingAttempts);
ERROR(" - delay: %d\n", ERROR(" - delay: %d\n",
@@ -36,6 +36,7 @@ status_t dp_aux_get_i2c_byte(uint32 connectorIndex, uint16 address,
uint32 dp_get_link_rate(uint32 connectorIndex, display_mode* mode); uint32 dp_get_link_rate(uint32 connectorIndex, display_mode* mode);
uint32 dp_get_lane_count(uint32 connectorIndex, display_mode* mode); uint32 dp_get_lane_count(uint32 connectorIndex, display_mode* mode);
uint8 dp_get_sink_type(uint32 connectorIndex);
void dp_setup_connectors(); void dp_setup_connectors();
+115 -84
View File
@@ -16,6 +16,7 @@
#include "accelerant.h" #include "accelerant.h"
#include "accelerant_protos.h" #include "accelerant_protos.h"
#include "atombios-obsolete.h"
#include "bios.h" #include "bios.h"
#include "connector.h" #include "connector.h"
#include "display.h" #include "display.h"
@@ -1216,6 +1217,7 @@ transmitter_dig_setup(uint32 connectorIndex, uint32 pixelClock,
DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3;
DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4; DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4;
DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 v5; DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 v5;
DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_6 v6;
}; };
union digTransmitterControl args; union digTransmitterControl args;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
@@ -1576,12 +1578,64 @@ transmitter_dig_setup(uint32 connectorIndex, uint32 pixelClock,
args.v5.asConfig.ucCoherentMode = 1; args.v5.asConfig.ucCoherentMode = 1;
} }
// RADEON_HPD_NONE? VVV // TODO: hpd_id, for now RADEON_HPD_NONE.
args.v5.asConfig.ucHPDSel = 0; args.v5.asConfig.ucHPDSel = 0;
args.v5.ucDigEncoderSel = 1 << digEncoderID; args.v5.ucDigEncoderSel = 1 << digEncoderID;
args.v5.ucDPLaneSet = laneSet; args.v5.ucDPLaneSet = laneSet;
break; break;
case 6:
args.v6.ucAction = command;
if (isDP) {
args.v6.ulSymClock
= B_HOST_TO_LENDIAN_INT16(dpClock / 10);
} else {
args.v6.ulSymClock
= B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
}
switch (encoderObjectID) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
if (linkB)
args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYB;
else
args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYA;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
if (linkB)
args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYD;
else
args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYC;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
if (linkB)
args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYF;
else
args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYE;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYG;
break;
}
if (isDP)
args.v6.ucLaneNum = dpLaneCount;
else if (pixelClock > 165000)
args.v6.ucLaneNum = 8;
else
args.v6.ucLaneNum = 4;
args.v6.ucConnObjId = connectorObjectID;
if (command == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH)
args.v6.ucDPLaneSet = laneSet;
else {
args.v6.ucDigMode
= display_get_encoder_mode(connectorIndex);
}
// TODO: hpd_id, for now RADEON_HPD_NONE.
args.v6.ucHPDSel = 0;
args.v6.ucDigEncoderSel = 1 << digEncoderID;
break;
default: default:
ERROR("%s: unknown table version\n", __func__); ERROR("%s: unknown table version\n", __func__);
} }
@@ -1806,13 +1860,10 @@ encoder_dpms_set(uint8 crtcID, int mode)
? ATOM_LCD_BLOFF : ATOM_LCD_BLON; ? ATOM_LCD_BLOFF : ATOM_LCD_BLON;
atom_execute_table(gAtomContext, index, (uint32*)&args); atom_execute_table(gAtomContext, index, (uint32*)&args);
} }
encoder_dpms_scratch(crtcID, true);
} }
if (info.dceMajor < 4)
encoder_dpms_scratch(crtcID, true);
} }
// If an external encoder exists, we should flip it on as well
if (gConnector[connectorIndex]->encoderExternal.valid == true)
encoder_dpms_set_external(crtcID, mode);
} }
@@ -1823,43 +1874,45 @@ encoder_dpms_set_dig(uint8 crtcID, int mode)
radeon_shared_info &info = *gInfo->shared_info; radeon_shared_info &info = *gInfo->shared_info;
uint32 connectorIndex = gDisplay[crtcID]->connectorIndex; uint32 connectorIndex = gDisplay[crtcID]->connectorIndex;
uint32 connectorFlags = gConnector[connectorIndex]->flags; connector_info* connector = gConnector[connectorIndex];
pll_info* pll = &gConnector[connectorIndex]->encoder.pll; uint32 connectorFlags = connector->flags;
pll_info* pll = &connector->encoder.pll;
bool hasExternal = connector->encoderExternal.valid;
bool travisQuirk = info.dceMajor < 5
&& (connectorFlags & ATOM_DEVICE_LCD_SUPPORT) != 0
&& connector->encoderExternal.objectID == ENCODER_OBJECT_ID_TRAVIS;
switch (mode) { switch (mode) {
case B_DPMS_ON: case B_DPMS_ON:
if (info.chipsetID == RADEON_RV710 if ((info.dceMajor == 4 && info.dceMinor == 1)
|| info.chipsetID == RADEON_RV730
|| (info.chipsetFlags & CHIP_APU) != 0
|| info.dceMajor >= 5) { || info.dceMajor >= 5) {
if (info.dceMajor >= 6) { // Setup encoder
/* We need to call CMD_SETUP before reenabling the encoder, encoder_dig_setup(connectorIndex, pll->pixelClock,
otherwise we never get a picture */ ATOM_ENCODER_CMD_SETUP);
transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0, encoder_dig_setup(connectorIndex, pll->pixelClock,
ATOM_ENCODER_CMD_SETUP); ATOM_ENCODER_CMD_SETUP_PANEL_MODE);
} } else if (info.dceMajor >= 4) {
// Setup encoder
encoder_dig_setup(connectorIndex, pll->pixelClock,
ATOM_ENCODER_CMD_SETUP);
} else {
// Setup encoder and transmitter
encoder_dig_setup(connectorIndex, pll->pixelClock, ATOM_ENABLE); encoder_dig_setup(connectorIndex, pll->pixelClock, ATOM_ENABLE);
transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0, transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0,
ATOM_TRANSMITTER_ACTION_SETUP); ATOM_TRANSMITTER_ACTION_SETUP);
transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0,
ATOM_TRANSMITTER_ACTION_ENABLE);
/* some early dce3.2 boards have a bug in their transmitter
control table */
if (info.chipsetID != RADEON_RV710
&& info.chipsetID != RADEON_RV730)
transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0,
ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT);
} else {
transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0,
ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT);
} }
if (connector->type == VIDEO_CONNECTOR_EDP) {
// TODO: If VIDEO_CONNECTOR_EDP, ATOM_TRANSMITTER_ACTION_POWER_ON
ERROR("%s: TODO, edp_panel_power!\n",
__func__);
}
// Enable transmitter
transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0,
ATOM_TRANSMITTER_ACTION_ENABLE);
if (connector_is_dp(connectorIndex)) { if (connector_is_dp(connectorIndex)) {
if (gConnector[connectorIndex]->type == VIDEO_CONNECTOR_EDP) {
ERROR("%s: TODO, edp_panel_power for this card!\n",
__func__);
// atombios_set_edp_panel_power(connector,
// ATOM_TRANSMITTER_ACTION_POWER_ON);
}
if (info.dceMajor >= 4) { if (info.dceMajor >= 4) {
encoder_dig_setup(connectorIndex, pll->pixelClock, encoder_dig_setup(connectorIndex, pll->pixelClock,
ATOM_ENCODER_CMD_DP_VIDEO_OFF); ATOM_ENCODER_CMD_DP_VIDEO_OFF);
@@ -1878,71 +1931,49 @@ encoder_dpms_set_dig(uint8 crtcID, int mode)
transmitter_dig_setup(connectorIndex, pll->pixelClock, transmitter_dig_setup(connectorIndex, pll->pixelClock,
0, 0, ATOM_TRANSMITTER_ACTION_LCD_BLON); 0, 0, ATOM_TRANSMITTER_ACTION_LCD_BLON);
} }
if (hasExternal)
encoder_external_setup(connectorIndex, ATOM_ENABLE);
break; break;
case B_DPMS_STAND_BY: case B_DPMS_STAND_BY:
case B_DPMS_SUSPEND: case B_DPMS_SUSPEND:
case B_DPMS_OFF: case B_DPMS_OFF:
if ((info.chipsetFlags & CHIP_APU) != 0 || info.dceMajor >= 5) {
transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0,
ATOM_TRANSMITTER_ACTION_DISABLE);
} else {
transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0,
ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT);
transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0,
ATOM_TRANSMITTER_ACTION_DISABLE);
encoder_dig_setup(connectorIndex, pll->pixelClock, ATOM_DISABLE);
}
if (connector_is_dp(connectorIndex)) { if (connector_is_dp(connectorIndex)) {
if (info.dceMajor >= 4) { if (info.dceMajor >= 4) {
encoder_dig_setup(connectorIndex, pll->pixelClock, encoder_dig_setup(connectorIndex, pll->pixelClock,
ATOM_ENCODER_CMD_DP_VIDEO_OFF); ATOM_ENCODER_CMD_DP_VIDEO_OFF);
#if 0
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
atombios_set_edp_panel_power(connector,
ATOM_TRANSMITTER_ACTION_POWER_OFF);
radeon_dig_connector->edp_on = false;
#endif
} }
} }
if (hasExternal)
encoder_external_setup(connectorIndex, ATOM_DISABLE);
if ((connectorFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) { if ((connectorFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) {
transmitter_dig_setup(connectorIndex, pll->pixelClock, transmitter_dig_setup(connectorIndex, pll->pixelClock,
0, 0, ATOM_TRANSMITTER_ACTION_LCD_BLOFF); 0, 0, ATOM_TRANSMITTER_ACTION_LCD_BLOFF);
} }
break; if (connector_is_dp(connectorIndex) && !travisQuirk) {
} // If not TRAVIS on < DCE 5, set_rx_power_state D3
} ERROR("%s: TODO: dpms off set_rx_power_state D3\n", __func__);
}
if (info.dceMajor >= 4) {
void // Disable transmitter
encoder_dpms_set_external(uint8 crtcID, int mode) transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0,
{ ATOM_TRANSMITTER_ACTION_DISABLE);
TRACE("%s: power: %s\n", __func__, mode == B_DPMS_ON ? "true" : "false"); } else {
// Disable transmitter and encoder
radeon_shared_info &info = *gInfo->shared_info; transmitter_dig_setup(connectorIndex, pll->pixelClock, 0, 0,
uint32 connectorIndex = gDisplay[crtcID]->connectorIndex; ATOM_TRANSMITTER_ACTION_DISABLE);
encoder_dig_setup(connectorIndex, pll->pixelClock, ATOM_DISABLE);
switch (mode) { }
case B_DPMS_ON:
if ((info.chipsetFlags & CHIP_APU) != 0) {
encoder_external_setup(connectorIndex,
EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT);
encoder_external_setup(connectorIndex,
EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF);
} else
encoder_external_setup(connectorIndex, ATOM_ENABLE);
break;
case B_DPMS_STAND_BY:
case B_DPMS_SUSPEND:
case B_DPMS_OFF:
if ((info.chipsetFlags & CHIP_APU) != 0) {
encoder_external_setup(connectorIndex,
EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING);
encoder_external_setup(connectorIndex,
EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT);
} else
encoder_external_setup(connectorIndex, ATOM_DISABLE);
if (connector_is_dp(connectorIndex)) {
if (travisQuirk) {
ERROR("%s: TODO: dpms off set_rx_power_state D3\n",
__func__);
}
if (connector->type == VIDEO_CONNECTOR_EDP) {
// TODO: ATOM_TRANSMITTER_ACTION_POWER_OFF
ERROR("%s: TODO, edp_panel_power!\n", __func__);
}
}
break; break;
} }
} }
@@ -39,7 +39,6 @@ void encoder_dpms_scratch(uint8 crtcID, bool power);
void encoder_dpms_set(uint8 crtcID, int mode); void encoder_dpms_set(uint8 crtcID, int mode);
void encoder_dpms_set_dig(uint8 crtcID, int mode); void encoder_dpms_set_dig(uint8 crtcID, int mode);
void encoder_dpms_set_dvo(uint8 crtcID, int mode); void encoder_dpms_set_dvo(uint8 crtcID, int mode);
void encoder_dpms_set_external(uint8 crtcID, int mode);
const char* encoder_name_lookup(uint32 encoderID); const char* encoder_name_lookup(uint32 encoderID);
uint32 encoder_object_lookup(uint32 connectorFlags, uint8 dacID); uint32 encoder_object_lookup(uint32 connectorFlags, uint8 dacID);