mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 10:19:47 +00:00
drm/amd/display: Add DP 2.0 SST DC Support
1. Retrieve 128/132b link cap. 2. 128/132b link training and payload allocation. 3. UHBR10 link rate support. [squash in warning fixes - Alex] Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com> Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
5a2730fc1f
commit
f01ee01958
23 changed files with 2555 additions and 43 deletions
|
@ -751,3 +751,11 @@ void dm_helpers_mst_enable_stream_features(const struct dc_stream_state *stream)
|
|||
&new_downspread.raw,
|
||||
sizeof(new_downspread));
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz)
|
||||
{
|
||||
// FPGA programming for this clock in diags framework that
|
||||
// needs to go through dm layer, therefore leave dummy interace here
|
||||
}
|
||||
#endif
|
|
@ -255,6 +255,24 @@ static bool create_links(
|
|||
goto failed_alloc;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) &&
|
||||
dc->caps.dp_hpo &&
|
||||
link->dc->res_pool->res_cap->num_hpo_dp_link_encoder > 0) {
|
||||
/* FPGA case - Allocate HPO DP link encoder */
|
||||
if (i < link->dc->res_pool->res_cap->num_hpo_dp_link_encoder) {
|
||||
link->hpo_dp_link_enc = link->dc->res_pool->hpo_dp_link_enc[i];
|
||||
|
||||
if (link->hpo_dp_link_enc == NULL) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
goto failed_alloc;
|
||||
}
|
||||
link->hpo_dp_link_enc->hpd_source = link->link_enc->hpd_source;
|
||||
link->hpo_dp_link_enc->transmitter = link->link_enc->transmitter;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
link->link_status.dpcd_caps = &link->dpcd_caps;
|
||||
|
||||
enc_init.ctx = dc->ctx;
|
||||
|
|
|
@ -64,6 +64,31 @@
|
|||
/*******************************************************************************
|
||||
* Private functions
|
||||
******************************************************************************/
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
static bool add_dp_hpo_link_encoder_to_link(struct dc_link *link)
|
||||
{
|
||||
struct hpo_dp_link_encoder *enc = resource_get_unused_hpo_dp_link_encoder(
|
||||
link->dc->res_pool);
|
||||
|
||||
if (!link->hpo_dp_link_enc && enc) {
|
||||
link->hpo_dp_link_enc = enc;
|
||||
link->hpo_dp_link_enc->transmitter = link->link_enc->transmitter;
|
||||
link->hpo_dp_link_enc->hpd_source = link->link_enc->hpd_source;
|
||||
}
|
||||
|
||||
return (link->hpo_dp_link_enc != NULL);
|
||||
}
|
||||
|
||||
static void remove_dp_hpo_link_encoder_from_link(struct dc_link *link)
|
||||
{
|
||||
if (link->hpo_dp_link_enc) {
|
||||
link->hpo_dp_link_enc->hpd_source = HPD_SOURCEID_UNKNOWN;
|
||||
link->hpo_dp_link_enc->transmitter = TRANSMITTER_UNKNOWN;
|
||||
link->hpo_dp_link_enc = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void dc_link_destruct(struct dc_link *link)
|
||||
{
|
||||
int i;
|
||||
|
@ -91,6 +116,12 @@ static void dc_link_destruct(struct dc_link *link)
|
|||
link->link_enc->funcs->destroy(&link->link_enc);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (link->hpo_dp_link_enc) {
|
||||
remove_dp_hpo_link_encoder_from_link(link);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (link->local_sink)
|
||||
dc_sink_release(link->local_sink);
|
||||
|
||||
|
@ -928,6 +959,11 @@ static bool dc_link_detect_helper(struct dc_link *link,
|
|||
return false;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(&link->reported_link_cap) == DP_128b_132b_ENCODING)
|
||||
add_dp_hpo_link_encoder_to_link(link);
|
||||
#endif
|
||||
|
||||
if (link->type == dc_connection_mst_branch) {
|
||||
LINK_INFO("link=%d, mst branch is now Connected\n",
|
||||
link->link_index);
|
||||
|
@ -1173,6 +1209,11 @@ static bool dc_link_detect_helper(struct dc_link *link,
|
|||
sizeof(link->mst_stream_alloc_table.stream_allocations));
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING)
|
||||
reset_dp_hpo_stream_encoders_for_link(link);
|
||||
#endif
|
||||
|
||||
link->type = dc_connection_none;
|
||||
sink_caps.signal = SIGNAL_TYPE_NONE;
|
||||
/* When we unplug a passive DP-HDMI dongle connection, dongle_max_pix_clk
|
||||
|
@ -1549,6 +1590,9 @@ static bool dc_link_construct(struct dc_link *link,
|
|||
}
|
||||
|
||||
DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
|
||||
#endif
|
||||
|
||||
/* Update link encoder tracking variables. These are used for the dynamic
|
||||
* assignment of link encoders to streams.
|
||||
|
@ -1741,17 +1785,36 @@ static enum dc_status enable_link_dp(struct dc_state *state,
|
|||
/* get link settings for video mode timing */
|
||||
decide_link_settings(stream, &link_settings);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(&link_settings) == DP_128b_132b_ENCODING &&
|
||||
pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
dp_enable_mst_on_sink(link, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
|
||||
/*in case it is not on*/
|
||||
link->dc->hwss.edp_power_control(link, true);
|
||||
link->dc->hwss.edp_wait_for_hpd_ready(link, true);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(&link_settings) == DP_128b_132b_ENCODING) {
|
||||
/* TODO - DP2.0 HW: calculate 32 symbol clock for HPO encoder */
|
||||
} else {
|
||||
pipe_ctx->stream_res.pix_clk_params.requested_sym_clk =
|
||||
link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
|
||||
if (state->clk_mgr && !apply_seamless_boot_optimization)
|
||||
state->clk_mgr->funcs->update_clocks(state->clk_mgr,
|
||||
state, false);
|
||||
}
|
||||
#else
|
||||
pipe_ctx->stream_res.pix_clk_params.requested_sym_clk =
|
||||
link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
|
||||
link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
|
||||
if (state->clk_mgr && !apply_seamless_boot_optimization)
|
||||
state->clk_mgr->funcs->update_clocks(state->clk_mgr,
|
||||
state, false);
|
||||
state, false);
|
||||
#endif
|
||||
|
||||
// during mode switch we do DP_SET_POWER off then on, and OUI is lost
|
||||
dpcd_set_source_specific_data(link);
|
||||
|
@ -1780,7 +1843,12 @@ static enum dc_status enable_link_dp(struct dc_state *state,
|
|||
else
|
||||
fec_enable = true;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING)
|
||||
dp_set_fec_enable(link, fec_enable);
|
||||
#else
|
||||
dp_set_fec_enable(link, fec_enable);
|
||||
#endif
|
||||
|
||||
// during mode set we do DP_SET_POWER off then on, aux writes are lost
|
||||
if (link->dpcd_sink_ext_caps.bits.oled == 1 ||
|
||||
|
@ -2284,6 +2352,9 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
|
|||
|
||||
if (dc_is_dp_signal(signal)) {
|
||||
/* SST DP, eDP */
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct dc_link_settings link_settings = link->cur_link_settings;
|
||||
#endif
|
||||
if (dc_is_dp_sst_signal(signal))
|
||||
dp_disable_link_phy(link, signal);
|
||||
else
|
||||
|
@ -2291,8 +2362,15 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
|
|||
|
||||
if (dc_is_dp_sst_signal(signal) ||
|
||||
link->mst_stream_alloc_table.stream_count == 0) {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING) {
|
||||
dp_set_fec_enable(link, false);
|
||||
dp_set_fec_ready(link, false);
|
||||
}
|
||||
#else
|
||||
dp_set_fec_enable(link, false);
|
||||
dp_set_fec_ready(link, false);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (signal != SIGNAL_TYPE_VIRTUAL)
|
||||
|
@ -2475,9 +2553,14 @@ static bool dp_active_dongle_validate_timing(
|
|||
break;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dpcd_caps->dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER &&
|
||||
dongle_caps->extendedCapValid == true) {
|
||||
#else
|
||||
if (dpcd_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER ||
|
||||
dongle_caps->extendedCapValid == false)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
/* Check Pixel Encoding */
|
||||
switch (timing->pixel_encoding) {
|
||||
|
@ -2520,6 +2603,87 @@ static bool dp_active_dongle_validate_timing(
|
|||
if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))
|
||||
return false;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
}
|
||||
|
||||
if (dongle_caps->dfp_cap_ext.supported) {
|
||||
|
||||
if (dongle_caps->dfp_cap_ext.max_pixel_rate_in_mps < (timing->pix_clk_100hz / 10000))
|
||||
return false;
|
||||
|
||||
if (dongle_caps->dfp_cap_ext.max_video_h_active_width < timing->h_addressable)
|
||||
return false;
|
||||
|
||||
if (dongle_caps->dfp_cap_ext.max_video_v_active_height < timing->v_addressable)
|
||||
return false;
|
||||
|
||||
if (timing->pixel_encoding == PIXEL_ENCODING_RGB) {
|
||||
if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
|
||||
return false;
|
||||
if (timing->display_color_depth == COLOR_DEPTH_666 &&
|
||||
!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_6bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_888 &&
|
||||
!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_8bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
|
||||
!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_10bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
|
||||
!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_12bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
|
||||
!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_16bpc)
|
||||
return false;
|
||||
} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR444) {
|
||||
if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
|
||||
return false;
|
||||
if (timing->display_color_depth == COLOR_DEPTH_888 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_8bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_10bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_12bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_16bpc)
|
||||
return false;
|
||||
} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
|
||||
if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
|
||||
return false;
|
||||
if (timing->display_color_depth == COLOR_DEPTH_888 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_8bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_10bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_12bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_16bpc)
|
||||
return false;
|
||||
} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
|
||||
if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
|
||||
return false;
|
||||
if (timing->display_color_depth == COLOR_DEPTH_888 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_8bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_10bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_12bpc)
|
||||
return false;
|
||||
else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
|
||||
!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_16bpc)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3016,6 +3180,107 @@ static void update_mst_stream_alloc_table(
|
|||
link->mst_stream_alloc_table.stream_allocations[i] =
|
||||
work_table[i];
|
||||
}
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/*
|
||||
* Payload allocation/deallocation for SST introduced in DP2.0
|
||||
*/
|
||||
enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx, bool allocate)
|
||||
{
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct dc_link *link = stream->link;
|
||||
struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
|
||||
struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
|
||||
struct link_mst_stream_allocation_table proposed_table = {0};
|
||||
struct fixed31_32 avg_time_slots_per_mtp;
|
||||
DC_LOGGER_INIT(link->ctx->logger);
|
||||
|
||||
/* slot X.Y for SST payload deallocate */
|
||||
if (!allocate) {
|
||||
avg_time_slots_per_mtp = dc_fixpt_from_int(0);
|
||||
|
||||
DC_LOG_DP2("SST Update Payload: set_throttled_vcp_size slot X.Y for SST stream"
|
||||
"X: %d "
|
||||
"Y: %d",
|
||||
dc_fixpt_floor(
|
||||
avg_time_slots_per_mtp),
|
||||
dc_fixpt_ceil(
|
||||
dc_fixpt_shl(
|
||||
dc_fixpt_sub_int(
|
||||
avg_time_slots_per_mtp,
|
||||
dc_fixpt_floor(
|
||||
avg_time_slots_per_mtp)),
|
||||
26)));
|
||||
|
||||
hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
|
||||
hpo_dp_link_encoder,
|
||||
hpo_dp_stream_encoder->inst,
|
||||
avg_time_slots_per_mtp);
|
||||
}
|
||||
|
||||
/* calculate VC payload and update branch with new payload allocation table*/
|
||||
if (!dpcd_write_128b_132b_sst_payload_allocation_table(
|
||||
stream,
|
||||
link,
|
||||
&proposed_table,
|
||||
allocate)) {
|
||||
DC_LOG_ERROR("SST Update Payload: Failed to update "
|
||||
"allocation table for "
|
||||
"pipe idx: %d\n",
|
||||
pipe_ctx->pipe_idx);
|
||||
}
|
||||
|
||||
proposed_table.stream_allocations[0].hpo_dp_stream_enc = hpo_dp_stream_encoder;
|
||||
|
||||
ASSERT(proposed_table.stream_count == 1);
|
||||
|
||||
//TODO - DP2.0 Logging: Instead of hpo_dp_stream_enc pointer, log instance id
|
||||
DC_LOG_DP2("SST Update Payload: hpo_dp_stream_enc: %p "
|
||||
"vcp_id: %d "
|
||||
"slot_count: %d\n",
|
||||
(void *) proposed_table.stream_allocations[0].hpo_dp_stream_enc,
|
||||
proposed_table.stream_allocations[0].vcp_id,
|
||||
proposed_table.stream_allocations[0].slot_count);
|
||||
|
||||
/* program DP source TX for payload */
|
||||
hpo_dp_link_encoder->funcs->update_stream_allocation_table(
|
||||
hpo_dp_link_encoder,
|
||||
&proposed_table);
|
||||
|
||||
/* poll for ACT handled */
|
||||
if (!dpcd_poll_for_allocation_change_trigger(link)) {
|
||||
// Failures will result in blackscreen and errors logged
|
||||
BREAK_TO_DEBUGGER();
|
||||
}
|
||||
|
||||
/* slot X.Y for SST payload allocate */
|
||||
if (allocate) {
|
||||
avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, link);
|
||||
|
||||
DC_LOG_DP2("SST Update Payload: "
|
||||
"slot.X: %d "
|
||||
"slot.Y: %d",
|
||||
dc_fixpt_floor(
|
||||
avg_time_slots_per_mtp),
|
||||
dc_fixpt_ceil(
|
||||
dc_fixpt_shl(
|
||||
dc_fixpt_sub_int(
|
||||
avg_time_slots_per_mtp,
|
||||
dc_fixpt_floor(
|
||||
avg_time_slots_per_mtp)),
|
||||
26)));
|
||||
|
||||
hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
|
||||
hpo_dp_link_encoder,
|
||||
hpo_dp_stream_encoder->inst,
|
||||
avg_time_slots_per_mtp);
|
||||
}
|
||||
|
||||
/* Always return DC_OK.
|
||||
* If part of sequence fails, log failure(s) and show blackscreen
|
||||
*/
|
||||
return DC_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* convert link_mst_stream_alloc_table to dm dp_mst_stream_alloc_table
|
||||
* because stream_encoder is not exposed to dm
|
||||
|
@ -3203,6 +3468,11 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
|
|||
config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA;
|
||||
config.link_enc_idx = pipe_ctx->stream->link->link_enc->transmitter - TRANSMITTER_UNIPHY_A;
|
||||
config.phy_idx = pipe_ctx->stream->link->link_enc->transmitter - TRANSMITTER_UNIPHY_A;
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
config.stream_enc_idx = pipe_ctx->stream_res.hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0;
|
||||
config.link_enc_idx = pipe_ctx->stream->link->hpo_dp_link_enc->inst;
|
||||
config.dp2_enabled = 1;
|
||||
}
|
||||
#endif
|
||||
config.dpms_off = dpms_off;
|
||||
config.dm_stream_ctx = pipe_ctx->stream->dm_stream_context;
|
||||
|
@ -3214,6 +3484,88 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct link_mst_stream_allocation_table proposed_table = {0};
|
||||
struct fixed31_32 avg_time_slots_per_mtp;
|
||||
uint8_t req_slot_count = 0;
|
||||
uint8_t vc_id = 1; /// VC ID always 1 for SST
|
||||
|
||||
struct dc_link_settings link_settings = {0};
|
||||
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
|
||||
|
||||
decide_link_settings(stream, &link_settings);
|
||||
stream->link->cur_link_settings = link_settings;
|
||||
|
||||
/* Enable clock, Configure lane count, and Enable Link Encoder*/
|
||||
enable_dp_hpo_output(stream->link, &stream->link->cur_link_settings);
|
||||
|
||||
#ifdef DIAGS_BUILD
|
||||
/* Workaround for FPGA HPO capture DP link data:
|
||||
* HPO capture will set link to active mode
|
||||
* This workaround is required to get a capture from start of frame
|
||||
*/
|
||||
if (!dc->debug.fpga_hpo_capture_en) {
|
||||
struct encoder_set_dp_phy_pattern_param params = {0};
|
||||
params.dp_phy_pattern = DP_TEST_PATTERN_VIDEO_MODE;
|
||||
|
||||
/* Set link active */
|
||||
stream->link->hpo_dp_link_enc->funcs->set_link_test_pattern(
|
||||
stream->link->hpo_dp_link_enc,
|
||||
¶ms);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Enable DP_STREAM_ENC */
|
||||
dc->hwss.enable_stream(pipe_ctx);
|
||||
|
||||
/* Set DPS PPS SDP (AKA "info frames") */
|
||||
if (pipe_ctx->stream->timing.flags.DSC) {
|
||||
dp_set_dsc_pps_sdp(pipe_ctx, true);
|
||||
}
|
||||
|
||||
/* Allocate Payload */
|
||||
if ((stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) && (state->stream_count > 1)) {
|
||||
// MST case
|
||||
uint8_t i;
|
||||
|
||||
proposed_table.stream_count = state->stream_count;
|
||||
for (i = 0; i < state->stream_count; i++) {
|
||||
avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(state->streams[i], state->streams[i]->link);
|
||||
req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
|
||||
proposed_table.stream_allocations[i].slot_count = req_slot_count;
|
||||
proposed_table.stream_allocations[i].vcp_id = i+1;
|
||||
/* NOTE: This makes assumption that pipe_ctx index is same as stream index */
|
||||
proposed_table.stream_allocations[i].hpo_dp_stream_enc = state->res_ctx.pipe_ctx[i].stream_res.hpo_dp_stream_enc;
|
||||
}
|
||||
} else {
|
||||
// SST case
|
||||
avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, stream->link);
|
||||
req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
|
||||
proposed_table.stream_count = 1; /// Always 1 stream for SST
|
||||
proposed_table.stream_allocations[0].slot_count = req_slot_count;
|
||||
proposed_table.stream_allocations[0].vcp_id = vc_id;
|
||||
proposed_table.stream_allocations[0].hpo_dp_stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
|
||||
}
|
||||
|
||||
stream->link->hpo_dp_link_enc->funcs->update_stream_allocation_table(
|
||||
stream->link->hpo_dp_link_enc,
|
||||
&proposed_table);
|
||||
|
||||
stream->link->hpo_dp_link_enc->funcs->set_throttled_vcp_size(
|
||||
stream->link->hpo_dp_link_enc,
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->inst,
|
||||
avg_time_slots_per_mtp);
|
||||
|
||||
|
||||
|
||||
dc->hwss.unblank_stream(pipe_ctx, &stream->link->cur_link_settings);
|
||||
}
|
||||
#endif
|
||||
|
||||
void core_link_enable_stream(
|
||||
struct dc_state *state,
|
||||
struct pipe_ctx *pipe_ctx)
|
||||
|
@ -3230,7 +3582,12 @@ void core_link_enable_stream(
|
|||
dc_is_virtual_signal(pipe_ctx->stream->signal))
|
||||
return;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (!dc_is_virtual_signal(pipe_ctx->stream->signal)
|
||||
&& !is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
#else
|
||||
if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) {
|
||||
#endif
|
||||
stream->link->link_enc->funcs->setup(
|
||||
stream->link->link_enc,
|
||||
pipe_ctx->stream->signal);
|
||||
|
@ -3240,13 +3597,32 @@ void core_link_enable_stream(
|
|||
stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE);
|
||||
}
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->set_stream_attribute(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
&stream->timing,
|
||||
stream->output_color_space,
|
||||
stream->use_vsc_sdp_for_colorimetry,
|
||||
stream->timing.flags.DSC,
|
||||
false);
|
||||
otg_out_dest = OUT_MUX_HPO_DP;
|
||||
} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
&stream->timing,
|
||||
stream->output_color_space,
|
||||
stream->use_vsc_sdp_for_colorimetry,
|
||||
stream->link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
|
||||
}
|
||||
#else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
&stream->timing,
|
||||
stream->output_color_space,
|
||||
stream->use_vsc_sdp_for_colorimetry,
|
||||
stream->link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
|
||||
#endif
|
||||
|
||||
if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal))
|
||||
pipe_ctx->stream_res.stream_enc->funcs->hdmi_set_stream_attribute(
|
||||
|
@ -3357,7 +3733,12 @@ void core_link_enable_stream(
|
|||
* as a workaround for the incorrect value being applied
|
||||
* from transmitter control.
|
||||
*/
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (!(dc_is_virtual_signal(pipe_ctx->stream->signal) ||
|
||||
is_dp_128b_132b_signal(pipe_ctx)))
|
||||
#else
|
||||
if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
|
||||
#endif
|
||||
stream->link->link_enc->funcs->setup(
|
||||
stream->link->link_enc,
|
||||
pipe_ctx->stream->signal);
|
||||
|
@ -3375,6 +3756,11 @@ void core_link_enable_stream(
|
|||
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
dc_link_allocate_mst_payload(pipe_ctx);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
|
||||
is_dp_128b_132b_signal(pipe_ctx))
|
||||
dc_link_update_sst_payload(pipe_ctx, true);
|
||||
#endif
|
||||
|
||||
dc->hwss.unblank_stream(pipe_ctx,
|
||||
&pipe_ctx->stream->link->cur_link_settings);
|
||||
|
@ -3391,6 +3777,11 @@ void core_link_enable_stream(
|
|||
dc->hwss.enable_audio_stream(pipe_ctx);
|
||||
|
||||
} else { // if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
fpga_dp_hpo_enable_link_and_stream(state, pipe_ctx);
|
||||
}
|
||||
#endif
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
|
||||
dc_is_virtual_signal(pipe_ctx->stream->signal))
|
||||
dp_set_dsc_enable(pipe_ctx, true);
|
||||
|
@ -3426,6 +3817,11 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
|
|||
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
deallocate_mst_payload(pipe_ctx);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
|
||||
is_dp_128b_132b_signal(pipe_ctx))
|
||||
dc_link_update_sst_payload(pipe_ctx, false);
|
||||
#endif
|
||||
|
||||
if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
|
||||
struct ext_hdmi_settings settings = {0};
|
||||
|
@ -3452,14 +3848,39 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
|
||||
!is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
|
||||
/* In DP1.x SST mode, our encoder will go to TPS1
|
||||
* when link is on but stream is off.
|
||||
* Disabling link before stream will avoid exposing TPS1 pattern
|
||||
* during the disable sequence as it will confuse some receivers
|
||||
* state machine.
|
||||
* In DP2 or MST mode, our encoder will stay video active
|
||||
*/
|
||||
disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal);
|
||||
dc->hwss.disable_stream(pipe_ctx);
|
||||
} else {
|
||||
dc->hwss.disable_stream(pipe_ctx);
|
||||
disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal);
|
||||
}
|
||||
#else
|
||||
disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal);
|
||||
|
||||
dc->hwss.disable_stream(pipe_ctx);
|
||||
#endif
|
||||
|
||||
if (pipe_ctx->stream->timing.flags.DSC) {
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
dp_set_dsc_enable(pipe_ctx, false);
|
||||
}
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_out_mux)
|
||||
pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, OUT_MUX_DIO);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
|
||||
|
@ -3592,6 +4013,13 @@ void dc_link_set_preferred_training_settings(struct dc *dc,
|
|||
|
||||
if (link_setting != NULL) {
|
||||
link->preferred_link_setting = *link_setting;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(link_setting) ==
|
||||
DP_128b_132b_ENCODING && !link->hpo_dp_link_enc) {
|
||||
if (!add_dp_hpo_link_encoder_to_link(link))
|
||||
memset(&link->preferred_link_setting, 0, sizeof(link->preferred_link_setting));
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN;
|
||||
link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN;
|
||||
|
@ -3633,6 +4061,38 @@ uint32_t dc_link_bandwidth_kbps(
|
|||
const struct dc_link *link,
|
||||
const struct dc_link_settings *link_setting)
|
||||
{
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
uint32_t total_data_bw_efficiency_x10000 = 0;
|
||||
uint32_t link_rate_per_lane_kbps = 0;
|
||||
|
||||
switch (dp_get_link_encoding_format(link_setting)) {
|
||||
case DP_8b_10b_ENCODING:
|
||||
/* For 8b/10b encoding:
|
||||
* link rate is defined in the unit of LINK_RATE_REF_FREQ_IN_KHZ per DP byte per lane.
|
||||
* data bandwidth efficiency is 80% with additional 3% overhead if FEC is supported.
|
||||
*/
|
||||
link_rate_per_lane_kbps = link_setting->link_rate * LINK_RATE_REF_FREQ_IN_KHZ * BITS_PER_DP_BYTE;
|
||||
total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_8b_10b_x10000;
|
||||
if (dc_link_should_enable_fec(link)) {
|
||||
total_data_bw_efficiency_x10000 /= 100;
|
||||
total_data_bw_efficiency_x10000 *= DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100;
|
||||
}
|
||||
break;
|
||||
case DP_128b_132b_ENCODING:
|
||||
/* For 128b/132b encoding:
|
||||
* link rate is defined in the unit of 10mbps per lane.
|
||||
* total data bandwidth efficiency is always 96.71%.
|
||||
*/
|
||||
link_rate_per_lane_kbps = link_setting->link_rate * 10000;
|
||||
total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_128b_132b_x10000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* overall effective link bandwidth = link rate per lane * lane count * total data bandwidth efficiency */
|
||||
return link_rate_per_lane_kbps * link_setting->lane_count / 10000 * total_data_bw_efficiency_x10000;
|
||||
#else
|
||||
uint32_t link_bw_kbps =
|
||||
link_setting->link_rate * LINK_RATE_REF_FREQ_IN_KHZ; /* bytes per sec */
|
||||
|
||||
|
@ -3663,9 +4123,9 @@ uint32_t dc_link_bandwidth_kbps(
|
|||
long long fec_link_bw_kbps = link_bw_kbps * 970LL;
|
||||
link_bw_kbps = (uint32_t)(div64_s64(fec_link_bw_kbps, 1000LL));
|
||||
}
|
||||
|
||||
return link_bw_kbps;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
const struct dc_link_settings *dc_link_get_link_cap(
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,6 +17,7 @@
|
|||
#include "link_enc_cfg.h"
|
||||
#include "clk_mgr.h"
|
||||
#include "inc/link_dpcd.h"
|
||||
#include "dccg.h"
|
||||
|
||||
static uint8_t convert_to_count(uint8_t lttpr_repeater_count)
|
||||
{
|
||||
|
@ -111,12 +112,37 @@ void dp_enable_link_phy(
|
|||
|
||||
link->cur_link_settings = *link_settings;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
|
||||
/* TODO - DP2.0 HW: notify link rate change here */
|
||||
} else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
|
||||
if (dc->clk_mgr->funcs->notify_link_rate_change)
|
||||
dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
|
||||
}
|
||||
#else
|
||||
if (dc->clk_mgr->funcs->notify_link_rate_change)
|
||||
dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
|
||||
|
||||
#endif
|
||||
if (dmcu != NULL && dmcu->funcs->lock_phy)
|
||||
dmcu->funcs->lock_phy(dmcu);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
|
||||
enable_dp_hpo_output(link, link_settings);
|
||||
} else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
|
||||
if (dc_is_dp_sst_signal(signal)) {
|
||||
link_enc->funcs->enable_dp_output(
|
||||
link_enc,
|
||||
link_settings,
|
||||
clock_source);
|
||||
} else {
|
||||
link_enc->funcs->enable_dp_mst_output(
|
||||
link_enc,
|
||||
link_settings,
|
||||
clock_source);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (dc_is_dp_sst_signal(signal)) {
|
||||
link_enc->funcs->enable_dp_output(
|
||||
link_enc,
|
||||
|
@ -128,7 +154,7 @@ void dp_enable_link_phy(
|
|||
link_settings,
|
||||
clock_source);
|
||||
}
|
||||
|
||||
#endif
|
||||
if (dmcu != NULL && dmcu->funcs->unlock_phy)
|
||||
dmcu->funcs->unlock_phy(dmcu);
|
||||
|
||||
|
@ -206,6 +232,9 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
|
|||
{
|
||||
struct dc *dc = link->ctx->dc;
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct hpo_dp_link_encoder *hpo_link_enc = link->hpo_dp_link_enc;
|
||||
#endif
|
||||
struct link_encoder *link_enc;
|
||||
|
||||
/* Link should always be assigned encoder when en-/disabling. */
|
||||
|
@ -221,14 +250,28 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
|
|||
if (signal == SIGNAL_TYPE_EDP) {
|
||||
if (link->dc->hwss.edp_backlight_control)
|
||||
link->dc->hwss.edp_backlight_control(link, false);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING)
|
||||
disable_dp_hpo_output(link, signal);
|
||||
else
|
||||
link_enc->funcs->disable_output(link_enc, signal);
|
||||
#else
|
||||
link_enc->funcs->disable_output(link_enc, signal);
|
||||
#endif
|
||||
link->dc->hwss.edp_power_control(link, false);
|
||||
} else {
|
||||
if (dmcu != NULL && dmcu->funcs->lock_phy)
|
||||
dmcu->funcs->lock_phy(dmcu);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING &&
|
||||
hpo_link_enc)
|
||||
disable_dp_hpo_output(link, signal);
|
||||
else
|
||||
link_enc->funcs->disable_output(link_enc, signal);
|
||||
#else
|
||||
link_enc->funcs->disable_output(link_enc, signal);
|
||||
|
||||
#endif
|
||||
if (dmcu != NULL && dmcu->funcs->unlock_phy)
|
||||
dmcu->funcs->unlock_phy(dmcu);
|
||||
}
|
||||
|
@ -273,6 +316,14 @@ bool dp_set_hw_training_pattern(
|
|||
case DP_TRAINING_PATTERN_SEQUENCE_4:
|
||||
test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
|
||||
break;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
case DP_128b_132b_TPS1:
|
||||
test_pattern = DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE;
|
||||
break;
|
||||
case DP_128b_132b_TPS2:
|
||||
test_pattern = DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -282,6 +333,10 @@ bool dp_set_hw_training_pattern(
|
|||
return true;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
#endif
|
||||
void dp_set_hw_lane_settings(
|
||||
struct dc_link *link,
|
||||
const struct link_training_settings *link_settings,
|
||||
|
@ -293,7 +348,20 @@ void dp_set_hw_lane_settings(
|
|||
return;
|
||||
|
||||
/* call Encoder to set lane settings */
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dp_get_link_encoding_format(&link_settings->link_settings) ==
|
||||
DP_128b_132b_ENCODING) {
|
||||
link->hpo_dp_link_enc->funcs->set_ffe(
|
||||
link->hpo_dp_link_enc,
|
||||
&link_settings->link_settings,
|
||||
link_settings->lane_settings[0].FFE_PRESET.raw);
|
||||
} else if (dp_get_link_encoding_format(&link_settings->link_settings)
|
||||
== DP_8b_10b_ENCODING) {
|
||||
encoder->funcs->dp_set_lane_settings(encoder, link_settings);
|
||||
}
|
||||
#else
|
||||
encoder->funcs->dp_set_lane_settings(encoder, link_settings);
|
||||
#endif
|
||||
}
|
||||
|
||||
void dp_set_hw_test_pattern(
|
||||
|
@ -304,6 +372,9 @@ void dp_set_hw_test_pattern(
|
|||
{
|
||||
struct encoder_set_dp_phy_pattern_param pattern_param = {0};
|
||||
struct link_encoder *encoder;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
enum dp_link_encoding link_encoding_format = dp_get_link_encoding_format(&link->cur_link_settings);
|
||||
#endif
|
||||
|
||||
/* Access link encoder based on whether it is statically
|
||||
* or dynamically assigned to a link.
|
||||
|
@ -319,8 +390,27 @@ void dp_set_hw_test_pattern(
|
|||
pattern_param.custom_pattern_size = custom_pattern_size;
|
||||
pattern_param.dp_panel_mode = dp_get_panel_mode(link);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
switch (link_encoding_format) {
|
||||
case DP_128b_132b_ENCODING:
|
||||
link->hpo_dp_link_enc->funcs->set_link_test_pattern(
|
||||
link->hpo_dp_link_enc, &pattern_param);
|
||||
break;
|
||||
case DP_8b_10b_ENCODING:
|
||||
ASSERT(encoder);
|
||||
encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param);
|
||||
break;
|
||||
default:
|
||||
DC_LOG_ERROR("%s: Unknown link encoding format.", __func__);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param);
|
||||
#endif
|
||||
}
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#undef DC_LOGGER
|
||||
#endif
|
||||
|
||||
void dp_retrain_link_dp_test(struct dc_link *link,
|
||||
struct dc_link_settings *link_setting,
|
||||
|
@ -468,7 +558,12 @@ void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
|
|||
optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
|
||||
|
||||
/* Enable DSC in encoder */
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)
|
||||
&& !is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
#else
|
||||
if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
#endif
|
||||
DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id);
|
||||
dsc_optc_config_log(dsc, &dsc_optc_cfg);
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
|
||||
|
@ -495,13 +590,21 @@ void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
|
|||
/* disable DSC in stream encoder */
|
||||
if (dc_is_dp_signal(stream->signal)) {
|
||||
|
||||
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
OPTC_DSC_DISABLED, 0, 0);
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc, false, NULL);
|
||||
}
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
false,
|
||||
NULL);
|
||||
else
|
||||
#endif
|
||||
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
OPTC_DSC_DISABLED, 0, 0);
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc, false, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* disable DSC block */
|
||||
|
@ -562,16 +665,32 @@ bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable)
|
|||
dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
|
||||
if (dc_is_dp_signal(stream->signal)) {
|
||||
DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id);
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
true,
|
||||
&dsc_packed_pps[0]);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
true,
|
||||
&dsc_packed_pps[0]);
|
||||
else
|
||||
#endif
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
true,
|
||||
&dsc_packed_pps[0]);
|
||||
}
|
||||
} else {
|
||||
/* disable DSC PPS in stream encoder */
|
||||
if (dc_is_dp_signal(stream->signal)) {
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc, false, NULL);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
false,
|
||||
NULL);
|
||||
else
|
||||
#endif
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc, false, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -593,3 +712,167 @@ bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
|
|||
return true;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#undef DC_LOGGER
|
||||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
|
||||
static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link)
|
||||
{
|
||||
switch (link->link_enc->transmitter) {
|
||||
case TRANSMITTER_UNIPHY_A:
|
||||
return PHYD32CLKA;
|
||||
case TRANSMITTER_UNIPHY_B:
|
||||
return PHYD32CLKB;
|
||||
case TRANSMITTER_UNIPHY_C:
|
||||
return PHYD32CLKC;
|
||||
case TRANSMITTER_UNIPHY_D:
|
||||
return PHYD32CLKD;
|
||||
case TRANSMITTER_UNIPHY_E:
|
||||
return PHYD32CLKE;
|
||||
default:
|
||||
return PHYD32CLKA;
|
||||
}
|
||||
}
|
||||
|
||||
void enable_dp_hpo_output(struct dc_link *link, const struct dc_link_settings *link_settings)
|
||||
{
|
||||
const struct dc *dc = link->dc;
|
||||
enum phyd32clk_clock_source phyd32clk;
|
||||
|
||||
/* Enable PHY PLL at target bit rate
|
||||
* UHBR10 = 10Gbps (SYMCLK32 = 312.5MHz)
|
||||
* UBR13.5 = 13.5Gbps (SYMCLK32 = 421.875MHz)
|
||||
* UHBR20 = 20Gbps (SYMCLK32 = 625MHz)
|
||||
*/
|
||||
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
switch (link_settings->link_rate) {
|
||||
case LINK_RATE_UHBR10:
|
||||
dm_set_phyd32clk(dc->ctx, 312500);
|
||||
break;
|
||||
case LINK_RATE_UHBR13_5:
|
||||
dm_set_phyd32clk(dc->ctx, 412875);
|
||||
break;
|
||||
case LINK_RATE_UHBR20:
|
||||
dm_set_phyd32clk(dc->ctx, 625000);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* DP2.0 HW: call transmitter control to enable PHY */
|
||||
link->hpo_dp_link_enc->funcs->enable_link_phy(
|
||||
link->hpo_dp_link_enc,
|
||||
link_settings,
|
||||
link->link_enc->transmitter);
|
||||
}
|
||||
|
||||
/* DCCG muxing and DTBCLK DTO */
|
||||
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
dc->res_pool->dccg->funcs->set_physymclk(
|
||||
dc->res_pool->dccg,
|
||||
link->link_enc_hw_inst,
|
||||
PHYSYMCLK_FORCE_SRC_PHYD32CLK,
|
||||
true);
|
||||
|
||||
phyd32clk = get_phyd32clk_src(link);
|
||||
dc->res_pool->dccg->funcs->enable_symclk32_le(
|
||||
dc->res_pool->dccg,
|
||||
link->hpo_dp_link_enc->inst,
|
||||
phyd32clk);
|
||||
link->hpo_dp_link_enc->funcs->link_enable(
|
||||
link->hpo_dp_link_enc,
|
||||
link_settings->lane_count);
|
||||
}
|
||||
}
|
||||
|
||||
void disable_dp_hpo_output(struct dc_link *link, enum signal_type signal)
|
||||
{
|
||||
const struct dc *dc = link->dc;
|
||||
|
||||
link->hpo_dp_link_enc->funcs->link_disable(link->hpo_dp_link_enc);
|
||||
|
||||
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
dc->res_pool->dccg->funcs->disable_symclk32_le(
|
||||
dc->res_pool->dccg,
|
||||
link->hpo_dp_link_enc->inst);
|
||||
|
||||
dc->res_pool->dccg->funcs->set_physymclk(
|
||||
dc->res_pool->dccg,
|
||||
link->link_enc_hw_inst,
|
||||
PHYSYMCLK_FORCE_SRC_SYMCLK,
|
||||
false);
|
||||
|
||||
dm_set_phyd32clk(dc->ctx, 0);
|
||||
} else {
|
||||
/* DP2.0 HW: call transmitter control to disable PHY */
|
||||
link->hpo_dp_link_enc->funcs->disable_link_phy(
|
||||
link->hpo_dp_link_enc,
|
||||
signal);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable)
|
||||
{
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
struct pipe_ctx *odm_pipe;
|
||||
int odm_combine_num_segments = 1;
|
||||
enum phyd32clk_clock_source phyd32clk;
|
||||
|
||||
if (enable) {
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
|
||||
odm_combine_num_segments++;
|
||||
|
||||
dc->res_pool->dccg->funcs->set_dpstreamclk(
|
||||
dc->res_pool->dccg,
|
||||
DTBCLK0,
|
||||
pipe_ctx->stream_res.tg->inst);
|
||||
|
||||
phyd32clk = get_phyd32clk_src(stream->link);
|
||||
dc->res_pool->dccg->funcs->enable_symclk32_se(
|
||||
dc->res_pool->dccg,
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->inst,
|
||||
phyd32clk);
|
||||
|
||||
dc->res_pool->dccg->funcs->set_dtbclk_dto(
|
||||
dc->res_pool->dccg,
|
||||
pipe_ctx->stream_res.tg->inst,
|
||||
stream->phy_pix_clk,
|
||||
odm_combine_num_segments,
|
||||
&stream->timing);
|
||||
} else {
|
||||
dc->res_pool->dccg->funcs->set_dtbclk_dto(
|
||||
dc->res_pool->dccg,
|
||||
pipe_ctx->stream_res.tg->inst,
|
||||
0,
|
||||
0,
|
||||
&stream->timing);
|
||||
dc->res_pool->dccg->funcs->disable_symclk32_se(
|
||||
dc->res_pool->dccg,
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->inst);
|
||||
dc->res_pool->dccg->funcs->set_dpstreamclk(
|
||||
dc->res_pool->dccg,
|
||||
REFCLK,
|
||||
pipe_ctx->stream_res.tg->inst);
|
||||
}
|
||||
}
|
||||
|
||||
void reset_dp_hpo_stream_encoders_for_link(struct dc_link *link)
|
||||
{
|
||||
const struct dc *dc = link->dc;
|
||||
struct dc_state *state = dc->current_state;
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
if (state->res_ctx.pipe_ctx[i].stream_res.hpo_dp_stream_enc &&
|
||||
state->res_ctx.pipe_ctx[i].stream &&
|
||||
state->res_ctx.pipe_ctx[i].stream->link == link &&
|
||||
!state->res_ctx.pipe_ctx[i].stream->dpms_off) {
|
||||
setup_dp_hpo_stream(&state->res_ctx.pipe_ctx[i], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef DC_LOGGER
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "set_mode_types.h"
|
||||
#include "virtual/virtual_stream_encoder.h"
|
||||
#include "dpcd_defs.h"
|
||||
#include "dc_link_dp.h"
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_SI)
|
||||
#include "dce60/dce60_resource.h"
|
||||
|
@ -346,6 +347,29 @@ bool resource_construct(
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
pool->hpo_dp_stream_enc_count = 0;
|
||||
if (create_funcs->create_hpo_dp_stream_encoder) {
|
||||
for (i = 0; i < caps->num_hpo_dp_stream_encoder; i++) {
|
||||
pool->hpo_dp_stream_enc[i] = create_funcs->create_hpo_dp_stream_encoder(i+ENGINE_ID_HPO_DP_0, ctx);
|
||||
if (pool->hpo_dp_stream_enc[i] == NULL)
|
||||
DC_ERR("DC: failed to create HPO DP stream encoder!\n");
|
||||
pool->hpo_dp_stream_enc_count++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pool->hpo_dp_link_enc_count = 0;
|
||||
if (create_funcs->create_hpo_dp_link_encoder) {
|
||||
for (i = 0; i < caps->num_hpo_dp_link_encoder; i++) {
|
||||
pool->hpo_dp_link_enc[i] = create_funcs->create_hpo_dp_link_encoder(i, ctx);
|
||||
if (pool->hpo_dp_link_enc[i] == NULL)
|
||||
DC_ERR("DC: failed to create HPO DP link encoder!\n");
|
||||
pool->hpo_dp_link_enc_count++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
for (i = 0; i < caps->num_mpc_3dlut; i++) {
|
||||
pool->mpc_lut[i] = dc_create_3dlut_func();
|
||||
|
@ -1665,6 +1689,22 @@ static void update_stream_engine_usage(
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
static void update_hpo_dp_stream_engine_usage(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct hpo_dp_stream_encoder *hpo_dp_stream_enc,
|
||||
bool acquired)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pool->hpo_dp_stream_enc_count; i++) {
|
||||
if (pool->hpo_dp_stream_enc[i] == hpo_dp_stream_enc)
|
||||
res_ctx->is_hpo_dp_stream_enc_acquired[i] = acquired;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TODO: release audio object */
|
||||
void update_audio_usage(
|
||||
struct resource_context *res_ctx,
|
||||
|
@ -1709,6 +1749,26 @@ static int acquire_first_free_pipe(
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
static struct hpo_dp_stream_encoder *find_first_free_match_hpo_dp_stream_enc_for_link(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct dc_stream_state *stream)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pool->hpo_dp_stream_enc_count; i++) {
|
||||
if (!res_ctx->is_hpo_dp_stream_enc_acquired[i] &&
|
||||
pool->hpo_dp_stream_enc[i]) {
|
||||
|
||||
return pool->hpo_dp_stream_enc[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct audio *find_first_free_audio(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
|
@ -1799,6 +1859,15 @@ enum dc_status dc_remove_stream_from_ctx(
|
|||
if (dc->res_pool->funcs->link_enc_unassign)
|
||||
dc->res_pool->funcs->link_enc_unassign(new_ctx, del_pipe->stream);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(del_pipe)) {
|
||||
update_hpo_dp_stream_engine_usage(
|
||||
&new_ctx->res_ctx, dc->res_pool,
|
||||
del_pipe->stream_res.hpo_dp_stream_enc,
|
||||
false);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (del_pipe->stream_res.audio)
|
||||
update_audio_usage(
|
||||
&new_ctx->res_ctx,
|
||||
|
@ -2051,6 +2120,31 @@ enum dc_status resource_map_pool_resources(
|
|||
pipe_ctx->stream_res.stream_enc,
|
||||
true);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/* Allocate DP HPO Stream Encoder based on signal, hw capabilities
|
||||
* and link settings
|
||||
*/
|
||||
if (dc_is_dp_signal(stream->signal) &&
|
||||
dc->caps.dp_hpo) {
|
||||
struct dc_link_settings link_settings = {0};
|
||||
|
||||
decide_link_settings(stream, &link_settings);
|
||||
if (dp_get_link_encoding_format(&link_settings) == DP_128b_132b_ENCODING) {
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc =
|
||||
find_first_free_match_hpo_dp_stream_enc_for_link(
|
||||
&context->res_ctx, pool, stream);
|
||||
|
||||
if (!pipe_ctx->stream_res.hpo_dp_stream_enc)
|
||||
return DC_NO_STREAM_ENC_RESOURCE;
|
||||
|
||||
update_hpo_dp_stream_engine_usage(
|
||||
&context->res_ctx, pool,
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TODO: Add check if ASIC support and EDID audio */
|
||||
if (!stream->converter_disable_audio &&
|
||||
dc_is_audio_capable_signal(pipe_ctx->stream->signal) &&
|
||||
|
@ -2726,6 +2820,11 @@ bool pipe_need_reprogram(
|
|||
if (pipe_ctx_old->stream_res.dsc != pipe_ctx->stream_res.dsc)
|
||||
return true;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (pipe_ctx_old->stream_res.hpo_dp_stream_enc != pipe_ctx->stream_res.hpo_dp_stream_enc)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
/* DIG link encoder resource assignment for stream changed. */
|
||||
if (pipe_ctx_old->stream->link_enc != pipe_ctx->stream->link_enc)
|
||||
return true;
|
||||
|
@ -2975,3 +3074,22 @@ void get_audio_check(struct audio_info *aud_modes,
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct hpo_dp_link_encoder *resource_get_unused_hpo_dp_link_encoder(
|
||||
const struct resource_pool *pool)
|
||||
{
|
||||
uint8_t i;
|
||||
struct hpo_dp_link_encoder *enc = NULL;
|
||||
|
||||
ASSERT(pool->hpo_dp_link_enc_count <= MAX_HPO_DP2_LINK_ENCODERS);
|
||||
|
||||
for (i = 0; i < pool->hpo_dp_link_enc_count; i++) {
|
||||
if (pool->hpo_dp_link_enc[i]->transmitter == TRANSMITTER_UNKNOWN) {
|
||||
enc = pool->hpo_dp_link_enc[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return enc;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -183,6 +183,9 @@ struct dc_caps {
|
|||
unsigned int cursor_cache_size;
|
||||
struct dc_plane_cap planes[MAX_PLANES];
|
||||
struct dc_color_caps color;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
bool dp_hpo;
|
||||
#endif
|
||||
bool vbios_lttpr_aware;
|
||||
bool vbios_lttpr_enable;
|
||||
};
|
||||
|
@ -289,7 +292,15 @@ struct dc_cap_funcs {
|
|||
|
||||
struct link_training_settings;
|
||||
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
union allow_lttpr_non_transparent_mode {
|
||||
struct {
|
||||
bool DP1_4A : 1;
|
||||
bool DP2_0 : 1;
|
||||
} bits;
|
||||
unsigned char raw;
|
||||
};
|
||||
#endif
|
||||
/* Structure to hold configuration flags set by dm at dc creation. */
|
||||
struct dc_config {
|
||||
bool gpu_vm_support;
|
||||
|
@ -302,7 +313,11 @@ struct dc_config {
|
|||
bool edp_no_power_sequencing;
|
||||
bool force_enum_edp;
|
||||
bool forced_clocks;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
union allow_lttpr_non_transparent_mode allow_lttpr_non_transparent_mode;
|
||||
#else
|
||||
bool allow_lttpr_non_transparent_mode;
|
||||
#endif
|
||||
bool multi_mon_pp_mclk_switch;
|
||||
bool disable_dmcu;
|
||||
bool enable_4to1MPC;
|
||||
|
@ -614,6 +629,10 @@ struct dc_debug_options {
|
|||
bool enable_dmcub_surface_flip;
|
||||
bool usbc_combo_phy_reset_wa;
|
||||
bool enable_dram_clock_change_one_display_vactive;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/* TODO - remove once tested */
|
||||
bool legacy_dp2_lt;
|
||||
#endif
|
||||
union mem_low_power_enable_options enable_mem_low_power;
|
||||
bool force_vblank_alignment;
|
||||
|
||||
|
@ -1146,6 +1165,12 @@ struct dpcd_caps {
|
|||
struct dc_lttpr_caps lttpr_caps;
|
||||
struct psr_caps psr_caps;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates;
|
||||
union dp_main_line_channel_coding_cap channel_coding_cap;
|
||||
union dp_sink_video_fallback_formats fallback_formats;
|
||||
union dp_fec_capability1 fec_cap1;
|
||||
#endif
|
||||
};
|
||||
|
||||
union dpcd_sink_ext_caps {
|
||||
|
|
|
@ -53,7 +53,17 @@ enum dc_link_rate {
|
|||
LINK_RATE_RBR2 = 0x0C, // Rate_5 (RBR2)- 3.24 Gbps/Lane
|
||||
LINK_RATE_RATE_6 = 0x10, // Rate_6 - 4.32 Gbps/Lane
|
||||
LINK_RATE_HIGH2 = 0x14, // Rate_7 (HBR2)- 5.40 Gbps/Lane
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
LINK_RATE_HIGH3 = 0x1E, // Rate_8 (HBR3)- 8.10 Gbps/Lane
|
||||
/* Starting from DP2.0 link rate enum directly represents actual
|
||||
* link rate value in unit of 10 mbps
|
||||
*/
|
||||
LINK_RATE_UHBR10 = 1000, // UHBR10 - 10.0 Gbps/Lane
|
||||
LINK_RATE_UHBR13_5 = 1350, // UHBR13.5 - 13.5 Gbps/Lane
|
||||
LINK_RATE_UHBR20 = 2000, // UHBR10 - 20.0 Gbps/Lane
|
||||
#else
|
||||
LINK_RATE_HIGH3 = 0x1E // Rate_8 (HBR3)- 8.10 Gbps/Lane
|
||||
#endif
|
||||
};
|
||||
|
||||
enum dc_link_spread {
|
||||
|
@ -90,17 +100,47 @@ enum dc_post_cursor2 {
|
|||
POST_CURSOR2_MAX_LEVEL = POST_CURSOR2_LEVEL3,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
enum dc_dp_ffe_preset_level {
|
||||
DP_FFE_PRESET_LEVEL0 = 0,
|
||||
DP_FFE_PRESET_LEVEL1,
|
||||
DP_FFE_PRESET_LEVEL2,
|
||||
DP_FFE_PRESET_LEVEL3,
|
||||
DP_FFE_PRESET_LEVEL4,
|
||||
DP_FFE_PRESET_LEVEL5,
|
||||
DP_FFE_PRESET_LEVEL6,
|
||||
DP_FFE_PRESET_LEVEL7,
|
||||
DP_FFE_PRESET_LEVEL8,
|
||||
DP_FFE_PRESET_LEVEL9,
|
||||
DP_FFE_PRESET_LEVEL10,
|
||||
DP_FFE_PRESET_LEVEL11,
|
||||
DP_FFE_PRESET_LEVEL12,
|
||||
DP_FFE_PRESET_LEVEL13,
|
||||
DP_FFE_PRESET_LEVEL14,
|
||||
DP_FFE_PRESET_LEVEL15,
|
||||
DP_FFE_PRESET_MAX_LEVEL = DP_FFE_PRESET_LEVEL15,
|
||||
};
|
||||
#endif
|
||||
|
||||
enum dc_dp_training_pattern {
|
||||
DP_TRAINING_PATTERN_SEQUENCE_1 = 0,
|
||||
DP_TRAINING_PATTERN_SEQUENCE_2,
|
||||
DP_TRAINING_PATTERN_SEQUENCE_3,
|
||||
DP_TRAINING_PATTERN_SEQUENCE_4,
|
||||
DP_TRAINING_PATTERN_VIDEOIDLE,
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
DP_128b_132b_TPS1,
|
||||
DP_128b_132b_TPS2,
|
||||
DP_128b_132b_TPS2_CDS,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum dp_link_encoding {
|
||||
DP_UNKNOWN_ENCODING = 0,
|
||||
DP_8b_10b_ENCODING = 1,
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
DP_128b_132b_ENCODING = 2,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dc_link_settings {
|
||||
|
@ -112,10 +152,26 @@ struct dc_link_settings {
|
|||
bool dpcd_source_device_specific_field_support;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
union dc_dp_ffe_preset {
|
||||
struct {
|
||||
uint8_t level : 4;
|
||||
uint8_t reserved : 1;
|
||||
uint8_t no_preshoot : 1;
|
||||
uint8_t no_deemphasis : 1;
|
||||
uint8_t method2 : 1;
|
||||
} settings;
|
||||
uint8_t raw;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct dc_lane_settings {
|
||||
enum dc_voltage_swing VOLTAGE_SWING;
|
||||
enum dc_pre_emphasis PRE_EMPHASIS;
|
||||
enum dc_post_cursor2 POST_CURSOR2;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
union dc_dp_ffe_preset FFE_PRESET;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dc_link_training_settings {
|
||||
|
@ -127,6 +183,9 @@ struct dc_link_training_overrides {
|
|||
enum dc_voltage_swing *voltage_swing;
|
||||
enum dc_pre_emphasis *pre_emphasis;
|
||||
enum dc_post_cursor2 *post_cursor2;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
union dc_dp_ffe_preset *ffe_preset;
|
||||
#endif
|
||||
|
||||
uint16_t *cr_pattern_time;
|
||||
uint16_t *eq_pattern_time;
|
||||
|
@ -140,6 +199,16 @@ struct dc_link_training_overrides {
|
|||
bool *fec_enable;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
union payload_table_update_status {
|
||||
struct {
|
||||
uint8_t VC_PAYLOAD_TABLE_UPDATED:1;
|
||||
uint8_t ACT_HANDLED:1;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
#endif
|
||||
|
||||
union dpcd_rev {
|
||||
struct {
|
||||
uint8_t MINOR:4;
|
||||
|
@ -227,7 +296,14 @@ union lane_align_status_updated {
|
|||
struct {
|
||||
uint8_t INTERLANE_ALIGN_DONE:1;
|
||||
uint8_t POST_LT_ADJ_REQ_IN_PROGRESS:1;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
uint8_t EQ_INTERLANE_ALIGN_DONE_128b_132b:1;
|
||||
uint8_t CDS_INTERLANE_ALIGN_DONE_128b_132b:1;
|
||||
uint8_t LT_FAILED_128b_132b:1;
|
||||
uint8_t RESERVED:1;
|
||||
#else
|
||||
uint8_t RESERVED:4;
|
||||
#endif
|
||||
uint8_t DOWNSTREAM_PORT_STATUS_CHANGED:1;
|
||||
uint8_t LINK_STATUS_UPDATED:1;
|
||||
} bits;
|
||||
|
@ -240,6 +316,12 @@ union lane_adjust {
|
|||
uint8_t PRE_EMPHASIS_LANE:2;
|
||||
uint8_t RESERVED:4;
|
||||
} bits;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct {
|
||||
uint8_t PRESET_VALUE :4;
|
||||
uint8_t RESERVED :4;
|
||||
} tx_ffe;
|
||||
#endif
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
|
@ -269,6 +351,12 @@ union dpcd_training_lane {
|
|||
uint8_t MAX_PRE_EMPHASIS_REACHED:1;
|
||||
uint8_t RESERVED:2;
|
||||
} bits;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct {
|
||||
uint8_t PRESET_VALUE :4;
|
||||
uint8_t RESERVED :4;
|
||||
} tx_ffe;
|
||||
#endif
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
|
@ -551,12 +639,18 @@ union test_response {
|
|||
|
||||
union phy_test_pattern {
|
||||
struct {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/* This field is 7 bits for DP2.0 */
|
||||
uint8_t PATTERN :7;
|
||||
uint8_t RESERVED :1;
|
||||
#else
|
||||
/* DpcdPhyTestPatterns. This field is 2 bits for DP1.1
|
||||
* and 3 bits for DP1.2.
|
||||
*/
|
||||
uint8_t PATTERN :3;
|
||||
/* BY speci, bit7:2 is 0 for DP1.1. */
|
||||
uint8_t RESERVED :5;
|
||||
#endif
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
@ -634,7 +728,14 @@ union dpcd_fec_capability {
|
|||
uint8_t UNCORRECTED_BLOCK_ERROR_COUNT_CAPABLE:1;
|
||||
uint8_t CORRECTED_BLOCK_ERROR_COUNT_CAPABLE:1;
|
||||
uint8_t BIT_ERROR_COUNT_CAPABLE:1;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
uint8_t PARITY_BLOCK_ERROR_COUNT_CAPABLE:1;
|
||||
uint8_t ARITY_BIT_ERROR_COUNT_CAPABLE:1;
|
||||
uint8_t FEC_RUNNING_INDICATOR_SUPPORTED:1;
|
||||
uint8_t FEC_ERROR_REPORTING_POLICY_SUPPORTED:1;
|
||||
#else
|
||||
uint8_t RESERVED:4;
|
||||
#endif
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
@ -758,4 +859,125 @@ struct psr_caps {
|
|||
bool psr_exit_link_training_required;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#define DP_MAIN_LINK_CHANNEL_CODING_CAP 0x006
|
||||
#define DP_SINK_VIDEO_FALLBACK_FORMATS 0x020
|
||||
#define DP_FEC_CAPABILITY_1 0x091
|
||||
#define DP_DFP_CAPABILITY_EXTENSION_SUPPORT 0x0A3
|
||||
#define DP_DSC_CONFIGURATION 0x161
|
||||
#define DP_PHY_SQUARE_PATTERN 0x249
|
||||
#define DP_128b_132b_SUPPORTED_LINK_RATES 0x2215
|
||||
#define DP_128b_132b_TRAINING_AUX_RD_INTERVAL 0x2216
|
||||
#define DP_TEST_264BIT_CUSTOM_PATTERN_7_0 0X2230
|
||||
#define DP_TEST_264BIT_CUSTOM_PATTERN_263_256 0X2250
|
||||
#define DP_DSC_SUPPORT_AND_DECODER_COUNT 0x2260
|
||||
#define DP_DSC_MAX_SLICE_COUNT_AND_AGGREGATION_0 0x2270
|
||||
# define DP_DSC_DECODER_0_MAXIMUM_SLICE_COUNT_MASK (1 << 0)
|
||||
# define DP_DSC_DECODER_0_AGGREGATION_SUPPORT_MASK (0b111 << 1)
|
||||
# define DP_DSC_DECODER_0_AGGREGATION_SUPPORT_SHIFT 1
|
||||
# define DP_DSC_DECODER_COUNT_MASK (0b111 << 5)
|
||||
# define DP_DSC_DECODER_COUNT_SHIFT 5
|
||||
#define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108
|
||||
#define DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER 0xF0006
|
||||
#define DP_PHY_REPEATER_128b_132b_RATES 0xF0007
|
||||
#define DP_128b_132b_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 0xF0022
|
||||
#define DP_INTRA_HOP_AUX_REPLY_INDICATION (1 << 3)
|
||||
/* TODO - Use DRM header to replace above once available */
|
||||
|
||||
union dp_main_line_channel_coding_cap {
|
||||
struct {
|
||||
uint8_t DP_8b_10b_SUPPORTED :1;
|
||||
uint8_t DP_128b_132b_SUPPORTED :1;
|
||||
uint8_t RESERVED :6;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
union dp_main_link_channel_coding_lttpr_cap {
|
||||
struct {
|
||||
uint8_t DP_128b_132b_SUPPORTED :1;
|
||||
uint8_t RESERVED :7;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
union dp_128b_132b_supported_link_rates {
|
||||
struct {
|
||||
uint8_t UHBR10 :1;
|
||||
uint8_t UHBR20 :1;
|
||||
uint8_t UHBR13_5:1;
|
||||
uint8_t RESERVED:5;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
union dp_128b_132b_supported_lttpr_link_rates {
|
||||
struct {
|
||||
uint8_t UHBR10 :1;
|
||||
uint8_t UHBR13_5:1;
|
||||
uint8_t UHBR20 :1;
|
||||
uint8_t RESERVED:5;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
union dp_sink_video_fallback_formats {
|
||||
struct {
|
||||
uint8_t dp_1024x768_60Hz_24bpp_support :1;
|
||||
uint8_t dp_1280x720_60Hz_24bpp_support :1;
|
||||
uint8_t dp_1920x1080_60Hz_24bpp_support :1;
|
||||
uint8_t RESERVED :5;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
union dp_fec_capability1 {
|
||||
struct {
|
||||
uint8_t AGGREGATED_ERROR_COUNTERS_CAPABLE :1;
|
||||
uint8_t RESERVED :7;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
struct dp_color_depth_caps {
|
||||
uint8_t support_6bpc :1;
|
||||
uint8_t support_8bpc :1;
|
||||
uint8_t support_10bpc :1;
|
||||
uint8_t support_12bpc :1;
|
||||
uint8_t support_16bpc :1;
|
||||
uint8_t RESERVED :3;
|
||||
};
|
||||
|
||||
struct dp_encoding_format_caps {
|
||||
uint8_t support_rgb :1;
|
||||
uint8_t support_ycbcr444:1;
|
||||
uint8_t support_ycbcr422:1;
|
||||
uint8_t support_ycbcr420:1;
|
||||
uint8_t RESERVED :4;
|
||||
};
|
||||
|
||||
union dp_dfp_cap_ext {
|
||||
struct {
|
||||
uint8_t supported;
|
||||
uint8_t max_pixel_rate_in_mps[2];
|
||||
uint8_t max_video_h_active_width[2];
|
||||
uint8_t max_video_v_active_height[2];
|
||||
struct dp_encoding_format_caps encoding_format_caps;
|
||||
struct dp_color_depth_caps rgb_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr444_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr422_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr420_color_depth_caps;
|
||||
} fields;
|
||||
uint8_t raw[12];
|
||||
};
|
||||
|
||||
union dp_128b_132b_training_aux_rd_interval {
|
||||
struct {
|
||||
uint8_t VALUE :7;
|
||||
uint8_t UNIT :1;
|
||||
} bits;
|
||||
uint8_t raw;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* DC_DP_TYPES_H */
|
||||
|
|
|
@ -154,6 +154,9 @@ struct dc_link {
|
|||
|
||||
struct panel_cntl *panel_cntl;
|
||||
struct link_encoder *link_enc;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct hpo_dp_link_encoder *hpo_dp_link_enc;
|
||||
#endif
|
||||
struct graphics_object_id link_id;
|
||||
/* Endpoint type distinguishes display endpoints which do not have entries
|
||||
* in the BIOS connector table from those that do. Helps when tracking link
|
||||
|
|
|
@ -395,9 +395,27 @@ struct dc_lttpr_caps {
|
|||
uint8_t max_link_rate;
|
||||
uint8_t phy_repeater_cnt;
|
||||
uint8_t max_ext_timeout;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
union dp_main_link_channel_coding_lttpr_cap main_link_channel_coding;
|
||||
union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates;
|
||||
#endif
|
||||
uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1];
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct dc_dongle_dfp_cap_ext {
|
||||
bool supported;
|
||||
uint16_t max_pixel_rate_in_mps;
|
||||
uint16_t max_video_h_active_width;
|
||||
uint16_t max_video_v_active_height;
|
||||
struct dp_encoding_format_caps encoding_format_caps;
|
||||
struct dp_color_depth_caps rgb_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr444_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr422_color_depth_caps;
|
||||
struct dp_color_depth_caps ycbcr420_color_depth_caps;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct dc_dongle_caps {
|
||||
/* dongle type (DP converter, CV smart dongle) */
|
||||
enum display_dongle_type dongle_type;
|
||||
|
@ -411,6 +429,9 @@ struct dc_dongle_caps {
|
|||
bool is_dp_hdmi_ycbcr420_converter;
|
||||
uint32_t dp_hdmi_max_bpc;
|
||||
uint32_t dp_hdmi_max_pixel_clk_in_khz;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct dc_dongle_dfp_cap_ext dfp_cap_ext;
|
||||
#endif
|
||||
};
|
||||
/* Scaling format */
|
||||
enum scaling_transformation {
|
||||
|
|
|
@ -1108,8 +1108,17 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
|
|||
clk_mgr->funcs->enable_pme_wa(clk_mgr);
|
||||
/* un-mute audio */
|
||||
/* TODO: audio should be per stream rather than per link */
|
||||
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->audio_mute_control(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc, false);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
|
||||
pipe_ctx->stream_res.stream_enc, false);
|
||||
#else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
|
||||
pipe_ctx->stream_res.stream_enc, false);
|
||||
#endif
|
||||
if (pipe_ctx->stream_res.audio)
|
||||
pipe_ctx->stream_res.audio->enabled = true;
|
||||
}
|
||||
|
@ -1129,14 +1138,32 @@ void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx)
|
|||
if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false)
|
||||
return;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->audio_mute_control(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc, true);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
|
||||
pipe_ctx->stream_res.stream_enc, true);
|
||||
#else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
|
||||
pipe_ctx->stream_res.stream_enc, true);
|
||||
#endif
|
||||
if (pipe_ctx->stream_res.audio) {
|
||||
pipe_ctx->stream_res.audio->enabled = false;
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_disable(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable(
|
||||
pipe_ctx->stream_res.stream_enc);
|
||||
#else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable(
|
||||
pipe_ctx->stream_res.stream_enc);
|
||||
#endif
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable(
|
||||
pipe_ctx->stream_res.stream_enc);
|
||||
|
@ -1166,16 +1193,37 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
|
|||
pipe_ctx->stream_res.stream_enc);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->stop_dp_info_packets(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc);
|
||||
} else if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
#else
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
#endif
|
||||
pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets(
|
||||
pipe_ctx->stream_res.stream_enc);
|
||||
|
||||
dc->hwss.disable_audio_stream(pipe_ctx);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->disable(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc);
|
||||
setup_dp_hpo_stream(pipe_ctx, false);
|
||||
/* TODO - DP2.0 HW: unmap stream from link encoder here */
|
||||
} else {
|
||||
link->link_enc->funcs->connect_dig_be_to_fe(
|
||||
link->link_enc,
|
||||
pipe_ctx->stream_res.stream_enc->id,
|
||||
false);
|
||||
}
|
||||
#else
|
||||
link->link_enc->funcs->connect_dig_be_to_fe(
|
||||
link->link_enc,
|
||||
pipe_ctx->stream_res.stream_enc->id,
|
||||
false);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -1210,7 +1258,15 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
|
|||
link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
/* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_blank(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc);
|
||||
} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
|
||||
#else
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
|
||||
#endif
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
|
||||
|
||||
if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) {
|
||||
|
@ -1451,10 +1507,23 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
|||
build_audio_output(context, pipe_ctx, &audio_output);
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_setup(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
pipe_ctx->stream_res.audio->inst,
|
||||
&pipe_ctx->stream->audio_info);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
pipe_ctx->stream_res.audio->inst,
|
||||
&pipe_ctx->stream->audio_info);
|
||||
#else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
pipe_ctx->stream_res.audio->inst,
|
||||
&pipe_ctx->stream->audio_info);
|
||||
#endif
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
|
@ -1469,10 +1538,18 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
|||
&pipe_ctx->stream->audio_info);
|
||||
}
|
||||
|
||||
/* */
|
||||
/* Do not touch stream timing on seamless boot optimization. */
|
||||
if (!pipe_ctx->stream->apply_seamless_boot_optimization)
|
||||
hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/* DCN3.1 FPGA Workaround
|
||||
* Need to enable HPO DP Stream Encoder before setting OTG master enable.
|
||||
* To do so, move calling function enable_stream_timing to only be done AFTER calling
|
||||
* function core_link_enable_stream
|
||||
*/
|
||||
if (!(hws->wa.dp_hpo_and_otg_sequence && is_dp_128b_132b_signal(pipe_ctx)))
|
||||
#endif
|
||||
/* */
|
||||
/* Do not touch stream timing on seamless boot optimization. */
|
||||
if (!pipe_ctx->stream->apply_seamless_boot_optimization)
|
||||
hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
|
||||
|
||||
if (hws->funcs.setup_vupdate_interrupt)
|
||||
hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
|
||||
|
@ -1526,6 +1603,18 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
|||
if (!stream->dpms_off)
|
||||
core_link_enable_stream(context, pipe_ctx);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/* DCN3.1 FPGA Workaround
|
||||
* Need to enable HPO DP Stream Encoder before setting OTG master enable.
|
||||
* To do so, move calling function enable_stream_timing to only be done AFTER calling
|
||||
* function core_link_enable_stream
|
||||
*/
|
||||
if (hws->wa.dp_hpo_and_otg_sequence && is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
if (!pipe_ctx->stream->apply_seamless_boot_optimization)
|
||||
hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
|
||||
}
|
||||
#endif
|
||||
|
||||
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
|
||||
|
||||
pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false;
|
||||
|
|
|
@ -1460,5 +1460,14 @@ void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
|||
if (enc->features.flags.bits.IS_HBR3_CAPABLE)
|
||||
max_link_cap.link_rate = LINK_RATE_HIGH3;
|
||||
|
||||
if (enc->features.flags.bits.IS_UHBR10_CAPABLE)
|
||||
max_link_cap.link_rate = LINK_RATE_UHBR10;
|
||||
|
||||
if (enc->features.flags.bits.IS_UHBR13_5_CAPABLE)
|
||||
max_link_cap.link_rate = LINK_RATE_UHBR13_5;
|
||||
|
||||
if (enc->features.flags.bits.IS_UHBR20_CAPABLE)
|
||||
max_link_cap.link_rate = LINK_RATE_UHBR20;
|
||||
|
||||
*link_settings = max_link_cap;
|
||||
}
|
||||
|
|
|
@ -2135,7 +2135,12 @@ void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx,
|
|||
|
||||
params.link_settings.link_rate = link_settings->link_rate;
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
/* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_unblank(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
pipe_ctx->stream_res.tg->inst);
|
||||
} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
|
||||
if (optc2_is_two_pixels_per_containter(&stream->timing) || params.opp_cnt > 1)
|
||||
params.timing.pix_clk_100hz /= 2;
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine(
|
||||
|
@ -2380,8 +2385,19 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
|
|||
* disconnect them during disable_stream
|
||||
* BY this, it is logic clean to separate stream and link
|
||||
*/
|
||||
link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
|
||||
pipe_ctx->stream_res.stream_enc->id, true);
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
setup_dp_hpo_stream(pipe_ctx, true);
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->enable_stream(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc);
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->map_stream_to_link(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->inst,
|
||||
link->hpo_dp_link_enc->inst);
|
||||
}
|
||||
|
||||
if (!is_dp_128b_132b_signal(pipe_ctx))
|
||||
link->link_enc->funcs->connect_dig_be_to_fe(
|
||||
link->link_enc, pipe_ctx->stream_res.stream_enc->id, true);
|
||||
|
||||
if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) {
|
||||
if (link->dc->hwss.program_dmdata_engine)
|
||||
|
@ -2406,7 +2422,9 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
|
|||
|
||||
/* enable audio only within mode set */
|
||||
if (pipe_ctx->stream_res.audio != NULL) {
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.hpo_dp_stream_enc);
|
||||
else if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "dcn20_dccg.h"
|
||||
#include "dcn20_vmid.h"
|
||||
#include "dc_link_ddc.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dce/dce_panel_cntl.h"
|
||||
|
||||
#include "navi10_ip_offset.h"
|
||||
|
@ -1604,6 +1605,7 @@ static void get_pixel_clock_parameters(
|
|||
pixel_clk_params->signal_type = pipe_ctx->stream->signal;
|
||||
pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
|
||||
/* TODO: un-hardcode*/
|
||||
/* TODO - DP2.0 HW: calculate requested_sym_clk for UHBR rates */
|
||||
pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
|
||||
LINK_RATE_REF_FREQ_IN_KHZ;
|
||||
pixel_clk_params->flags.ENABLE_SS = 0;
|
||||
|
@ -3044,6 +3046,8 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
|
|||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||
continue;
|
||||
if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -561,11 +561,6 @@ static const struct dcn10_link_enc_mask le_mask = {
|
|||
DPCS_DCN31_MASK_SH_LIST(_MASK)
|
||||
};
|
||||
|
||||
#define dpp_regs(id)\
|
||||
[id] = {\
|
||||
DPP_REG_LIST_DCN30(id),\
|
||||
}
|
||||
|
||||
#define hpo_dp_stream_encoder_reg_list(id)\
|
||||
[id] = {\
|
||||
DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\
|
||||
|
@ -609,6 +604,11 @@ static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = {
|
|||
DCN3_1_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK)
|
||||
};
|
||||
|
||||
#define dpp_regs(id)\
|
||||
[id] = {\
|
||||
DPP_REG_LIST_DCN30(id),\
|
||||
}
|
||||
|
||||
static const struct dcn3_dpp_registers dpp_regs[] = {
|
||||
dpp_regs(0),
|
||||
dpp_regs(1),
|
||||
|
@ -1449,6 +1449,13 @@ static struct dce_hwseq *dcn31_hwseq_create(
|
|||
hws->regs = &hwseq_reg;
|
||||
hws->shifts = &hwseq_shift;
|
||||
hws->masks = &hwseq_mask;
|
||||
/* DCN3.1 FPGA Workaround
|
||||
* Need to enable HPO DP Stream Encoder before setting OTG master enable.
|
||||
* To do so, move calling function enable_stream_timing to only be done AFTER calling
|
||||
* function core_link_enable_stream
|
||||
*/
|
||||
if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
|
||||
hws->wa.dp_hpo_and_otg_sequence = true;
|
||||
}
|
||||
return hws;
|
||||
}
|
||||
|
@ -2102,6 +2109,7 @@ static bool dcn31_resource_construct(
|
|||
dc->caps.max_slave_rgb_planes = 1;
|
||||
dc->caps.post_blend_color_processing = true;
|
||||
dc->caps.force_dp_tps4_for_cp2520 = true;
|
||||
dc->caps.dp_hpo = true;
|
||||
dc->caps.extended_aux_timeout_support = true;
|
||||
dc->caps.dmcub_support = true;
|
||||
dc->caps.is_apu = true;
|
||||
|
|
|
@ -37,6 +37,7 @@ struct cp_psp_stream_config {
|
|||
uint8_t phy_idx;
|
||||
uint8_t assr_enabled;
|
||||
uint8_t mst_enabled;
|
||||
uint8_t dp2_enabled;
|
||||
void *dm_stream_ctx;
|
||||
bool dpms_off;
|
||||
};
|
||||
|
|
|
@ -160,6 +160,8 @@ void dm_set_dcn_clocks(
|
|||
struct dc_context *ctx,
|
||||
struct dc_clocks *clks);
|
||||
|
||||
void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz);
|
||||
|
||||
bool dm_helpers_dmub_outbox_interrupt_control(struct dc_context *ctx, bool enable);
|
||||
|
||||
void dm_helpers_smu_timeout(struct dc_context *ctx, unsigned int msg_id, unsigned int param, unsigned int timeout_us);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#define LINK_TRAINING_RETRY_DELAY 50 /* ms */
|
||||
#define LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD 3200 /*us*/
|
||||
#define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 552 /*us*/
|
||||
#define MAX_MTP_SLOT_COUNT 64
|
||||
#define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50
|
||||
#define TRAINING_AUX_RD_INTERVAL 100 //us
|
||||
|
||||
|
@ -189,5 +190,26 @@ enum dc_status dpcd_configure_lttpr_mode(
|
|||
struct link_training_settings *lt_settings);
|
||||
|
||||
enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings *link_settings);
|
||||
bool dpcd_write_128b_132b_sst_payload_allocation_table(
|
||||
const struct dc_stream_state *stream,
|
||||
struct dc_link *link,
|
||||
struct link_mst_stream_allocation_table *proposed_table,
|
||||
bool allocate);
|
||||
|
||||
enum dc_status dpcd_configure_channel_coding(
|
||||
struct dc_link *link,
|
||||
struct link_training_settings *lt_settings);
|
||||
|
||||
bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link);
|
||||
|
||||
struct fixed31_32 calculate_sst_avg_time_slots_per_mtp(
|
||||
const struct dc_stream_state *stream,
|
||||
const struct dc_link *link);
|
||||
void enable_dp_hpo_output(struct dc_link *link, const struct dc_link_settings *link_settings);
|
||||
void disable_dp_hpo_output(struct dc_link *link, enum signal_type signal);
|
||||
void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx);
|
||||
void reset_dp_hpo_stream_encoders_for_link(struct dc_link *link);
|
||||
|
||||
bool dp_retrieve_lttpr_cap(struct dc_link *link);
|
||||
#endif /* __DC_LINK_DP_H__ */
|
||||
|
|
|
@ -41,6 +41,9 @@ struct dce_hwseq_wa {
|
|||
bool DEGVIDCN10_254;
|
||||
bool DEGVIDCN21;
|
||||
bool disallow_self_refresh_during_multi_plane_transition;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
bool dp_hpo_and_otg_sequence;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct hwseq_wa_state {
|
||||
|
|
|
@ -200,4 +200,9 @@ int get_num_mpc_splits(struct pipe_ctx *pipe);
|
|||
|
||||
int get_num_odm_splits(struct pipe_ctx *pipe);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct hpo_dp_link_encoder *resource_get_unused_hpo_dp_link_encoder(
|
||||
const struct resource_pool *pool);
|
||||
#endif
|
||||
|
||||
#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
|
||||
|
|
|
@ -80,6 +80,15 @@ enum dpcd_phy_test_patterns {
|
|||
PHY_TEST_PATTERN_CP2520_1,
|
||||
PHY_TEST_PATTERN_CP2520_2,
|
||||
PHY_TEST_PATTERN_CP2520_3, /* same as TPS4 */
|
||||
PHY_TEST_PATTERN_128b_132b_TPS1 = 0x8,
|
||||
PHY_TEST_PATTERN_128b_132b_TPS2 = 0x10,
|
||||
PHY_TEST_PATTERN_PRBS9 = 0x18,
|
||||
PHY_TEST_PATTERN_PRBS11 = 0x20,
|
||||
PHY_TEST_PATTERN_PRBS15 = 0x28,
|
||||
PHY_TEST_PATTERN_PRBS23 = 0x30,
|
||||
PHY_TEST_PATTERN_PRBS31 = 0x38,
|
||||
PHY_TEST_PATTERN_264BIT_CUSTOM = 0x40,
|
||||
PHY_TEST_PATTERN_SQUARE_PULSE = 0x48,
|
||||
};
|
||||
|
||||
enum dpcd_test_dyn_range {
|
||||
|
@ -135,7 +144,14 @@ enum dpcd_training_patterns {
|
|||
DPCD_TRAINING_PATTERN_1,
|
||||
DPCD_TRAINING_PATTERN_2,
|
||||
DPCD_TRAINING_PATTERN_3,
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
DPCD_TRAINING_PATTERN_4 = 7,
|
||||
DPCD_128b_132b_TPS1 = 1,
|
||||
DPCD_128b_132b_TPS2 = 2,
|
||||
DPCD_128b_132b_TPS2_CDS = 3,
|
||||
#else
|
||||
DPCD_TRAINING_PATTERN_4 = 7
|
||||
#endif
|
||||
};
|
||||
|
||||
/* This enum is for use with PsrSinkPsrStatus.bits.sinkSelfRefreshStatus
|
||||
|
|
|
@ -53,7 +53,11 @@ enum edp_revision {
|
|||
};
|
||||
|
||||
enum {
|
||||
LINK_RATE_REF_FREQ_IN_KHZ = 27000 /*27MHz*/
|
||||
LINK_RATE_REF_FREQ_IN_KHZ = 27000, /*27MHz*/
|
||||
BITS_PER_DP_BYTE = 10,
|
||||
DATA_EFFICIENCY_8b_10b_x10000 = 8000, /* 80% data efficiency */
|
||||
DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100 = 97, /* 97% data efficiency when FEC is enabled */
|
||||
DATA_EFFICIENCY_128b_132b_x10000 = 9646, /* 96.71% data efficiency x 99.75% downspread factor */
|
||||
};
|
||||
|
||||
enum link_training_result {
|
||||
|
@ -70,6 +74,12 @@ enum link_training_result {
|
|||
LINK_TRAINING_LINK_LOSS,
|
||||
/* Abort link training (because sink unplugged) */
|
||||
LINK_TRAINING_ABORT,
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
DP_128b_132b_LT_FAILED,
|
||||
DP_128b_132b_MAX_LOOP_COUNT_REACHED,
|
||||
DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT,
|
||||
DP_128b_132b_CDS_DONE_TIMEOUT,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum lttpr_mode {
|
||||
|
@ -86,11 +96,23 @@ struct link_training_settings {
|
|||
enum dc_pre_emphasis *pre_emphasis;
|
||||
enum dc_post_cursor2 *post_cursor2;
|
||||
bool should_set_fec_ready;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/* TODO - factor lane_settings out because it changes during LT */
|
||||
union dc_dp_ffe_preset *ffe_preset;
|
||||
#endif
|
||||
|
||||
uint16_t cr_pattern_time;
|
||||
uint16_t eq_pattern_time;
|
||||
uint16_t cds_pattern_time;
|
||||
enum dc_dp_training_pattern pattern_for_cr;
|
||||
enum dc_dp_training_pattern pattern_for_eq;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
enum dc_dp_training_pattern pattern_for_cds;
|
||||
|
||||
uint32_t eq_wait_time_limit;
|
||||
uint8_t eq_loop_count_limit;
|
||||
uint32_t cds_wait_time_limit;
|
||||
#endif
|
||||
|
||||
bool enhanced_framing;
|
||||
bool allow_invalid_msa_timing_param;
|
||||
|
|
|
@ -72,6 +72,9 @@
|
|||
#define DC_LOG_DSC(...) DRM_DEBUG_KMS(__VA_ARGS__)
|
||||
#define DC_LOG_SMU(...) pr_debug("[SMU_MSG]:"__VA_ARGS__)
|
||||
#define DC_LOG_DWB(...) DRM_DEBUG_KMS(__VA_ARGS__)
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#define DC_LOG_DP2(...) DRM_DEBUG_KMS(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
struct dal_logger;
|
||||
|
||||
|
@ -123,6 +126,9 @@ enum dc_log_type {
|
|||
LOG_MAX_HW_POINTS,
|
||||
LOG_ALL_TF_CHANNELS,
|
||||
LOG_SAMPLE_1DLUT,
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
LOG_DP2,
|
||||
#endif
|
||||
LOG_SECTION_TOTAL_COUNT
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue