drm/amd/display: move dp cts functions from dc_link_dp to link_dp_cts
Create new files link_dp_cts.c and link_dp_cts.h, and move DP cts functions into them. Reviewed-by: George Shen <George.Shen@amd.com> Acked-by: Alan Liu <HaoPing.Liu@amd.com> Signed-off-by: Wenjing Liu <wenjing.liu@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
c5a31f178e
commit
de3fb39017
@ -4095,110 +4095,6 @@ void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
|
||||
dc->hwss.set_avmute(pipe_ctx, enable);
|
||||
}
|
||||
|
||||
void dc_link_set_drive_settings(struct dc *dc,
|
||||
struct link_training_settings *lt_settings,
|
||||
const struct dc_link *link)
|
||||
{
|
||||
|
||||
int i;
|
||||
struct link_resource link_res;
|
||||
|
||||
for (i = 0; i < dc->link_count; i++)
|
||||
if (dc->links[i] == link)
|
||||
break;
|
||||
|
||||
if (i >= dc->link_count)
|
||||
ASSERT_CRITICAL(false);
|
||||
|
||||
dc_link_get_cur_link_res(link, &link_res);
|
||||
dp_set_drive_settings(dc->links[i], &link_res, lt_settings);
|
||||
}
|
||||
|
||||
void dc_link_set_preferred_link_settings(struct dc *dc,
|
||||
struct dc_link_settings *link_setting,
|
||||
struct dc_link *link)
|
||||
{
|
||||
int i;
|
||||
struct pipe_ctx *pipe;
|
||||
struct dc_stream_state *link_stream;
|
||||
struct dc_link_settings store_settings = *link_setting;
|
||||
|
||||
link->preferred_link_setting = store_settings;
|
||||
|
||||
/* Retrain with preferred link settings only relevant for
|
||||
* DP signal type
|
||||
* Check for non-DP signal or if passive dongle present
|
||||
*/
|
||||
if (!dc_is_dp_signal(link->connector_signal) ||
|
||||
link->dongle_max_pix_clk > 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe->stream && pipe->stream->link) {
|
||||
if (pipe->stream->link == link) {
|
||||
link_stream = pipe->stream;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Stream not found */
|
||||
if (i == MAX_PIPES)
|
||||
return;
|
||||
|
||||
/* Cannot retrain link if backend is off */
|
||||
if (link_stream->dpms_off)
|
||||
return;
|
||||
|
||||
if (link_decide_link_settings(link_stream, &store_settings))
|
||||
dp_retrain_link_dp_test(link, &store_settings, false);
|
||||
}
|
||||
|
||||
void dc_link_set_preferred_training_settings(struct dc *dc,
|
||||
struct dc_link_settings *link_setting,
|
||||
struct dc_link_training_overrides *lt_overrides,
|
||||
struct dc_link *link,
|
||||
bool skip_immediate_retrain)
|
||||
{
|
||||
if (lt_overrides != NULL)
|
||||
link->preferred_training_settings = *lt_overrides;
|
||||
else
|
||||
memset(&link->preferred_training_settings, 0, sizeof(link->preferred_training_settings));
|
||||
|
||||
if (link_setting != NULL) {
|
||||
link->preferred_link_setting = *link_setting;
|
||||
} else {
|
||||
link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN;
|
||||
link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
|
||||
link->type == dc_connection_mst_branch)
|
||||
dm_helpers_dp_mst_update_branch_bandwidth(dc->ctx, link);
|
||||
|
||||
/* Retrain now, or wait until next stream update to apply */
|
||||
if (skip_immediate_retrain == false)
|
||||
dc_link_set_preferred_link_settings(dc, &link->preferred_link_setting, link);
|
||||
}
|
||||
|
||||
void dc_link_set_test_pattern(struct dc_link *link,
|
||||
enum dp_test_pattern test_pattern,
|
||||
enum dp_test_pattern_color_space test_pattern_color_space,
|
||||
const struct link_training_settings *p_link_settings,
|
||||
const unsigned char *p_custom_pattern,
|
||||
unsigned int cust_pattern_size)
|
||||
{
|
||||
if (link != NULL)
|
||||
dc_link_dp_set_test_pattern(
|
||||
link,
|
||||
test_pattern,
|
||||
test_pattern_color_space,
|
||||
p_link_settings,
|
||||
p_custom_pattern,
|
||||
cust_pattern_size);
|
||||
}
|
||||
|
||||
uint32_t dc_link_bandwidth_kbps(
|
||||
const struct dc_link *link,
|
||||
const struct dc_link_settings *link_setting)
|
||||
|
@ -104,884 +104,6 @@ bool dp_validate_mode_timing(
|
||||
return false;
|
||||
}
|
||||
|
||||
static enum dc_link_rate get_link_rate_from_test_link_rate(uint8_t test_rate)
|
||||
{
|
||||
switch (test_rate) {
|
||||
case DP_TEST_LINK_RATE_RBR:
|
||||
return LINK_RATE_LOW;
|
||||
case DP_TEST_LINK_RATE_HBR:
|
||||
return LINK_RATE_HIGH;
|
||||
case DP_TEST_LINK_RATE_HBR2:
|
||||
return LINK_RATE_HIGH2;
|
||||
case DP_TEST_LINK_RATE_HBR3:
|
||||
return LINK_RATE_HIGH3;
|
||||
case DP_TEST_LINK_RATE_UHBR10:
|
||||
return LINK_RATE_UHBR10;
|
||||
case DP_TEST_LINK_RATE_UHBR20:
|
||||
return LINK_RATE_UHBR20;
|
||||
case DP_TEST_LINK_RATE_UHBR13_5:
|
||||
return LINK_RATE_UHBR13_5;
|
||||
default:
|
||||
return LINK_RATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void dp_test_send_link_training(struct dc_link *link)
|
||||
{
|
||||
struct dc_link_settings link_settings = {0};
|
||||
uint8_t test_rate = 0;
|
||||
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TEST_LANE_COUNT,
|
||||
(unsigned char *)(&link_settings.lane_count),
|
||||
1);
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TEST_LINK_RATE,
|
||||
&test_rate,
|
||||
1);
|
||||
link_settings.link_rate = get_link_rate_from_test_link_rate(test_rate);
|
||||
|
||||
/* Set preferred link settings */
|
||||
link->verified_link_cap.lane_count = link_settings.lane_count;
|
||||
link->verified_link_cap.link_rate = link_settings.link_rate;
|
||||
|
||||
dp_retrain_link_dp_test(link, &link_settings, false);
|
||||
}
|
||||
|
||||
static bool is_dp_phy_sqaure_pattern(enum dp_test_pattern test_pattern)
|
||||
{
|
||||
return (DP_TEST_PATTERN_SQUARE_BEGIN <= test_pattern &&
|
||||
test_pattern <= DP_TEST_PATTERN_SQUARE_END);
|
||||
}
|
||||
|
||||
/* TODO Raven hbr2 compliance eye output is unstable
|
||||
* (toggling on and off) with debugger break
|
||||
* This caueses intermittent PHY automation failure
|
||||
* Need to look into the root cause */
|
||||
static void dp_test_send_phy_test_pattern(struct dc_link *link)
|
||||
{
|
||||
union phy_test_pattern dpcd_test_pattern;
|
||||
union lane_adjust dpcd_lane_adjustment[2];
|
||||
unsigned char dpcd_post_cursor_2_adjustment = 0;
|
||||
unsigned char test_pattern_buffer[
|
||||
(DP_TEST_264BIT_CUSTOM_PATTERN_263_256 -
|
||||
DP_TEST_264BIT_CUSTOM_PATTERN_7_0)+1] = {0};
|
||||
unsigned int test_pattern_size = 0;
|
||||
enum dp_test_pattern test_pattern;
|
||||
union lane_adjust dpcd_lane_adjust;
|
||||
unsigned int lane;
|
||||
struct link_training_settings link_training_settings;
|
||||
unsigned char no_preshoot = 0;
|
||||
unsigned char no_deemphasis = 0;
|
||||
|
||||
dpcd_test_pattern.raw = 0;
|
||||
memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
|
||||
memset(&link_training_settings, 0, sizeof(link_training_settings));
|
||||
|
||||
/* get phy test pattern and pattern parameters from DP receiver */
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_PHY_TEST_PATTERN,
|
||||
&dpcd_test_pattern.raw,
|
||||
sizeof(dpcd_test_pattern));
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_ADJUST_REQUEST_LANE0_1,
|
||||
&dpcd_lane_adjustment[0].raw,
|
||||
sizeof(dpcd_lane_adjustment));
|
||||
|
||||
/* prepare link training settings */
|
||||
link_training_settings.link_settings = link->cur_link_settings;
|
||||
|
||||
link_training_settings.lttpr_mode = dc_link_decide_lttpr_mode(link, &link->cur_link_settings);
|
||||
|
||||
if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
|
||||
link_training_settings.lttpr_mode == LTTPR_MODE_TRANSPARENT)
|
||||
dp_fixed_vs_pe_read_lane_adjust(
|
||||
link,
|
||||
link_training_settings.dpcd_lane_settings);
|
||||
|
||||
/*get post cursor 2 parameters
|
||||
* For DP 1.1a or eariler, this DPCD register's value is 0
|
||||
* For DP 1.2 or later:
|
||||
* Bits 1:0 = POST_CURSOR2_LANE0; Bits 3:2 = POST_CURSOR2_LANE1
|
||||
* Bits 5:4 = POST_CURSOR2_LANE2; Bits 7:6 = POST_CURSOR2_LANE3
|
||||
*/
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_ADJUST_REQUEST_POST_CURSOR2,
|
||||
&dpcd_post_cursor_2_adjustment,
|
||||
sizeof(dpcd_post_cursor_2_adjustment));
|
||||
|
||||
/* translate request */
|
||||
switch (dpcd_test_pattern.bits.PATTERN) {
|
||||
case PHY_TEST_PATTERN_D10_2:
|
||||
test_pattern = DP_TEST_PATTERN_D102;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_SYMBOL_ERROR:
|
||||
test_pattern = DP_TEST_PATTERN_SYMBOL_ERROR;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_PRBS7:
|
||||
test_pattern = DP_TEST_PATTERN_PRBS7;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_80BIT_CUSTOM:
|
||||
test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_CP2520_1:
|
||||
/* CP2520 pattern is unstable, temporarily use TPS4 instead */
|
||||
test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
|
||||
DP_TEST_PATTERN_TRAINING_PATTERN4 :
|
||||
DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_CP2520_2:
|
||||
/* CP2520 pattern is unstable, temporarily use TPS4 instead */
|
||||
test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
|
||||
DP_TEST_PATTERN_TRAINING_PATTERN4 :
|
||||
DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_CP2520_3:
|
||||
test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_128b_132b_TPS1:
|
||||
test_pattern = DP_TEST_PATTERN_128b_132b_TPS1;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_128b_132b_TPS2:
|
||||
test_pattern = DP_TEST_PATTERN_128b_132b_TPS2;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_PRBS9:
|
||||
test_pattern = DP_TEST_PATTERN_PRBS9;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_PRBS11:
|
||||
test_pattern = DP_TEST_PATTERN_PRBS11;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_PRBS15:
|
||||
test_pattern = DP_TEST_PATTERN_PRBS15;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_PRBS23:
|
||||
test_pattern = DP_TEST_PATTERN_PRBS23;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_PRBS31:
|
||||
test_pattern = DP_TEST_PATTERN_PRBS31;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_264BIT_CUSTOM:
|
||||
test_pattern = DP_TEST_PATTERN_264BIT_CUSTOM;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_SQUARE:
|
||||
test_pattern = DP_TEST_PATTERN_SQUARE;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED:
|
||||
test_pattern = DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED;
|
||||
no_preshoot = 1;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED:
|
||||
test_pattern = DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED;
|
||||
no_deemphasis = 1;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED:
|
||||
test_pattern = DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED;
|
||||
no_preshoot = 1;
|
||||
no_deemphasis = 1;
|
||||
break;
|
||||
default:
|
||||
test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM) {
|
||||
test_pattern_size = (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
|
||||
DP_TEST_80BIT_CUSTOM_PATTERN_7_0) + 1;
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
|
||||
test_pattern_buffer,
|
||||
test_pattern_size);
|
||||
}
|
||||
|
||||
if (is_dp_phy_sqaure_pattern(test_pattern)) {
|
||||
test_pattern_size = 1; // Square pattern data is 1 byte (DP spec)
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_PHY_SQUARE_PATTERN,
|
||||
test_pattern_buffer,
|
||||
test_pattern_size);
|
||||
}
|
||||
|
||||
if (test_pattern == DP_TEST_PATTERN_264BIT_CUSTOM) {
|
||||
test_pattern_size = (DP_TEST_264BIT_CUSTOM_PATTERN_263_256-
|
||||
DP_TEST_264BIT_CUSTOM_PATTERN_7_0) + 1;
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TEST_264BIT_CUSTOM_PATTERN_7_0,
|
||||
test_pattern_buffer,
|
||||
test_pattern_size);
|
||||
}
|
||||
|
||||
for (lane = 0; lane <
|
||||
(unsigned int)(link->cur_link_settings.lane_count);
|
||||
lane++) {
|
||||
dpcd_lane_adjust.raw =
|
||||
dp_get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane);
|
||||
if (link_dp_get_encoding_format(&link->cur_link_settings) ==
|
||||
DP_8b_10b_ENCODING) {
|
||||
link_training_settings.hw_lane_settings[lane].VOLTAGE_SWING =
|
||||
(enum dc_voltage_swing)
|
||||
(dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
|
||||
link_training_settings.hw_lane_settings[lane].PRE_EMPHASIS =
|
||||
(enum dc_pre_emphasis)
|
||||
(dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
|
||||
link_training_settings.hw_lane_settings[lane].POST_CURSOR2 =
|
||||
(enum dc_post_cursor2)
|
||||
((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
|
||||
} else if (link_dp_get_encoding_format(&link->cur_link_settings) ==
|
||||
DP_128b_132b_ENCODING) {
|
||||
link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.level =
|
||||
dpcd_lane_adjust.tx_ffe.PRESET_VALUE;
|
||||
link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.no_preshoot = no_preshoot;
|
||||
link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.no_deemphasis = no_deemphasis;
|
||||
}
|
||||
}
|
||||
|
||||
dp_hw_to_dpcd_lane_settings(&link_training_settings,
|
||||
link_training_settings.hw_lane_settings,
|
||||
link_training_settings.dpcd_lane_settings);
|
||||
/*Usage: Measure DP physical lane signal
|
||||
* by DP SI test equipment automatically.
|
||||
* PHY test pattern request is generated by equipment via HPD interrupt.
|
||||
* HPD needs to be active all the time. HPD should be active
|
||||
* all the time. Do not touch it.
|
||||
* forward request to DS
|
||||
*/
|
||||
dc_link_dp_set_test_pattern(
|
||||
link,
|
||||
test_pattern,
|
||||
DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED,
|
||||
&link_training_settings,
|
||||
test_pattern_buffer,
|
||||
test_pattern_size);
|
||||
}
|
||||
|
||||
static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video)
|
||||
{
|
||||
union audio_test_mode dpcd_test_mode = {0};
|
||||
struct audio_test_pattern_type dpcd_pattern_type = {0};
|
||||
union audio_test_pattern_period dpcd_pattern_period[AUDIO_CHANNELS_COUNT] = {0};
|
||||
enum dp_test_pattern test_pattern = DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
|
||||
|
||||
struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
|
||||
struct pipe_ctx *pipe_ctx = &pipes[0];
|
||||
unsigned int channel_count;
|
||||
unsigned int channel = 0;
|
||||
unsigned int modes = 0;
|
||||
unsigned int sampling_rate_in_hz = 0;
|
||||
|
||||
// get audio test mode and test pattern parameters
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TEST_AUDIO_MODE,
|
||||
&dpcd_test_mode.raw,
|
||||
sizeof(dpcd_test_mode));
|
||||
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TEST_AUDIO_PATTERN_TYPE,
|
||||
&dpcd_pattern_type.value,
|
||||
sizeof(dpcd_pattern_type));
|
||||
|
||||
channel_count = min(dpcd_test_mode.bits.channel_count + 1, AUDIO_CHANNELS_COUNT);
|
||||
|
||||
// read pattern periods for requested channels when sawTooth pattern is requested
|
||||
if (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH ||
|
||||
dpcd_pattern_type.value == AUDIO_TEST_PATTERN_OPERATOR_DEFINED) {
|
||||
|
||||
test_pattern = (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH) ?
|
||||
DP_TEST_PATTERN_AUDIO_SAWTOOTH : DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
|
||||
// read period for each channel
|
||||
for (channel = 0; channel < channel_count; channel++) {
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TEST_AUDIO_PERIOD_CH1 + channel,
|
||||
&dpcd_pattern_period[channel].raw,
|
||||
sizeof(dpcd_pattern_period[channel]));
|
||||
}
|
||||
}
|
||||
|
||||
// translate sampling rate
|
||||
switch (dpcd_test_mode.bits.sampling_rate) {
|
||||
case AUDIO_SAMPLING_RATE_32KHZ:
|
||||
sampling_rate_in_hz = 32000;
|
||||
break;
|
||||
case AUDIO_SAMPLING_RATE_44_1KHZ:
|
||||
sampling_rate_in_hz = 44100;
|
||||
break;
|
||||
case AUDIO_SAMPLING_RATE_48KHZ:
|
||||
sampling_rate_in_hz = 48000;
|
||||
break;
|
||||
case AUDIO_SAMPLING_RATE_88_2KHZ:
|
||||
sampling_rate_in_hz = 88200;
|
||||
break;
|
||||
case AUDIO_SAMPLING_RATE_96KHZ:
|
||||
sampling_rate_in_hz = 96000;
|
||||
break;
|
||||
case AUDIO_SAMPLING_RATE_176_4KHZ:
|
||||
sampling_rate_in_hz = 176400;
|
||||
break;
|
||||
case AUDIO_SAMPLING_RATE_192KHZ:
|
||||
sampling_rate_in_hz = 192000;
|
||||
break;
|
||||
default:
|
||||
sampling_rate_in_hz = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
link->audio_test_data.flags.test_requested = 1;
|
||||
link->audio_test_data.flags.disable_video = disable_video;
|
||||
link->audio_test_data.sampling_rate = sampling_rate_in_hz;
|
||||
link->audio_test_data.channel_count = channel_count;
|
||||
link->audio_test_data.pattern_type = test_pattern;
|
||||
|
||||
if (test_pattern == DP_TEST_PATTERN_AUDIO_SAWTOOTH) {
|
||||
for (modes = 0; modes < pipe_ctx->stream->audio_info.mode_count; modes++) {
|
||||
link->audio_test_data.pattern_period[modes] = dpcd_pattern_period[modes].bits.pattern_period;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dc_link_dp_handle_automated_test(struct dc_link *link)
|
||||
{
|
||||
union test_request test_request;
|
||||
union test_response test_response;
|
||||
|
||||
memset(&test_request, 0, sizeof(test_request));
|
||||
memset(&test_response, 0, sizeof(test_response));
|
||||
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TEST_REQUEST,
|
||||
&test_request.raw,
|
||||
sizeof(union test_request));
|
||||
if (test_request.bits.LINK_TRAINING) {
|
||||
/* ACK first to let DP RX test box monitor LT sequence */
|
||||
test_response.bits.ACK = 1;
|
||||
core_link_write_dpcd(
|
||||
link,
|
||||
DP_TEST_RESPONSE,
|
||||
&test_response.raw,
|
||||
sizeof(test_response));
|
||||
dp_test_send_link_training(link);
|
||||
/* no acknowledge request is needed again */
|
||||
test_response.bits.ACK = 0;
|
||||
}
|
||||
if (test_request.bits.LINK_TEST_PATTRN) {
|
||||
union test_misc dpcd_test_params;
|
||||
union link_test_pattern dpcd_test_pattern;
|
||||
|
||||
memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern));
|
||||
memset(&dpcd_test_params, 0, sizeof(dpcd_test_params));
|
||||
|
||||
/* get link test pattern and pattern parameters */
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TEST_PATTERN,
|
||||
&dpcd_test_pattern.raw,
|
||||
sizeof(dpcd_test_pattern));
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TEST_MISC0,
|
||||
&dpcd_test_params.raw,
|
||||
sizeof(dpcd_test_params));
|
||||
test_response.bits.ACK = dm_helpers_dp_handle_test_pattern_request(link->ctx, link,
|
||||
dpcd_test_pattern, dpcd_test_params) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (test_request.bits.AUDIO_TEST_PATTERN) {
|
||||
dp_test_get_audio_test_data(link, test_request.bits.TEST_AUDIO_DISABLED_VIDEO);
|
||||
test_response.bits.ACK = 1;
|
||||
}
|
||||
|
||||
if (test_request.bits.PHY_TEST_PATTERN) {
|
||||
dp_test_send_phy_test_pattern(link);
|
||||
test_response.bits.ACK = 1;
|
||||
}
|
||||
|
||||
/* send request acknowledgment */
|
||||
if (test_response.bits.ACK)
|
||||
core_link_write_dpcd(
|
||||
link,
|
||||
DP_TEST_RESPONSE,
|
||||
&test_response.raw,
|
||||
sizeof(test_response));
|
||||
}
|
||||
|
||||
static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern)
|
||||
{
|
||||
if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&
|
||||
test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||
|
||||
test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static void set_crtc_test_pattern(struct dc_link *link,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
enum dp_test_pattern test_pattern,
|
||||
enum dp_test_pattern_color_space test_pattern_color_space)
|
||||
{
|
||||
enum controller_dp_test_pattern controller_test_pattern;
|
||||
enum dc_color_depth color_depth = pipe_ctx->
|
||||
stream->timing.display_color_depth;
|
||||
struct bit_depth_reduction_params params;
|
||||
struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
|
||||
int width = pipe_ctx->stream->timing.h_addressable +
|
||||
pipe_ctx->stream->timing.h_border_left +
|
||||
pipe_ctx->stream->timing.h_border_right;
|
||||
int height = pipe_ctx->stream->timing.v_addressable +
|
||||
pipe_ctx->stream->timing.v_border_bottom +
|
||||
pipe_ctx->stream->timing.v_border_top;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
switch (test_pattern) {
|
||||
case DP_TEST_PATTERN_COLOR_SQUARES:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA;
|
||||
break;
|
||||
case DP_TEST_PATTERN_VERTICAL_BARS:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_VERTICALBARS;
|
||||
break;
|
||||
case DP_TEST_PATTERN_HORIZONTAL_BARS:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_RAMP:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_COLORRAMP;
|
||||
break;
|
||||
default:
|
||||
controller_test_pattern =
|
||||
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (test_pattern) {
|
||||
case DP_TEST_PATTERN_COLOR_SQUARES:
|
||||
case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
|
||||
case DP_TEST_PATTERN_VERTICAL_BARS:
|
||||
case DP_TEST_PATTERN_HORIZONTAL_BARS:
|
||||
case DP_TEST_PATTERN_COLOR_RAMP:
|
||||
{
|
||||
/* disable bit depth reduction */
|
||||
pipe_ctx->stream->bit_depth_params = params;
|
||||
opp->funcs->opp_program_bit_depth_reduction(opp, ¶ms);
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
|
||||
pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
|
||||
controller_test_pattern, color_depth);
|
||||
else if (link->dc->hwss.set_disp_pattern_generator) {
|
||||
struct pipe_ctx *odm_pipe;
|
||||
enum controller_dp_color_space controller_color_space;
|
||||
int opp_cnt = 1;
|
||||
int offset = 0;
|
||||
int dpg_width = width;
|
||||
|
||||
switch (test_pattern_color_space) {
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_RGB:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_RGB;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR601;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR709;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED:
|
||||
default:
|
||||
controller_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
|
||||
DC_LOG_ERROR("%s: Color space must be defined for test pattern", __func__);
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
|
||||
opp_cnt++;
|
||||
dpg_width = width / opp_cnt;
|
||||
offset = dpg_width;
|
||||
|
||||
link->dc->hwss.set_disp_pattern_generator(link->dc,
|
||||
pipe_ctx,
|
||||
controller_test_pattern,
|
||||
controller_color_space,
|
||||
color_depth,
|
||||
NULL,
|
||||
dpg_width,
|
||||
height,
|
||||
0);
|
||||
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
|
||||
struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
|
||||
|
||||
odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, ¶ms);
|
||||
link->dc->hwss.set_disp_pattern_generator(link->dc,
|
||||
odm_pipe,
|
||||
controller_test_pattern,
|
||||
controller_color_space,
|
||||
color_depth,
|
||||
NULL,
|
||||
dpg_width,
|
||||
height,
|
||||
offset);
|
||||
offset += offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DP_TEST_PATTERN_VIDEO_MODE:
|
||||
{
|
||||
/* restore bitdepth reduction */
|
||||
resource_build_bit_depth_reduction_params(pipe_ctx->stream, ¶ms);
|
||||
pipe_ctx->stream->bit_depth_params = params;
|
||||
opp->funcs->opp_program_bit_depth_reduction(opp, ¶ms);
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
|
||||
pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
|
||||
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
|
||||
color_depth);
|
||||
else if (link->dc->hwss.set_disp_pattern_generator) {
|
||||
struct pipe_ctx *odm_pipe;
|
||||
int opp_cnt = 1;
|
||||
int dpg_width;
|
||||
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
|
||||
opp_cnt++;
|
||||
|
||||
dpg_width = width / opp_cnt;
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
|
||||
struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
|
||||
|
||||
odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, ¶ms);
|
||||
link->dc->hwss.set_disp_pattern_generator(link->dc,
|
||||
odm_pipe,
|
||||
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
|
||||
CONTROLLER_DP_COLOR_SPACE_UDEFINED,
|
||||
color_depth,
|
||||
NULL,
|
||||
dpg_width,
|
||||
height,
|
||||
0);
|
||||
}
|
||||
link->dc->hwss.set_disp_pattern_generator(link->dc,
|
||||
pipe_ctx,
|
||||
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
|
||||
CONTROLLER_DP_COLOR_SPACE_UDEFINED,
|
||||
color_depth,
|
||||
NULL,
|
||||
dpg_width,
|
||||
height,
|
||||
0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool dc_link_dp_set_test_pattern(
|
||||
struct dc_link *link,
|
||||
enum dp_test_pattern test_pattern,
|
||||
enum dp_test_pattern_color_space test_pattern_color_space,
|
||||
const struct link_training_settings *p_link_settings,
|
||||
const unsigned char *p_custom_pattern,
|
||||
unsigned int cust_pattern_size)
|
||||
{
|
||||
struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
|
||||
struct pipe_ctx *pipe_ctx = NULL;
|
||||
unsigned int lane;
|
||||
unsigned int i;
|
||||
unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0};
|
||||
union dpcd_training_pattern training_pattern;
|
||||
enum dpcd_phy_test_patterns pattern;
|
||||
|
||||
memset(&training_pattern, 0, sizeof(training_pattern));
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
if (pipes[i].stream == NULL)
|
||||
continue;
|
||||
|
||||
if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) {
|
||||
pipe_ctx = &pipes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pipe_ctx == NULL)
|
||||
return false;
|
||||
|
||||
/* Reset CRTC Test Pattern if it is currently running and request is VideoMode */
|
||||
if (link->test_pattern_enabled && test_pattern ==
|
||||
DP_TEST_PATTERN_VIDEO_MODE) {
|
||||
/* Set CRTC Test Pattern */
|
||||
set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
|
||||
dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
|
||||
(uint8_t *)p_custom_pattern,
|
||||
(uint32_t)cust_pattern_size);
|
||||
|
||||
/* Unblank Stream */
|
||||
link->dc->hwss.unblank_stream(
|
||||
pipe_ctx,
|
||||
&link->verified_link_cap);
|
||||
/* TODO:m_pHwss->MuteAudioEndpoint
|
||||
* (pPathMode->pDisplayPath, false);
|
||||
*/
|
||||
|
||||
/* Reset Test Pattern state */
|
||||
link->test_pattern_enabled = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check for PHY Test Patterns */
|
||||
if (is_dp_phy_pattern(test_pattern)) {
|
||||
/* Set DPCD Lane Settings before running test pattern */
|
||||
if (p_link_settings != NULL) {
|
||||
if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
|
||||
p_link_settings->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
|
||||
dp_fixed_vs_pe_set_retimer_lane_settings(
|
||||
link,
|
||||
p_link_settings->dpcd_lane_settings,
|
||||
p_link_settings->link_settings.lane_count);
|
||||
} else {
|
||||
dp_set_hw_lane_settings(link, &pipe_ctx->link_res, p_link_settings, DPRX);
|
||||
}
|
||||
dpcd_set_lane_settings(link, p_link_settings, DPRX);
|
||||
}
|
||||
|
||||
/* Blank stream if running test pattern */
|
||||
if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
|
||||
/*TODO:
|
||||
* m_pHwss->
|
||||
* MuteAudioEndpoint(pPathMode->pDisplayPath, true);
|
||||
*/
|
||||
/* Blank stream */
|
||||
link->dc->hwss.blank_stream(pipe_ctx);
|
||||
}
|
||||
|
||||
dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
|
||||
(uint8_t *)p_custom_pattern,
|
||||
(uint32_t)cust_pattern_size);
|
||||
|
||||
if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
|
||||
/* Set Test Pattern state */
|
||||
link->test_pattern_enabled = true;
|
||||
if (p_link_settings != NULL)
|
||||
dpcd_set_link_settings(link,
|
||||
p_link_settings);
|
||||
}
|
||||
|
||||
switch (test_pattern) {
|
||||
case DP_TEST_PATTERN_VIDEO_MODE:
|
||||
pattern = PHY_TEST_PATTERN_NONE;
|
||||
break;
|
||||
case DP_TEST_PATTERN_D102:
|
||||
pattern = PHY_TEST_PATTERN_D10_2;
|
||||
break;
|
||||
case DP_TEST_PATTERN_SYMBOL_ERROR:
|
||||
pattern = PHY_TEST_PATTERN_SYMBOL_ERROR;
|
||||
break;
|
||||
case DP_TEST_PATTERN_PRBS7:
|
||||
pattern = PHY_TEST_PATTERN_PRBS7;
|
||||
break;
|
||||
case DP_TEST_PATTERN_80BIT_CUSTOM:
|
||||
pattern = PHY_TEST_PATTERN_80BIT_CUSTOM;
|
||||
break;
|
||||
case DP_TEST_PATTERN_CP2520_1:
|
||||
pattern = PHY_TEST_PATTERN_CP2520_1;
|
||||
break;
|
||||
case DP_TEST_PATTERN_CP2520_2:
|
||||
pattern = PHY_TEST_PATTERN_CP2520_2;
|
||||
break;
|
||||
case DP_TEST_PATTERN_CP2520_3:
|
||||
pattern = PHY_TEST_PATTERN_CP2520_3;
|
||||
break;
|
||||
case DP_TEST_PATTERN_128b_132b_TPS1:
|
||||
pattern = PHY_TEST_PATTERN_128b_132b_TPS1;
|
||||
break;
|
||||
case DP_TEST_PATTERN_128b_132b_TPS2:
|
||||
pattern = PHY_TEST_PATTERN_128b_132b_TPS2;
|
||||
break;
|
||||
case DP_TEST_PATTERN_PRBS9:
|
||||
pattern = PHY_TEST_PATTERN_PRBS9;
|
||||
break;
|
||||
case DP_TEST_PATTERN_PRBS11:
|
||||
pattern = PHY_TEST_PATTERN_PRBS11;
|
||||
break;
|
||||
case DP_TEST_PATTERN_PRBS15:
|
||||
pattern = PHY_TEST_PATTERN_PRBS15;
|
||||
break;
|
||||
case DP_TEST_PATTERN_PRBS23:
|
||||
pattern = PHY_TEST_PATTERN_PRBS23;
|
||||
break;
|
||||
case DP_TEST_PATTERN_PRBS31:
|
||||
pattern = PHY_TEST_PATTERN_PRBS31;
|
||||
break;
|
||||
case DP_TEST_PATTERN_264BIT_CUSTOM:
|
||||
pattern = PHY_TEST_PATTERN_264BIT_CUSTOM;
|
||||
break;
|
||||
case DP_TEST_PATTERN_SQUARE:
|
||||
pattern = PHY_TEST_PATTERN_SQUARE;
|
||||
break;
|
||||
case DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED:
|
||||
pattern = PHY_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED;
|
||||
break;
|
||||
case DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED:
|
||||
pattern = PHY_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED;
|
||||
break;
|
||||
case DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED:
|
||||
pattern = PHY_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (test_pattern == DP_TEST_PATTERN_VIDEO_MODE
|
||||
/*TODO:&& !pPathMode->pDisplayPath->IsTargetPoweredOn()*/)
|
||||
return false;
|
||||
|
||||
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
|
||||
if (is_dp_phy_sqaure_pattern(test_pattern))
|
||||
core_link_write_dpcd(link,
|
||||
DP_LINK_SQUARE_PATTERN,
|
||||
p_custom_pattern,
|
||||
1);
|
||||
|
||||
/* tell receiver that we are sending qualification
|
||||
* pattern DP 1.2 or later - DP receiver's link quality
|
||||
* pattern is set using DPCD LINK_QUAL_LANEx_SET
|
||||
* register (0x10B~0x10E)\
|
||||
*/
|
||||
for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++)
|
||||
link_qual_pattern[lane] =
|
||||
(unsigned char)(pattern);
|
||||
|
||||
core_link_write_dpcd(link,
|
||||
DP_LINK_QUAL_LANE0_SET,
|
||||
link_qual_pattern,
|
||||
sizeof(link_qual_pattern));
|
||||
} else if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_10 ||
|
||||
link->dpcd_caps.dpcd_rev.raw == 0) {
|
||||
/* tell receiver that we are sending qualification
|
||||
* pattern DP 1.1a or earlier - DP receiver's link
|
||||
* quality pattern is set using
|
||||
* DPCD TRAINING_PATTERN_SET -> LINK_QUAL_PATTERN_SET
|
||||
* register (0x102). We will use v_1.3 when we are
|
||||
* setting test pattern for DP 1.1.
|
||||
*/
|
||||
core_link_read_dpcd(link, DP_TRAINING_PATTERN_SET,
|
||||
&training_pattern.raw,
|
||||
sizeof(training_pattern));
|
||||
training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern;
|
||||
core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET,
|
||||
&training_pattern.raw,
|
||||
sizeof(training_pattern));
|
||||
}
|
||||
} else {
|
||||
enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
|
||||
|
||||
switch (test_pattern_color_space) {
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_RGB:
|
||||
color_space = COLOR_SPACE_SRGB;
|
||||
if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
|
||||
color_space = COLOR_SPACE_SRGB_LIMITED;
|
||||
break;
|
||||
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
|
||||
color_space = COLOR_SPACE_YCBCR601;
|
||||
if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
|
||||
color_space = COLOR_SPACE_YCBCR601_LIMITED;
|
||||
break;
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
|
||||
color_space = COLOR_SPACE_YCBCR709;
|
||||
if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
|
||||
color_space = COLOR_SPACE_YCBCR709_LIMITED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable) {
|
||||
if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
|
||||
union dmub_hw_lock_flags hw_locks = { 0 };
|
||||
struct dmub_hw_lock_inst_flags inst_flags = { 0 };
|
||||
|
||||
hw_locks.bits.lock_dig = 1;
|
||||
inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
|
||||
|
||||
dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
|
||||
true,
|
||||
&hw_locks,
|
||||
&inst_flags);
|
||||
} else
|
||||
pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable(
|
||||
pipe_ctx->stream_res.tg);
|
||||
}
|
||||
|
||||
pipe_ctx->stream_res.tg->funcs->lock(pipe_ctx->stream_res.tg);
|
||||
/* update MSA to requested color space */
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(pipe_ctx->stream_res.stream_enc,
|
||||
&pipe_ctx->stream->timing,
|
||||
color_space,
|
||||
pipe_ctx->stream->use_vsc_sdp_for_colorimetry,
|
||||
link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
|
||||
|
||||
if (pipe_ctx->stream->use_vsc_sdp_for_colorimetry) {
|
||||
if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
|
||||
pipe_ctx->stream->vsc_infopacket.sb[17] |= (1 << 7); // sb17 bit 7 Dynamic Range: 0 = VESA range, 1 = CTA range
|
||||
else
|
||||
pipe_ctx->stream->vsc_infopacket.sb[17] &= ~(1 << 7);
|
||||
resource_build_info_frame(pipe_ctx);
|
||||
link->dc->hwss.update_info_frame(pipe_ctx);
|
||||
}
|
||||
|
||||
/* CRTC Patterns */
|
||||
set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
|
||||
pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg);
|
||||
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
|
||||
CRTC_STATE_VACTIVE);
|
||||
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
|
||||
CRTC_STATE_VBLANK);
|
||||
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
|
||||
CRTC_STATE_VACTIVE);
|
||||
|
||||
if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable) {
|
||||
if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
|
||||
union dmub_hw_lock_flags hw_locks = { 0 };
|
||||
struct dmub_hw_lock_inst_flags inst_flags = { 0 };
|
||||
|
||||
hw_locks.bits.lock_dig = 1;
|
||||
inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
|
||||
|
||||
dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
|
||||
false,
|
||||
&hw_locks,
|
||||
&inst_flags);
|
||||
} else
|
||||
pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable(
|
||||
pipe_ctx->stream_res.tg);
|
||||
}
|
||||
|
||||
/* Set Test Pattern state */
|
||||
link->test_pattern_enabled = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dp_enable_mst_on_sink(struct dc_link *link, bool enable)
|
||||
{
|
||||
unsigned char mstmCntl;
|
||||
@ -1281,43 +403,6 @@ void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode)
|
||||
&dp_test_mode, sizeof(dp_test_mode));
|
||||
}
|
||||
|
||||
void dp_retrain_link_dp_test(struct dc_link *link,
|
||||
struct dc_link_settings *link_setting,
|
||||
bool skip_video_pattern)
|
||||
{
|
||||
struct pipe_ctx *pipe;
|
||||
unsigned int i;
|
||||
|
||||
udelay(100);
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe->stream != NULL &&
|
||||
pipe->stream->link == link &&
|
||||
!pipe->stream->dpms_off &&
|
||||
!pipe->top_pipe && !pipe->prev_odm_pipe) {
|
||||
core_link_disable_stream(pipe);
|
||||
pipe->link_config.dp_link_settings = *link_setting;
|
||||
update_dp_encoder_resources_for_test_harness(
|
||||
link->dc,
|
||||
pipe->stream->ctx->dc->current_state,
|
||||
pipe);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe->stream != NULL &&
|
||||
pipe->stream->link == link &&
|
||||
!pipe->stream->dpms_off &&
|
||||
!pipe->top_pipe && !pipe->prev_odm_pipe) {
|
||||
core_link_enable_stream(
|
||||
pipe->stream->ctx->dc->current_state,
|
||||
pipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef DC_LOGGER
|
||||
#define DC_LOGGER \
|
||||
dsc->ctx->logger
|
||||
|
@ -74,8 +74,6 @@ struct fixed31_32 calculate_sst_avg_time_slots_per_mtp(
|
||||
const struct dc_link *link);
|
||||
void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode);
|
||||
void dp_retrain_link_dp_test(struct dc_link *link,
|
||||
struct dc_link_settings *link_setting,
|
||||
bool skip_video_pattern);
|
||||
|
||||
|
||||
#endif /* __DC_LINK_DP_H__ */
|
||||
|
@ -26,7 +26,7 @@
|
||||
###############################################################################
|
||||
# accessories
|
||||
###############################################################################
|
||||
LINK_ACCESSORIES = link_dp_trace.o
|
||||
LINK_ACCESSORIES = link_dp_trace.o link_dp_cts.o
|
||||
|
||||
AMD_DAL_LINK_ACCESSORIES = $(addprefix $(AMDDALPATH)/dc/link/accessories/, \
|
||||
$(LINK_ACCESSORIES))
|
||||
|
1055
drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
Normal file
1055
drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2023 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
|
||||
*
|
||||
*/
|
||||
#ifndef __LINK_DP_CTS_H__
|
||||
#define __LINK_DP_CTS_H__
|
||||
#include "link.h"
|
||||
|
||||
void dp_retrain_link_dp_test(struct dc_link *link,
|
||||
struct dc_link_settings *link_setting,
|
||||
bool skip_video_pattern);
|
||||
|
||||
#endif /* __LINK_DP_CTS_H__ */
|
Loading…
Reference in New Issue
Block a user