Commit 9d8033d6 authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher

drm/amd/display: add setup/reset stream encoder to link_hwss

[why]
Factor setup/reset stream encoder to link hwss.
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Acked-by: default avatarWayne Lin <wayne.lin@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 702f8dd8
......@@ -3441,7 +3441,7 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
struct link_mst_stream_allocation_table proposed_table = {0};
struct fixed31_32 avg_time_slots_per_mtp;
const struct dc_link_settings empty_link_settings = {0};
const struct link_hwss *link_hwss = dc_link_hwss_get(link, &pipe_ctx->link_res);
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
DC_LOGGER_INIT(link->ctx->logger);
/* slot X.Y for SST payload deallocate */
......@@ -3450,9 +3450,11 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
if (link_hwss->set_hblank_min_symbol_width)
link_hwss->set_hblank_min_symbol_width(pipe_ctx,
if (link_hwss->ext.set_throttled_vcp_size)
link_hwss->ext.set_throttled_vcp_size(pipe_ctx,
avg_time_slots_per_mtp);
if (link_hwss->ext.set_hblank_min_symbol_width)
link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
&empty_link_settings,
avg_time_slots_per_mtp);
}
......@@ -3498,9 +3500,11 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
if (link_hwss->set_hblank_min_symbol_width)
link_hwss->set_hblank_min_symbol_width(pipe_ctx,
if (link_hwss->ext.set_throttled_vcp_size)
link_hwss->ext.set_throttled_vcp_size(pipe_ctx,
avg_time_slots_per_mtp);
if (link_hwss->ext.set_hblank_min_symbol_width)
link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
&link->cur_link_settings,
avg_time_slots_per_mtp);
}
......@@ -3526,7 +3530,7 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
struct fixed31_32 pbn_per_slot;
int i;
enum act_return_status ret;
const struct link_hwss *link_hwss = dc_link_hwss_get(link, &pipe_ctx->link_res);
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
DC_LOGGER_INIT(link->ctx->logger);
/* Link encoder may have been dynamically assigned to non-physical display endpoint. */
......@@ -3634,9 +3638,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
if (link_hwss->set_hblank_min_symbol_width)
link_hwss->set_hblank_min_symbol_width(pipe_ctx,
if (link_hwss->ext.set_throttled_vcp_size)
link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
if (link_hwss->ext.set_hblank_min_symbol_width)
link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
&link->cur_link_settings,
avg_time_slots_per_mtp);
......@@ -3655,7 +3660,7 @@ enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw
struct dp_mst_stream_allocation_table proposed_table = {0};
uint8_t i;
enum act_return_status ret;
const struct link_hwss *link_hwss = dc_link_hwss_get(link, &pipe_ctx->link_res);
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
DC_LOGGER_INIT(link->ctx->logger);
/* decrease throttled vcp size */
......@@ -3663,9 +3668,10 @@ enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw
pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
if (link_hwss->set_hblank_min_symbol_width)
link_hwss->set_hblank_min_symbol_width(pipe_ctx,
if (link_hwss->ext.set_throttled_vcp_size)
link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
if (link_hwss->ext.set_hblank_min_symbol_width)
link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
&link->cur_link_settings,
avg_time_slots_per_mtp);
......@@ -3737,7 +3743,7 @@ enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t
struct dp_mst_stream_allocation_table proposed_table = {0};
uint8_t i;
enum act_return_status ret;
const struct link_hwss *link_hwss = dc_link_hwss_get(link, &pipe_ctx->link_res);
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
DC_LOGGER_INIT(link->ctx->logger);
/* notify immediate branch device table update */
......@@ -3796,9 +3802,10 @@ enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t
pbn_per_slot = get_pbn_per_slot(stream);
avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
if (link_hwss->set_hblank_min_symbol_width)
link_hwss->set_hblank_min_symbol_width(pipe_ctx,
if (link_hwss->ext.set_throttled_vcp_size)
link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
if (link_hwss->ext.set_hblank_min_symbol_width)
link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
&link->cur_link_settings,
avg_time_slots_per_mtp);
......@@ -3815,7 +3822,7 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
int i;
bool mst_mode = (link->type == dc_connection_mst_branch);
const struct link_hwss *link_hwss = dc_link_hwss_get(link, &pipe_ctx->link_res);
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
const struct dc_link_settings empty_link_settings = {0};
DC_LOGGER_INIT(link->ctx->logger);
......@@ -3834,9 +3841,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
*/
/* slot X.Y */
link_hwss->set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
if (link_hwss->set_hblank_min_symbol_width)
link_hwss->set_hblank_min_symbol_width(pipe_ctx,
if (link_hwss->ext.set_throttled_vcp_size)
link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
if (link_hwss->ext.set_hblank_min_symbol_width)
link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
&empty_link_settings,
avg_time_slots_per_mtp);
......@@ -4004,8 +4012,8 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi
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};
const struct link_hwss *link_hwss = get_link_hwss(stream->link, &pipe_ctx->link_res);
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
decide_link_settings(stream, &link_settings);
......@@ -4066,12 +4074,8 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi
pipe_ctx->link_res.hpo_dp_link_enc,
&proposed_table);
pipe_ctx->link_res.hpo_dp_link_enc->funcs->set_throttled_vcp_size(
pipe_ctx->link_res.hpo_dp_link_enc,
pipe_ctx->stream_res.hpo_dp_stream_enc->inst,
avg_time_slots_per_mtp);
if (link_hwss->ext.set_throttled_vcp_size)
link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
dc->hwss.unblank_stream(pipe_ctx, &stream->link->cur_link_settings);
}
......
......@@ -2700,26 +2700,15 @@ bool perform_link_training_with_retries(
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
enum dp_panel_mode panel_mode = dp_get_panel_mode(link);
struct link_encoder *link_enc;
enum link_training_result status = LINK_TRAINING_CR_FAIL_LANE0;
struct dc_link_settings current_setting = *link_setting;
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
/* Dynamically assigned link encoders associated with stream rather than
* link.
*/
if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign)
link_enc = link_enc_cfg_get_link_enc_used_by_stream(link->ctx->dc, pipe_ctx->stream);
else
link_enc = link->link_enc;
/* We need to do this before the link training to ensure the idle pattern in SST
* mode will be sent right after the link training
*/
if (dp_get_link_encoding_format(&current_setting) == DP_8b_10b_ENCODING) {
link_enc->funcs->connect_dig_be_to_fe(link_enc,
pipe_ctx->stream_res.stream_enc->id, true);
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
}
if (dp_get_link_encoding_format(&current_setting) == DP_8b_10b_ENCODING)
/* We need to do this before the link training to ensure the idle
* pattern in SST mode will be sent right after the link training
*/
link_hwss->setup_stream_encoder(pipe_ctx);
for (j = 0; j < attempts; ++j) {
......
......@@ -784,54 +784,8 @@ void disable_dp_hpo_output(struct dc_link *link,
}
}
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);
}
}
static void set_dummy_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
struct fixed31_32 throttled_vcp_size);
static void virtual_setup_stream_encoder(struct pipe_ctx *pipe_ctx);
static void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx);
/************************* below goes to dio_link_hwss ************************/
static bool can_use_dio_link_hwss(const struct dc_link *link,
......@@ -850,8 +804,48 @@ static void set_dio_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
throttled_vcp_size);
}
static struct link_encoder *get_dio_link_encoder(const struct dc_link *link)
{
/* Link encoder may have been dynamically assigned to non-physical display endpoint. */
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign)
return link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
else
return link->link_enc;
}
static void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
{
struct link_encoder *link_enc = get_dio_link_encoder(pipe_ctx->stream->link);
ASSERT(link_enc);
link_enc->funcs->connect_dig_be_to_fe(link_enc,
pipe_ctx->stream_res.stream_enc->id, true);
if (dc_is_dp_signal(pipe_ctx->stream->signal))
dp_source_sequence_trace(pipe_ctx->stream->link,
DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
}
static void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
{
struct link_encoder *link_enc = get_dio_link_encoder(pipe_ctx->stream->link);
link_enc->funcs->connect_dig_be_to_fe(
link_enc,
pipe_ctx->stream_res.stream_enc->id,
false);
if (dc_is_dp_signal(pipe_ctx->stream->signal))
dp_source_sequence_trace(pipe_ctx->stream->link,
DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE);
}
static const struct link_hwss dio_link_hwss = {
.set_throttled_vcp_size = set_dio_throttled_vcp_size,
.setup_stream_encoder = setup_dio_stream_encoder,
.reset_stream_encoder = reset_dio_stream_encoder,
.ext = {
.set_throttled_vcp_size = set_dio_throttled_vcp_size,
},
};
/*********************** below goes to hpo_dp_link_hwss ***********************/
......@@ -895,13 +889,57 @@ static void set_dp_hpo_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx,
hblank_min_symbol_width);
}
static const struct link_hwss hpo_dp_link_hwss = {
.set_throttled_vcp_size = set_dp_hpo_throttled_vcp_size,
static int get_odm_segment_count(struct pipe_ctx *pipe_ctx)
{
struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
int count = 1;
/* function pointers below this point require check for NULL
* *********************************************************************
*/
.set_hblank_min_symbol_width = set_dp_hpo_hblank_min_symbol_width,
while (odm_pipe != NULL) {
count++;
odm_pipe = odm_pipe->next_odm_pipe;
}
return count;
}
static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
{
struct dc *dc = pipe_ctx->stream->ctx->dc;
struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
struct hpo_dp_link_encoder *link_enc = pipe_ctx->link_res.hpo_dp_link_enc;
struct dccg *dccg = dc->res_pool->dccg;
struct timing_generator *tg = pipe_ctx->stream_res.tg;
int odm_segment_count = get_odm_segment_count(pipe_ctx);
enum phyd32clk_clock_source phyd32clk = get_phyd32clk_src(pipe_ctx->stream->link);
dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst);
dccg->funcs->enable_symclk32_se(dccg, stream_enc->inst, phyd32clk);
dccg->funcs->set_dtbclk_dto(dccg, tg->inst, pipe_ctx->stream->phy_pix_clk,
odm_segment_count,
&pipe_ctx->stream->timing);
stream_enc->funcs->enable_stream(stream_enc);
stream_enc->funcs->map_stream_to_link(stream_enc, stream_enc->inst, link_enc->inst);
}
static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
{
struct dc *dc = pipe_ctx->stream->ctx->dc;
struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
struct dccg *dccg = dc->res_pool->dccg;
struct timing_generator *tg = pipe_ctx->stream_res.tg;
stream_enc->funcs->disable(stream_enc);
dccg->funcs->set_dtbclk_dto(dccg, tg->inst, 0, 0, &pipe_ctx->stream->timing);
dccg->funcs->disable_symclk32_se(dccg, stream_enc->inst);
dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst);
}
static const struct link_hwss hpo_dp_link_hwss = {
.setup_stream_encoder = setup_hpo_dp_stream_encoder,
.reset_stream_encoder = reset_hpo_dp_stream_encoder,
.ext = {
.set_throttled_vcp_size = set_dp_hpo_throttled_vcp_size,
.set_hblank_min_symbol_width = set_dp_hpo_hblank_min_symbol_width,
},
};
/*********************** below goes to dpia_link_hwss *************************/
static bool can_use_dpia_link_hwss(const struct dc_link *link,
......@@ -912,21 +950,27 @@ static bool can_use_dpia_link_hwss(const struct dc_link *link,
}
static const struct link_hwss dpia_link_hwss = {
.set_throttled_vcp_size = set_dio_throttled_vcp_size,
.setup_stream_encoder = setup_dio_stream_encoder,
.reset_stream_encoder = reset_dio_stream_encoder,
.ext = {
.set_throttled_vcp_size = set_dio_throttled_vcp_size,
},
};
/*********************** below goes to link_hwss ******************************/
static void set_dummy_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
struct fixed31_32 throttled_vcp_size)
static void virtual_setup_stream_encoder(struct pipe_ctx *pipe_ctx)
{
return;
}
static const struct link_hwss dummy_link_hwss = {
.set_throttled_vcp_size = set_dummy_throttled_vcp_size,
static void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx)
{
}
static const struct link_hwss virtual_link_hwss = {
.setup_stream_encoder = virtual_setup_stream_encoder,
.reset_stream_encoder = virtual_reset_stream_encoder,
};
const struct link_hwss *dc_link_hwss_get(const struct dc_link *link,
const struct link_hwss *get_link_hwss(const struct dc_link *link,
const struct link_resource *link_res)
{
if (can_use_dp_hpo_link_hwss(link, link_res))
......@@ -953,7 +997,7 @@ const struct link_hwss *dc_link_hwss_get(const struct dc_link *link,
else if (can_use_dio_link_hwss(link, link_res))
return &dio_link_hwss;
else
return &dummy_link_hwss;
return &virtual_link_hwss;
}
#undef DC_LOGGER
......@@ -667,17 +667,12 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
struct dc_link *link = pipe_ctx->stream->link;
const struct dc *dc = link->dc;
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
uint32_t active_total_with_borders;
uint32_t early_control = 0;
struct timing_generator *tg = pipe_ctx->stream_res.tg;
/* For MST, there are multiply stream go to only one link.
* connect DIG back_end to front_end while enable_stream and
* 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);
link_hwss->setup_stream_encoder(pipe_ctx);
dc->hwss.update_info_frame(pipe_ctx);
......@@ -1178,7 +1173,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
struct dc *dc = pipe_ctx->stream->ctx->dc;
struct link_encoder *link_enc = NULL;
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) {
pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets(
......@@ -1196,34 +1191,17 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
dc->hwss.disable_audio_stream(pipe_ctx);
/* Link encoder may have been dynamically assigned to non-physical display endpoint. */
if (link->ep_type == DISPLAY_ENDPOINT_PHY)
link_enc = link->link_enc;
else if (dc->res_pool->funcs->link_encs_assign)
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
ASSERT(link_enc);
link_hwss->reset_stream_encoder(pipe_ctx);
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 {
if (link_enc)
link_enc->funcs->connect_dig_be_to_fe(
link_enc,
pipe_ctx->stream_res.stream_enc->id,
false);
/* TODO: This looks like a bug to me as we are disabling HPO IO when
* we are just disabling a single HPO stream. Shouldn't we disable HPO
* HW control only when HPOs for all streams are disabled?
*/
if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control)
pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control(
pipe_ctx->stream->ctx->dc->hwseq, false);
}
if (dc_is_dp_signal(pipe_ctx->stream->signal))
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE);
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dc->hwseq->funcs.setup_hpo_hw_control && is_dp_128b_132b_signal(pipe_ctx))
dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, false);
#endif
}
void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
......
......@@ -2390,46 +2390,22 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
uint32_t active_total_with_borders;
uint32_t early_control = 0;
struct timing_generator *tg = pipe_ctx->stream_res.tg;
struct link_encoder *link_enc;
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
struct dc *dc = pipe_ctx->stream->ctx->dc;
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign)
link_enc = link_enc_cfg_get_link_enc_used_by_stream(link->ctx->dc, pipe_ctx->stream);
else
link_enc = link->link_enc;
ASSERT(link_enc);
/* For MST, there are multiply stream go to only one link.
* connect DIG back_end to front_end while enable_stream and
* disconnect them during disable_stream
* BY this, it is logic clean to separate stream and link
*/
if (is_dp_128b_132b_signal(pipe_ctx)) {
if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control)
pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control(
pipe_ctx->stream->ctx->dc->hwseq, true);
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,
pipe_ctx->link_res.hpo_dp_link_enc->inst);
if (dc->hwseq->funcs.setup_hpo_hw_control)
dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, true);
}
if (!is_dp_128b_132b_signal(pipe_ctx) && link_enc)
link_enc->funcs->connect_dig_be_to_fe(
link_enc, pipe_ctx->stream_res.stream_enc->id, true);
if (dc_is_dp_signal(pipe_ctx->stream->signal))
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
link_hwss->setup_stream_encoder(pipe_ctx);
if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) {
if (link->dc->hwss.program_dmdata_engine)
link->dc->hwss.program_dmdata_engine(pipe_ctx);
if (dc->hwss.program_dmdata_engine)
dc->hwss.program_dmdata_engine(pipe_ctx);
}
link->dc->hwss.update_info_frame(pipe_ctx);
dc->hwss.update_info_frame(pipe_ctx);
if (dc_is_dp_signal(pipe_ctx->stream->signal))
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
......
......@@ -77,21 +77,27 @@ struct link_resource;
struct fixed31_32;
struct pipe_ctx;
struct link_hwss {
/* you must define a dummy implementation and assign the function to
* dummy_link_hwss if you don't want to check for NULL pointer
struct link_hwss_ext {
/* function pointers below require check for NULL at all time
* *********************************************************************
*/
void (*set_hblank_min_symbol_width)(struct pipe_ctx *pipe_ctx,
const struct dc_link_settings *link_settings,
struct fixed31_32 throttled_vcp_size);
void (*set_throttled_vcp_size)(struct pipe_ctx *pipe_ctx,
struct fixed31_32 throttled_vcp_size);
};
/* function pointers below this point require check for NULL
struct link_hwss {
struct link_hwss_ext ext;
/* function pointers below MUST be assigned to all types of link_hwss
* *********************************************************************
*/
void (*set_hblank_min_symbol_width)(struct pipe_ctx *pipe_ctx,
const struct dc_link_settings *link_settings,
struct fixed31_32 throttled_vcp_size);
void (*setup_stream_encoder)(struct pipe_ctx *pipe_ctx);
void (*reset_stream_encoder)(struct pipe_ctx *pipe_ctx);
};
const struct link_hwss *dc_link_hwss_get(const struct dc_link *link, const struct link_resource *link_res);
const struct link_hwss *get_link_hwss(const struct dc_link *link, const struct link_resource *link_res);
#endif /* __DC_LINK_HWSS_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment