diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 153 |
1 files changed, 94 insertions, 59 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index df8a7718a85f..bc3ec05bf34b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -466,6 +466,71 @@ void dcn10_log_hw_state(struct dc *dc, log_mpc_crc(dc, log_ctx); + { + int hpo_dp_link_enc_count = 0; + + if (pool->hpo_dp_stream_enc_count > 0) { + DTN_INFO("DP HPO S_ENC: Enabled OTG Format Depth Vid SDP Compressed Link\n"); + for (i = 0; i < pool->hpo_dp_stream_enc_count; i++) { + struct hpo_dp_stream_encoder_state hpo_dp_se_state = {0}; + struct hpo_dp_stream_encoder *hpo_dp_stream_enc = pool->hpo_dp_stream_enc[i]; + + if (hpo_dp_stream_enc && hpo_dp_stream_enc->funcs->read_state) { + hpo_dp_stream_enc->funcs->read_state(hpo_dp_stream_enc, &hpo_dp_se_state); + + DTN_INFO("[%d]: %d %d %6s %d %d %d %d %d\n", + hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0, + hpo_dp_se_state.stream_enc_enabled, + hpo_dp_se_state.otg_inst, + (hpo_dp_se_state.pixel_encoding == 0) ? "4:4:4" : + ((hpo_dp_se_state.pixel_encoding == 1) ? "4:2:2" : + (hpo_dp_se_state.pixel_encoding == 2) ? "4:2:0" : "Y-Only"), + (hpo_dp_se_state.component_depth == 0) ? 6 : + ((hpo_dp_se_state.component_depth == 1) ? 8 : + (hpo_dp_se_state.component_depth == 2) ? 10 : 12), + hpo_dp_se_state.vid_stream_enabled, + hpo_dp_se_state.sdp_enabled, + hpo_dp_se_state.compressed_format, + hpo_dp_se_state.mapped_to_link_enc); + } + } + + DTN_INFO("\n"); + } + + /* log DP HPO L_ENC section if any hpo_dp_link_enc exists */ + for (i = 0; i < dc->link_count; i++) + if (dc->links[i]->hpo_dp_link_enc) + hpo_dp_link_enc_count++; + + if (hpo_dp_link_enc_count) { + DTN_INFO("DP HPO L_ENC: Enabled Mode Lanes Stream Slots VC Rate X VC Rate Y\n"); + + for (i = 0; i < dc->link_count; i++) { + struct hpo_dp_link_encoder *hpo_dp_link_enc = dc->links[i]->hpo_dp_link_enc; + struct hpo_dp_link_enc_state hpo_dp_le_state = {0}; + + if (hpo_dp_link_enc && hpo_dp_link_enc->funcs->read_state) { + hpo_dp_link_enc->funcs->read_state(hpo_dp_link_enc, &hpo_dp_le_state); + DTN_INFO("[%d]: %d %6s %d %d %d %d %d\n", + hpo_dp_link_enc->inst, + hpo_dp_le_state.link_enc_enabled, + (hpo_dp_le_state.link_mode == 0) ? "TPS1" : + (hpo_dp_le_state.link_mode == 1) ? "TPS2" : + (hpo_dp_le_state.link_mode == 2) ? "ACTIVE" : "TEST", + hpo_dp_le_state.lane_count, + hpo_dp_le_state.stream_src[0], + hpo_dp_le_state.slot_count[0], + hpo_dp_le_state.vc_rate_x[0], + hpo_dp_le_state.vc_rate_y[0]); + DTN_INFO("\n"); + } + } + + DTN_INFO("\n"); + } + } + DTN_INFO_END(); } @@ -1301,7 +1366,7 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context) void dcn10_init_hw(struct dc *dc) { - int i, j; + int i; struct abm *abm = dc->res_pool->abm; struct dmcu *dmcu = dc->res_pool->dmcu; struct dce_hwseq *hws = dc->hwseq; @@ -1397,43 +1462,8 @@ void dcn10_init_hw(struct dc *dc) dmub_enable_outbox_notification(dc); /* we want to turn off all dp displays before doing detection */ - if (dc->config.power_down_display_on_boot) { - uint8_t dpcd_power_state = '\0'; - enum dc_status status = DC_ERROR_UNEXPECTED; - - for (i = 0; i < dc->link_count; i++) { - if (dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) - continue; - - /* DP 2.0 requires that LTTPR Caps be read first */ - dp_retrieve_lttpr_cap(dc->links[i]); - - /* - * If any of the displays are lit up turn them off. - * The reason is that some MST hubs cannot be turned off - * completely until we tell them to do so. - * If not turned off, then displays connected to MST hub - * won't light up. - */ - status = core_link_read_dpcd(dc->links[i], DP_SET_POWER, - &dpcd_power_state, sizeof(dpcd_power_state)); - if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) { - /* blank dp stream before power off receiver*/ - if (dc->links[i]->link_enc->funcs->get_dig_frontend) { - unsigned int fe = dc->links[i]->link_enc->funcs->get_dig_frontend(dc->links[i]->link_enc); - - for (j = 0; j < dc->res_pool->stream_enc_count; j++) { - if (fe == dc->res_pool->stream_enc[j]->id) { - dc->res_pool->stream_enc[j]->funcs->dp_blank( - dc->res_pool->stream_enc[j]); - break; - } - } - } - dp_receiver_power_ctrl(dc->links[i], false); - } - } - } + if (dc->config.power_down_display_on_boot) + blank_all_dp_displays(dc, true); /* If taking control over from VBIOS, we may want to optimize our first * mode set, so we need to skip powering down pipes until we know which @@ -1522,7 +1552,7 @@ void dcn10_power_down_on_boot(struct dc *dc) for (i = 0; i < dc->link_count; i++) { struct dc_link *link = dc->links[i]; - if (link->link_enc->funcs->is_dig_enabled && + if (link->link_enc && link->link_enc->funcs->is_dig_enabled && link->link_enc->funcs->is_dig_enabled(link->link_enc) && dc->hwss.power_down) { dc->hwss.power_down(dc); @@ -3176,13 +3206,11 @@ void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data) static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) { - struct pipe_ctx *test_pipe; + struct pipe_ctx *test_pipe, *split_pipe; const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data; - const struct rect *r1 = &scl_data->recout, *r2; - int r1_r = r1->x + r1->width, r1_b = r1->y + r1->height, r2_r, r2_b; + struct rect r1 = scl_data->recout, r2, r2_half; + int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b; int cur_layer = pipe_ctx->plane_state->layer_index; - bool upper_pipe_exists = false; - struct fixed31_32 one = dc_fixpt_from_int(1); /** * Disable the cursor if there's another pipe above this with a @@ -3191,26 +3219,33 @@ static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) */ for (test_pipe = pipe_ctx->top_pipe; test_pipe; test_pipe = test_pipe->top_pipe) { - if (!test_pipe->plane_state->visible) + // Skip invisible layer and pipe-split plane on same layer + if (!test_pipe->plane_state->visible || test_pipe->plane_state->layer_index == cur_layer) continue; - r2 = &test_pipe->plane_res.scl_data.recout; - r2_r = r2->x + r2->width; - r2_b = r2->y + r2->height; + r2 = test_pipe->plane_res.scl_data.recout; + r2_r = r2.x + r2.width; + r2_b = r2.y + r2.height; + split_pipe = test_pipe; - if (r1->x >= r2->x && r1->y >= r2->y && r1_r <= r2_r && r1_b <= r2_b) - return true; + /** + * There is another half plane on same layer because of + * pipe-split, merge together per same height. + */ + for (split_pipe = pipe_ctx->top_pipe; split_pipe; + split_pipe = split_pipe->top_pipe) + if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) { + r2_half = split_pipe->plane_res.scl_data.recout; + r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x; + r2.width = r2.width + r2_half.width; + r2_r = r2.x + r2.width; + break; + } - if (test_pipe->plane_state->layer_index < cur_layer) - upper_pipe_exists = true; + if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b) + return true; } - // if plane scaled, assume an upper plane can handle cursor if it exists. - if (upper_pipe_exists && - (scl_data->ratios.horz.value != one.value || - scl_data->ratios.vert.value != one.value)) - return true; - return false; } @@ -3613,7 +3648,7 @@ void dcn10_unblank_stream(struct pipe_ctx *pipe_ctx, if (dc_is_dp_signal(pipe_ctx->stream->signal)) { if (params.timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) params.timing.pix_clk_100hz /= 2; - pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); + pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, ¶ms); } if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { |