Working towards DP connector support

* Lots of new DisplayPort functions
* Call DP link training during mode set
* Rename dp_info variables to be less redundant
* Make encoder_pick_dig accept connector ID and
  then check parent display
* Encode/Decode DP link speed functions
* Calculate DP lanes
* Rewrite encoder_dig_setup
* Correct bitsPerChannel to bitsPerColor
* My TRAVIS DisplayPort -> LVDS bridge now works
This commit is contained in:
Alexander von Gluck IV
2011-12-14 17:46:45 -06:00
parent 86ecd6fba9
commit c8677fb138
9 changed files with 320 additions and 164 deletions
@@ -130,10 +130,10 @@ typedef struct {
typedef struct {
bool valid;
uint8 dpConfig[8]; // DP configuration data
uint8 dpSinkType;
uint8 dpClock;
int dpLaneCount;
uint8 config[8]; // DP configuration data
uint8 sinkType;
uint8 clock;
int laneCount;
bool eDPOn;
} dp_info;
@@ -713,6 +713,18 @@ connector_probe()
}
bool
connector_is_dp(uint32 connectorIndex)
{
if (gConnector[connectorIndex]->type == VIDEO_CONNECTOR_DP
|| gConnector[connectorIndex]->type != VIDEO_CONNECTOR_EDP
|| gConnector[connectorIndex]->encoder.isDPBridge == false) {
return true;
}
return false;
}
void
debug_connectors()
{
@@ -65,6 +65,7 @@ status_t connector_attach_gpio(uint32 id, uint8 hwPin);
bool connector_read_edid(uint32 connector, edid1_info* edid);
status_t connector_probe();
status_t connector_probe_legacy();
bool connector_is_dp(uint32 connectorIndex);
void debug_connectors();
+113 -20
View File
@@ -13,7 +13,7 @@
#include "accelerant.h"
#include "accelerant_protos.h"
#include "displayport_reg.h"
#include "connector.h"
#undef TRACE
@@ -333,6 +333,58 @@ dp_get_link_clock(uint32 connectorIndex)
}
uint32
dp_get_link_clock_encode(uint32 dpLinkClock)
{
switch (dpLinkClock) {
case 270000:
return DP_LINK_BW_2_7;
case 540000:
return DP_LINK_BW_5_4;
}
return DP_LINK_BW_1_62;
}
uint32
dp_get_link_clock_decode(uint32 dpLinkClock)
{
switch (dpLinkClock) {
case DP_LINK_BW_2_7:
return 270000;
case DP_LINK_BW_5_4:
return 540000;
}
return 162000;
}
static uint32
dp_get_lane_count(uint32 connectorIndex, uint32 pixelClock)
{
// TODO: bpp hardcoded
uint32 bitsPerPixel = 32;
uint32 maxLaneCount = gDPInfo[connectorIndex]->config[DP_MAX_LANE_COUNT]
& DP_MAX_LANE_COUNT_MASK;
uint32 maxLinkRate = dp_get_link_clock_decode(
gDPInfo[connectorIndex]->config[DP_MAX_LINK_RATE]);
uint32 lane;
for (lane = 1; lane < maxLaneCount; lane <<= 1) {
uint32 maxDPPixelClock = (maxLinkRate * lane * 8) / bitsPerPixel;
if (pixelClock <= maxDPPixelClock)
break;
}
TRACE("%s: connector: %" B_PRIu32 ", lanes: %" B_PRIu32 "\n", __func__,
connectorIndex, lane);
return lane;
}
void
dp_setup_connectors()
{
@@ -341,14 +393,12 @@ dp_setup_connectors()
for (uint32 index = 0; index < ATOM_MAX_SUPPORTED_DEVICE; index++) {
gDPInfo[index]->valid = false;
if (gConnector[index]->valid == false) {
gDPInfo[index]->dpConfig[0] = 0;
gDPInfo[index]->config[0] = 0;
continue;
}
if (gConnector[index]->type != VIDEO_CONNECTOR_DP
&& gConnector[index]->type != VIDEO_CONNECTOR_EDP
&& gConnector[index]->encoder.isDPBridge == false) {
gDPInfo[index]->dpConfig[0] = 0;
if (connector_is_dp(index) == false) {
gDPInfo[index]->config[0] = 0;
continue;
}
@@ -357,23 +407,18 @@ dp_setup_connectors()
uint8 auxMessage[25];
int result;
int i;
result = dp_aux_read(hwPin, DP_DPCD_REV, auxMessage, 8, 0);
if (result > 0) {
memcpy(gDPInfo[index]->dpConfig, auxMessage, 8);
TRACE("%s: connector #%" B_PRIu32 " DP Config:\n", __func__, index);
for (i = 0; i < 8; i++)
TRACE("%s: %02x\n", __func__, auxMessage[i]);
gDPInfo[index]->valid = true;
memcpy(gDPInfo[index]->config, auxMessage, 8);
}
}
}
status_t
dp_link_train(uint8 crtcID)
dp_link_train(uint8 crtcID, display_mode* mode)
{
TRACE("%s\n", __func__);
@@ -384,6 +429,10 @@ dp_link_train(uint8 crtcID)
return B_ERROR;
}
gDPInfo[connectorIndex]->clock = dp_get_link_clock(connectorIndex);
gDPInfo[connectorIndex]->laneCount
= dp_get_lane_count(connectorIndex, mode->timing.pixel_clock);
int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
// Table version
uint8 tableMajor;
@@ -405,7 +454,7 @@ dp_link_train(uint8 crtcID)
uint32 hwPin = gGPIOInfo[gpioID]->hwPin;
uint32 dpEncoderID = 0;
if (encoder_pick_dig(crtcID) > 0)
if (encoder_pick_dig(connectorIndex) > 0)
dpEncoderID |= ATOM_DP_CONFIG_DIG2_ENCODER;
else
dpEncoderID |= ATOM_DP_CONFIG_DIG1_ENCODER;
@@ -415,22 +464,66 @@ dp_link_train(uint8 crtcID)
dpEncoderID |= ATOM_DP_CONFIG_LINK_A;
//uint8 dpReadInterval = dpcd_reg_read(hwPin, DP_TRAINING_AUX_RD_INTERVAL);
uint8 dpMaxLanes = dpcd_reg_read(hwPin, DP_MAX_LANE_COUNT);
uint8 sandbox = dpcd_reg_read(hwPin, DP_MAX_LANE_COUNT);
radeon_shared_info &info = *gInfo->shared_info;
bool dpTPS3Supported = false;
if (info.dceMajor >= 5 && (dpMaxLanes & DP_TPS3_SUPPORTED) != 0)
if (info.dceMajor >= 5 && (sandbox & DP_TPS3_SUPPORTED) != 0)
dpTPS3Supported = true;
// power up the DP sink
if (gDPInfo[connectorIndex]->dpConfig[0] >= 0x11)
// DisplayPort training initialization
// Power up the DP sink
if (gDPInfo[connectorIndex]->config[0] >= 0x11)
dpcd_reg_write(hwPin, DP_SET_POWER, DP_SET_POWER_D0);
// possibly enable downspread on the sink
if (gDPInfo[connectorIndex]->dpConfig[3] & 0x1)
// Possibly enable downspread on the sink
if ((gDPInfo[connectorIndex]->config[3] & 0x1) != 0)
dpcd_reg_write(hwPin, DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5);
else
dpcd_reg_write(hwPin, DP_DOWNSPREAD_CTRL, 0);
encoder_dig_setup(connectorIndex, 0,
ATOM_ENCODER_CMD_SETUP_PANEL_MODE);
if (gDPInfo[connectorIndex]->config[0] >= 0x11)
sandbox |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
dpcd_reg_write(hwPin, DP_LANE_COUNT_SET, sandbox);
// Set the link rate on the DP sink
sandbox = dp_get_link_clock_encode(gDPInfo[connectorIndex]->clock);
dpcd_reg_write(hwPin, DP_LINK_BW_SET, sandbox);
// Start link training on source
if (info.dceMajor >= 4 || !dpUseEncoder) {
encoder_dig_setup(connectorIndex, 0,
ATOM_ENCODER_CMD_DP_LINK_TRAINING_START);
} else {
ERROR("%s: TODO: cannot use AtomBIOS DPEncoderService on card!\n",
__func__);
}
/* disable the training pattern on the sink */
dpcd_reg_write(hwPin, DP_TRAINING_PATTERN_SET,
DP_TRAINING_PATTERN_DISABLE);
// TODO: dp_link_train_cr
// TODO: dp_link_train_ce
snooze(400);
/* disable the training pattern on the sink */
dpcd_reg_write(hwPin, DP_TRAINING_PATTERN_SET,
DP_TRAINING_PATTERN_DISABLE);
/* disable the training pattern on the source */
if (info.dceMajor >= 4 || !dpUseEncoder) {
encoder_dig_setup(connectorIndex, 0,
ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
} else {
ERROR("%s: TODO: cannot use AtomBIOS DPEncoderService on card!\n",
__func__);
}
return B_OK;
}
@@ -9,9 +9,12 @@
#define RADEON_HD_DISPLAYPORT_H
#include <create_display_modes.h>
#include <stdint.h>
#include <SupportDefs.h>
#include "displayport_reg.h"
int dp_aux_write(uint32 hwPin, uint16 address, uint8* send,
uint8 sendBytes, uint8 delay);
@@ -23,8 +26,11 @@ status_t dp_aux_get_i2c_byte(uint32 hwPin, uint16 address,
uint8* data, bool end);
uint32 dp_get_link_clock(uint32 connectorIndex);
uint32 dp_get_link_clock_encode(uint32 dpLinkClock);
uint32 dp_get_link_clock_decode(uint32 dpLinkClock);
void dp_setup_connectors();
status_t dp_link_train(uint32 connectorIndex);
status_t dp_link_train(uint8 crtcID, display_mode* mode);
#endif /* RADEON_HD_DISPLAYPORT_H */
+162 -135
View File
@@ -17,7 +17,9 @@
#include "accelerant.h"
#include "accelerant_protos.h"
#include "bios.h"
#include "connector.h"
#include "display.h"
#include "displayport.h"
#include "utility.h"
@@ -113,7 +115,7 @@ encoder_assign_crtc(uint8 crtcID)
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
switch (encoder_pick_dig(crtcID)) {
switch (encoder_pick_dig(connectorIndex)) {
case 0:
args.v2.ucEncoderID
= ASIC_INT_DIG1_ENCODER_ID;
@@ -178,13 +180,21 @@ encoder_assign_crtc(uint8 crtcID)
uint32
encoder_pick_dig(uint8 crtcID)
encoder_pick_dig(uint32 connectorIndex)
{
TRACE("%s\n", __func__);
radeon_shared_info &info = *gInfo->shared_info;
uint32 connectorIndex = gDisplay[crtcID]->connectorIndex;
uint32 encoderID = gConnector[connectorIndex]->encoder.objectID;
// obtain assigned CRT
uint32 crtcID;
for (crtcID = 0; crtcID < MAX_DISPLAY; crtcID++) {
if (gDisplay[crtcID]->active != true)
continue;
if (gDisplay[crtcID]->connectorIndex == connectorIndex)
break;
}
bool linkB = gConnector[connectorIndex]->encoder.linkEnumeration
== GRAPH_OBJECT_ENUM_ID2 ? true : false;
@@ -405,6 +415,9 @@ encoder_digital_setup(uint32 connectorIndex, uint32 pixelClock, int command)
union lvdsEncoderControl args;
memset(&args, 0, sizeof(args));
TRACE("%s: table %" B_PRIu8 ".%" B_PRIu8 "\n", __func__,
tableMajor, tableMinor);
switch (tableMajor) {
case 1:
case 2:
@@ -499,10 +512,10 @@ encoder_dig_setup(uint32 connectorIndex, uint32 pixelClock, int command)
if (info.dceMajor > 4)
index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl);
else {
if (1) // TODO: pick dig encoder
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
else
if (encoder_pick_dig(connectorIndex))
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
else
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
}
// Table verson
@@ -525,124 +538,140 @@ encoder_dig_setup(uint32 connectorIndex, uint32 pixelClock, int command)
union digEncoderControl args;
memset(&args, 0, sizeof(args));
args.v1.ucAction = command;
args.v1.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
uint32 encoderID = gConnector[connectorIndex]->encoder.objectID;
bool isDPBridge = gConnector[connectorIndex]->encoder.isDPBridge;
bool linkB = gConnector[connectorIndex]->encoder.linkEnumeration
== GRAPH_OBJECT_ENUM_ID2 ? true : false;
// determine DP panel mode
uint32 panelMode;
if (info.dceMajor >= 4 && isDPBridge) {
if (encoderID == ENCODER_OBJECT_ID_NUTMEG)
panelMode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
else {
// aka ENCODER_OBJECT_ID_TRAVIS or VIDEO_CONNECTOR_EDP
panelMode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
}
} else
panelMode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
#if 0
if (command == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) {
if (info.dceMajor >= 4 && 0) // TODO: 0 == if DP bridge
args.v3.ucPanelMode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
else
args.v3.ucPanelMode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
} else {
args.v1.ucEncoderMode = display_get_encoder_mode(connectorIndex);
if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP
|| args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST) {
args.v1.ucLaneNum = dp_lane_count;
} else if (pixelClock > 165000)
args.v1.ucLaneNum = 8;
else
args.v1.ucLaneNum = 4;
if (info.dceMajor >= 5) {
if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP
|| args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST) {
if (dpClock == 270000) {
args.v1.ucConfig
|= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
} else if (dpClock == 540000) {
args.v1.ucConfig
|= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;
}
}
args.v4.acConfig.ucDigSel = dig->dig_encoder;
switch (bpc) {
case 0:
args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE;
break;
case 6:
args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR;
break;
case 8:
default:
args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
break;
case 10:
args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR;
break;
case 12:
args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR;
break;
case 16:
args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR;
break;
}
//if (hpdID == RADEON_HPD_NONE)
if (1)
args.v4.ucHPD_ID = 0;
else
args.v4.ucHPD_ID = hpd_id + 1;
} else if (info.dceMajor >= 4) {
if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP
&& dp_clock == 270000) {
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
}
args.v3.acConfig.ucDigSel = dig->dig_encoder;
switch (bpc) {
case 0:
args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE;
break;
case 6:
args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR;
break;
case 8:
default:
args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
break;
case 10:
args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR;
break;
case 12:
args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR;
break;
case 16:
args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR;
break;
}
} else {
if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP
&& dp_clock == 270000) {
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
}
#endif
switch (encoderID) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
break;
}
#if 0
if (dig->linkb)
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
else
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
uint32 encoderID = gConnector[connectorIndex]->encoder.objectID;
if (gConnector[connectorIndex]->type == VIDEO_CONNECTOR_EDP) {
uint8 temp = dpcd_read_reg(hwPin, DP_EDP_CONFIGURATION_CAP);
if ((temp & 1) != 0)
panelMode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
}
#endif
return atom_execute_table(gAtomContext, index, (uint32*)&args);
TRACE("%s: table %" B_PRIu8 ".%" B_PRIu8 "\n", __func__,
tableMajor, tableMinor);
uint32 dpClock = dp_get_link_clock(connectorIndex);
switch (tableMinor) {
case 1:
args.v1.ucAction = command;
args.v1.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
if (command == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)
args.v3.ucPanelMode = panelMode;
else {
args.v1.ucEncoderMode
= display_get_encoder_mode(connectorIndex);
}
if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP
|| args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)
&& dpClock == 270000) {
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
}
switch (encoderID) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
break;
}
if (linkB)
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
else
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
break;
case 2:
case 3:
args.v1.ucAction = command;
args.v1.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
if (command == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)
args.v3.ucPanelMode = panelMode;
else {
args.v3.ucEncoderMode
= display_get_encoder_mode(connectorIndex);
}
if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP
|| args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST) {
args.v1.ucLaneNum = gDPInfo[connectorIndex]->laneCount;
} else if (pixelClock > 165000)
args.v1.ucLaneNum = 8;
else
args.v1.ucLaneNum = 4;
if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP
|| args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)
&& dpClock == 270000) {
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
}
args.v3.acConfig.ucDigSel = encoder_pick_dig(connectorIndex);
// TODO: get BPC
switch (8) {
case 0:
args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE;
break;
case 6:
args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR;
break;
case 8:
default:
args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
break;
case 10:
args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR;
break;
case 12:
args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR;
break;
case 16:
args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR;
break;
}
break;
case 4:
args.v4.ucHPD_ID = 0;
ERROR("%s: tableMinor 4 TODO!\n", __func__);
break;
}
status_t result = atom_execute_table(gAtomContext, index, (uint32*)&args);
#if 0
if (gConnector[connectorIndex]->type == VIDEO_CONNECTOR_EDP
&& panelMode == DP_PANEL_MODE_INTERNAL_DP2_MODE) {
dpcd_write_reg(hwPin, DP_EDP_CONFIGURATION_SET, 1);
}
#endif
return result;
}
@@ -673,6 +702,8 @@ encoder_external_setup(uint32 connectorIndex, uint32 pixelClock, int command)
= (gConnector[connectorIndex]->objectID & OBJECT_ID_MASK)
>> OBJECT_ID_SHIFT;
TRACE("%s: table %" B_PRIu8 ".%" B_PRIu8 "\n", __func__,
tableMajor, tableMinor);
switch (tableMajor) {
case 1:
// no options needed on table 1.x
@@ -1053,7 +1084,7 @@ encoder_dpms_scratch(uint8 crtcID, bool power)
void
encoder_dpms_set(uint8 crtcID, uint8 encoderID, int mode)
{
int index = 0;
int index = -1;
radeon_shared_info &info = *gInfo->shared_info;
DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
@@ -1116,29 +1147,25 @@ encoder_dpms_set(uint8 crtcID, uint8 encoderID, int mode)
switch (mode) {
case B_DPMS_ON:
args.ucAction = ATOM_ENABLE;
atom_execute_table(gAtomContext, index, (uint32*)&args);
if (info.dceMajor < 5) {
if ((encoderFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) {
args.ucAction = ATOM_LCD_BLON;
atom_execute_table(gAtomContext, index, (uint32*)&args);
}
encoder_dpms_scratch(crtcID, true);
}
break;
case B_DPMS_STAND_BY:
case B_DPMS_SUSPEND:
case B_DPMS_OFF:
args.ucAction = ATOM_DISABLE;
atom_execute_table(gAtomContext, index, (uint32*)&args);
if (info.dceMajor < 5) {
if ((encoderFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) {
args.ucAction = ATOM_LCD_BLOFF;
atom_execute_table(gAtomContext, index, (uint32*)&args);
}
encoder_dpms_scratch(crtcID, false);
}
break;
}
if (index >= 0) {
atom_execute_table(gAtomContext, index, (uint32*)&args);
if (info.dceMajor < 5) {
if ((encoderFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) {
args.ucAction = args.ucAction == ATOM_DISABLE
? ATOM_LCD_BLOFF : ATOM_LCD_BLON;
atom_execute_table(gAtomContext, index, (uint32*)&args);
}
encoder_dpms_scratch(crtcID, true);
}
}
}
+1 -1
View File
@@ -13,7 +13,7 @@
void encoder_assign_crtc(uint8 crtcID);
uint32 encoder_pick_dig(uint8 crtcID);
uint32 encoder_pick_dig(uint32 connectorIndex);
void encoder_apply_quirks(uint8 crtcID);
void encoder_mode_set(uint8 id, uint32 pixelClock);
@@ -21,7 +21,9 @@
#include "accelerant.h"
#include "accelerant_protos.h"
#include "bios.h"
#include "connector.h"
#include "display.h"
#include "displayport.h"
#include "encoder.h"
#include "pll.h"
#include "utility.h"
@@ -204,8 +206,23 @@ radeon_set_display_mode(display_mode* mode)
display_crtc_lock(id, ATOM_DISABLE);
// *** encoder commit
// handle DisplayPort link training
if (connector_is_dp(connectorIndex)) {
if (info.dceMajor >= 4)
encoder_dig_setup(connectorIndex,
ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
dp_link_train(id, mode);
if (info.dceMajor >= 4)
encoder_dig_setup(connectorIndex,
ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
}
encoder_dpms_set(id, gConnector[connectorIndex]->encoder.objectID,
B_DPMS_ON);
encoder_output_lock(false);
}
+3 -3
View File
@@ -492,7 +492,7 @@ pll_set(uint8 pllID, uint32 pixelClock, uint8 crtcID)
int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
atom_parse_cmd_header(gAtomContext, index, &tableMajor, &tableMinor);
uint32 bitsPerChannel = 8;
uint32 bitsPerColor = 8;
// TODO: Digital Depth, EDID 1.4+ on digital displays
// isn't in Haiku edid common code?
@@ -558,7 +558,7 @@ pll_set(uint8 pllID, uint32 pixelClock, uint8 crtcID)
args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
// if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
// args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_REF_DIV_SRC;
switch (bitsPerChannel) {
switch (bitsPerColor) {
case 8:
default:
args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
@@ -584,7 +584,7 @@ pll_set(uint8 pllID, uint32 pixelClock, uint8 crtcID)
args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
// if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
// args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
switch (bitsPerChannel) {
switch (bitsPerColor) {
case 8:
default:
args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;