/* * Copyright 2012-15 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: AMD *
*/
result = bp->funcs->transmitter_control(bp, cntl);
return result;
}
staticvoid enable_phy_bypass_mode( struct dce110_link_encoder *enc110, bool enable)
{ /* This register resides in DP back end block;
* transmitter is used for the offset */
REG_UPDATE(DP_DPHY_CNTL, DPHY_BYPASS, enable);
}
staticvoid disable_prbs_symbols( struct dce110_link_encoder *enc110, bool disable)
{ /* This register resides in DP back end block;
* transmitter is used for the offset */
staticvoid program_pattern_symbols( struct dce110_link_encoder *enc110,
uint16_t pattern_symbols[8])
{ /* This register resides in DP back end block;
* transmitter is used for the offset */
/* Enable phy bypass mode to enable the test pattern */
enable_phy_bypass_mode(enc110, true);
}
staticvoid set_link_training_complete( struct dce110_link_encoder *enc110, bool complete)
{ /* This register resides in DP back end block;
* transmitter is used for the offset */
switch (value) { case DCE110_DIG_FE_SOURCE_SELECT_DIGA:
result = ENGINE_ID_DIGA; break; case DCE110_DIG_FE_SOURCE_SELECT_DIGB:
result = ENGINE_ID_DIGB; break; case DCE110_DIG_FE_SOURCE_SELECT_DIGC:
result = ENGINE_ID_DIGC; break; case DCE110_DIG_FE_SOURCE_SELECT_DIGD:
result = ENGINE_ID_DIGD; break; case DCE110_DIG_FE_SOURCE_SELECT_DIGE:
result = ENGINE_ID_DIGE; break; case DCE110_DIG_FE_SOURCE_SELECT_DIGF:
result = ENGINE_ID_DIGF; break; case DCE110_DIG_FE_SOURCE_SELECT_DIGG:
result = ENGINE_ID_DIGG; break; default: // invalid source select DIG
result = ENGINE_ID_UNKNOWN;
}
/* previously there is a register DP_HBR2_EYE_PATTERN * that is enabled to get the pattern. * But it does not work with the latest spec change, * so we are programming the following registers manually. * * The following settings have been confirmed
* by Nick Chorney and Sandra Liu */
/* Disable PHY Bypass mode to setup the test pattern */
/* previously there is a register DP_HBR2_EYE_PATTERN * that is enabled to get the pattern. * But it does not work with the latest spec change, * so we are programming the following registers manually. * * The following settings have been confirmed
* by Nick Chorney and Sandra Liu */
/* Disable PHY Bypass mode to setup the test pattern */
/* restore LINK_FRAMING_CNTL and DPHY_SCRAMBLER_BS_COUNT * in case we were doing HBR2 compliance pattern before
*/
REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
DP_IDLE_BS_INTERVAL, 0x2000,
DP_VBID_DISABLE, 0,
DP_VID_ENHANCED_FRAME_MODE, 1);
/* restore LINK_FRAMING_CNTL * in case we were doing HBR2 compliance pattern before
*/
REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
DP_IDLE_BS_INTERVAL, 0x2000,
DP_VBID_DISABLE, 0,
DP_VID_ENHANCED_FRAME_MODE, 1);
/* DCE6 has no DP_DPHY_SCRAM_CNTL register, skip DPHY_SCRAMBLER_BS_COUNT restore */
/* set link training complete */
set_link_training_complete(enc110, true);
/* Disable PHY Bypass mode to setup the test pattern */
enable_phy_bypass_mode(enc110, false);
if (exit_link_training_required)
REG_UPDATE(DP_DPHY_FAST_TRAINING,
DPHY_RX_FAST_TRAINING_CAPABLE, 1); else {
REG_UPDATE(DP_DPHY_FAST_TRAINING,
DPHY_RX_FAST_TRAINING_CAPABLE, 0); /*In DCE 11, we are able to pre-program a Force SR register * to be able to trigger SR symbol after 5 idle patterns * transmitted. Upon PSR Exit, DMCU can trigger * DPHY_LOAD_BS_COUNT_START = 1. Upon writing 1 to * DPHY_LOAD_BS_COUNT_START and the internal counter * reaches DPHY_LOAD_BS_COUNT, the next BS symbol will be * replaced by SR symbol once.
*/
if (signal == SIGNAL_TYPE_DVI_DUAL_LINK)
max_pixel_clock *= 2;
/* This handles the case of HDMI downgrade to DVI we don't want to * we don't want to cap the pixel clock if the DDI is not DVI.
*/ if (connector_signal != SIGNAL_TYPE_DVI_DUAL_LINK &&
connector_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
max_pixel_clock = enc110->base.features.max_hdmi_pixel_clock;
/* DVI only support RGB pixel encoding */ if (crtc_timing->pixel_encoding != PIXEL_ENCODING_RGB) returnfalse;
/*connect DVI via adpater's HDMI connector*/ if ((connector_signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
connector_signal == SIGNAL_TYPE_HDMI_TYPE_A) &&
signal != SIGNAL_TYPE_HDMI_TYPE_A &&
crtc_timing->pix_clk_100hz > (TMDS_MAX_PIXEL_CLOCK * 10)) returnfalse; if (crtc_timing->pix_clk_100hz < (TMDS_MIN_PIXEL_CLOCK * 10)) returnfalse;
if (crtc_timing->pix_clk_100hz > (max_pixel_clock * 10)) returnfalse;
/* DVI supports 6/8bpp single-link and 10/16bpp dual-link */ switch (crtc_timing->display_color_depth) { case COLOR_DEPTH_666: case COLOR_DEPTH_888: break; case COLOR_DEPTH_101010: case COLOR_DEPTH_161616: if (signal != SIGNAL_TYPE_DVI_DUAL_LINK) returnfalse; break; default: returnfalse;
}
if (max_deep_color < crtc_timing->display_color_depth) returnfalse;
if (crtc_timing->display_color_depth < COLOR_DEPTH_888) returnfalse; if (adjusted_pix_clk_khz < TMDS_MIN_PIXEL_CLOCK) returnfalse;
if ((adjusted_pix_clk_khz == 0) ||
(adjusted_pix_clk_khz > enc110->base.features.max_hdmi_pixel_clock)) returnfalse;
/* DCE11 HW does not support 420 */ if (!enc110->base.features.hdmi_ycbcr420_supported &&
crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) returnfalse;
if ((!enc110->base.features.flags.bits.HDMI_6GB_EN ||
enc110->base.ctx->dc->debug.hdmi20_disable) &&
adjusted_pix_clk_khz >= 300000) returnfalse; if (enc110->base.ctx->dc->debug.hdmi20_disable &&
crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) returnfalse; returntrue;
}
/* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE. * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY. * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS. * Prefer DIG assignment is decided by board design. * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design * and VBIOS will filter out 7 UNIPHY for DCE 8.0. * By this, adding DIGG should not hurt DCE 8.0. * This will let DCE 8.1 share DCE 8.0 as much as possible
*/
if (enc110->base.connector.id == CONNECTOR_ID_EDP)
cntl.signal = SIGNAL_TYPE_EDP;
result = link_transmitter_control(enc110, &cntl);
if (result != BP_RESULT_OK) {
DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
__func__);
BREAK_TO_DEBUGGER(); return;
}
if (enc110->base.connector.id == CONNECTOR_ID_LVDS) {
cntl.action = TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS;
result = link_transmitter_control(enc110, &cntl);
ASSERT(result == BP_RESULT_OK);
}
aux_initialize(enc110);
/* reinitialize HPD. * hpd_initialize() will pass DIG_FE id to HW context. * All other routine within HW context will use fe_engine_offset * as DIG_FE id even caller pass DIG_FE id.
* So this routine must be called first. */
hpd_initialize(enc110);
}
/* number_of_lanes is used for pixel clock adjust, * but it's not passed to asic_control. * We need to set number of lanes manually.
*/
configure_encoder(enc110, link_settings);
cntl.connector_obj_id = enc110->base.connector;
cntl.action = TRANSMITTER_CONTROL_ENABLE;
cntl.engine_id = enc->preferred_engine;
cntl.transmitter = enc110->base.transmitter;
cntl.pll_id = clock_source;
cntl.signal = SIGNAL_TYPE_DISPLAY_PORT;
cntl.lanes_number = link_settings->lane_count;
cntl.hpd_sel = enc110->base.hpd_source;
cntl.pixel_clock = link_settings->link_rate
* LINK_RATE_REF_FREQ_IN_KHZ; /* TODO: check if undefined works */
cntl.color_depth = COLOR_DEPTH_UNDEFINED;
result = link_transmitter_control(enc110, &cntl);
if (result != BP_RESULT_OK) {
DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
__func__);
BREAK_TO_DEBUGGER();
}
}
/* number_of_lanes is used for pixel clock adjust, * but it's not passed to asic_control. * We need to set number of lanes manually.
*/
configure_encoder(enc110, link_settings);
/* number_of_lanes is used for pixel clock adjust, * but it's not passed to asic_control. * We need to set number of lanes manually.
*/
dce60_configure_encoder(enc110, link_settings);
cntl.connector_obj_id = enc110->base.connector;
cntl.action = TRANSMITTER_CONTROL_ENABLE;
cntl.engine_id = enc->preferred_engine;
cntl.transmitter = enc110->base.transmitter;
cntl.pll_id = clock_source;
cntl.signal = SIGNAL_TYPE_DISPLAY_PORT;
cntl.lanes_number = link_settings->lane_count;
cntl.hpd_sel = enc110->base.hpd_source;
cntl.pixel_clock = link_settings->link_rate
* LINK_RATE_REF_FREQ_IN_KHZ; /* TODO: check if undefined works */
cntl.color_depth = COLOR_DEPTH_UNDEFINED;
result = link_transmitter_control(enc110, &cntl);
if (result != BP_RESULT_OK) {
DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
__func__);
BREAK_TO_DEBUGGER();
}
}
/* number_of_lanes is used for pixel clock adjust, * but it's not passed to asic_control. * We need to set number of lanes manually.
*/
dce60_configure_encoder(enc110, link_settings);
if (!dce110_is_dig_enabled(enc)) { /* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */ return;
} /* Power-down RX and disable GPU PHY should be paired. * Disabling PHY without powering down RX may cause
* symbol lock loss, on which we will get DP Sink interrupt. */
/* There is a case for the DP active dongles * where we want to disable the PHY but keep RX powered, * for those we need to ignore DP Sink interrupt * by checking lane count that has been set
* on the last do_enable_output(). */
/* post cursor 2 setting only applies to HBR2 link rate */ if (link_settings->link_rate == LINK_RATE_HIGH2) { /* this is passed to VBIOS
* to program post cursor 2 level */
/* call VBIOS table to set voltage swing and pre-emphasis */ if (link_transmitter_control(enc110, &cntl) != BP_RESULT_OK) {
DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", __func__);
BREAK_TO_DEBUGGER();
}
}
}
/* set DP PHY test and training patterns */ void dce110_link_encoder_dp_set_phy_pattern( struct link_encoder *enc, conststruct encoder_set_dp_phy_pattern_param *param)
{ struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
switch (param->dp_phy_pattern) { case DP_TEST_PATTERN_TRAINING_PATTERN1:
dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 0); break; case DP_TEST_PATTERN_TRAINING_PATTERN2:
dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 1); break; case DP_TEST_PATTERN_TRAINING_PATTERN3:
dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 2); break; case DP_TEST_PATTERN_TRAINING_PATTERN4:
dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 3); break; case DP_TEST_PATTERN_D102:
set_dp_phy_pattern_d102(enc110); break; case DP_TEST_PATTERN_SYMBOL_ERROR:
set_dp_phy_pattern_symbol_error(enc110); break; case DP_TEST_PATTERN_PRBS7:
set_dp_phy_pattern_prbs7(enc110); break; case DP_TEST_PATTERN_80BIT_CUSTOM:
set_dp_phy_pattern_80bit_custom(
enc110, param->custom_pattern); break; case DP_TEST_PATTERN_CP2520_1:
set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 1); break; case DP_TEST_PATTERN_CP2520_2:
set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 2); break; case DP_TEST_PATTERN_CP2520_3:
set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 3); break; case DP_TEST_PATTERN_VIDEO_MODE: {
set_dp_phy_pattern_passthrough_mode(
enc110, param->dp_panel_mode); break;
}
/* send allocation change trigger (ACT) ? * this step first sends the ACT, * then double buffers the SAT into the hardware
* making the new allocation active on the DP MST mode link */
/* DP_MSE_SAT_UPDATE: * 0 - No Action * 1 - Update SAT with trigger
* 2 - Update SAT without trigger */
/* wait for update to complete * (i.e. DP_MSE_SAT_UPDATE field is reset to 0) * then wait for the transmission * of at least 16 MTP headers on immediate local link. * i.e. DP_MSE_16_MTP_KEEPOUT field (read only) is reset to 0 * a value of 1 indicates that DP MST mode * is in the 16 MTP keepout region after a VC has been added. * MST stream bandwidth (VC rate) can be configured
* after this bit is cleared */
/* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE. * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY. * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS. * Prefer DIG assignment is decided by board design. * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design * and VBIOS will filter out 7 UNIPHY for DCE 8.0. * By this, adding DIGG should not hurt DCE 8.0. * This will let DCE 8.1 share DCE 8.0 as much as possible
*/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.