mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 14:04:27 -04:00
drm/amd/display: Remove sink usage from DPMS
[Why] stream->sink is optional and can be null, so should always be checked before dereference. Additionally, most of its usage in DPMS sequences is for stream->sink->link, which can be replaced with stream->link, as the two should always be the same. [How] * Replace stream->sink->link in DPMS on/off * Add assert to USB4 BW allocation where sink is required * Avoid inconsistencies in resource access, e.g. don't repeat stream->link after it was already saved to a local variable * Pull out effective VPG calculation to helper getter * Formatting fixes Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Signed-off-by: Dominik Kaszewski <dominik.kaszewski@amd.com> Signed-off-by: George Zhang <george.zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
2a58107823
commit
8fa813b7fd
@@ -2296,6 +2296,8 @@ static enum dc_status enable_link(
|
||||
|
||||
static bool allocate_usb4_bandwidth_for_stream(struct dc_stream_state *stream, int stream_bw)
|
||||
{
|
||||
ASSERT(stream->sink);
|
||||
|
||||
struct dc_link *link = stream->sink->link;
|
||||
int req_bw = stream_bw;
|
||||
|
||||
@@ -2342,6 +2344,8 @@ static bool allocate_usb4_bandwidth_for_stream(struct dc_stream_state *stream, i
|
||||
|
||||
static bool allocate_usb4_bandwidth(struct dc_stream_state *stream)
|
||||
{
|
||||
ASSERT(stream->sink);
|
||||
|
||||
bool ret;
|
||||
|
||||
int bw = dc_bandwidth_in_kbps_from_timing(&stream->timing,
|
||||
@@ -2361,38 +2365,43 @@ static bool deallocate_usb4_bandwidth(struct dc_stream_state *stream)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct vpg *get_vpg(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal))
|
||||
return pipe_ctx->stream_res.hpo_frl_stream_enc->vpg;
|
||||
else if (dp_is_128b_132b_signal(pipe_ctx))
|
||||
return pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
|
||||
else
|
||||
return pipe_ctx->stream_res.stream_enc->vpg;
|
||||
}
|
||||
|
||||
void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct dc_link *link = stream->sink->link;
|
||||
struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
|
||||
enum dp_panel_mode panel_mode_dp = dp_get_panel_mode(link);
|
||||
|
||||
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct dc *dc = stream->ctx->dc;
|
||||
struct dc_link *link = stream->link;
|
||||
struct vpg *vpg = get_vpg(pipe_ctx);
|
||||
enum dp_panel_mode panel_mode_dp = dp_get_panel_mode(link);
|
||||
|
||||
ASSERT(is_master_pipe_for_link(link, pipe_ctx));
|
||||
|
||||
if (dp_is_128b_132b_signal(pipe_ctx))
|
||||
vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
|
||||
if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal))
|
||||
vpg = pipe_ctx->stream_res.hpo_frl_stream_enc->vpg;
|
||||
if (dc_is_virtual_signal(pipe_ctx->stream->signal))
|
||||
if (dc_is_virtual_signal(stream->signal))
|
||||
return;
|
||||
|
||||
if (pipe_ctx->stream->sink) {
|
||||
if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
|
||||
pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
|
||||
if (stream->sink) {
|
||||
if (stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
|
||||
stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
|
||||
DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x link=%d sink_count=%d\n", __func__,
|
||||
pipe_ctx->stream->sink->edid_caps.display_name,
|
||||
pipe_ctx->stream->signal, link->link_index, link->sink_count);
|
||||
stream->sink->edid_caps.display_name,
|
||||
stream->signal, link->link_index, link->sink_count);
|
||||
}
|
||||
}
|
||||
|
||||
link_wait_for_unlocked(link);
|
||||
|
||||
if (!pipe_ctx->stream->sink->edid_caps.panel_patch.skip_avmute) {
|
||||
if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
|
||||
if (stream->sink && !stream->sink->edid_caps.panel_patch.skip_avmute) {
|
||||
if (dc_is_hdmi_signal(stream->signal))
|
||||
set_avmute(pipe_ctx, true);
|
||||
}
|
||||
|
||||
@@ -2402,15 +2411,15 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
|
||||
dc->hwss.blank_stream(pipe_ctx);
|
||||
|
||||
if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation)
|
||||
deallocate_usb4_bandwidth(pipe_ctx->stream);
|
||||
deallocate_usb4_bandwidth(stream);
|
||||
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
deallocate_mst_payload(pipe_ctx);
|
||||
else if (dc_is_dp_sst_signal(pipe_ctx->stream->signal) &&
|
||||
else if (dc_is_dp_sst_signal(stream->signal) &&
|
||||
dp_is_128b_132b_signal(pipe_ctx))
|
||||
update_sst_payload(pipe_ctx, false);
|
||||
|
||||
if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
|
||||
if (dc_is_hdmi_signal(stream->signal)) {
|
||||
struct ext_hdmi_settings settings = {0};
|
||||
enum engine_id eng_id = pipe_ctx->stream_res.stream_enc->id;
|
||||
|
||||
@@ -2433,7 +2442,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
|
||||
}
|
||||
}
|
||||
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
|
||||
if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
|
||||
!dp_is_128b_132b_signal(pipe_ctx)) {
|
||||
|
||||
/* In DP1.x SST mode, our encoder will go to TPS1
|
||||
@@ -2443,18 +2452,18 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
|
||||
* state machine.
|
||||
* In DP2 or MST mode, our encoder will stay video active
|
||||
*/
|
||||
disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
|
||||
disable_link(link, &pipe_ctx->link_res, stream->signal);
|
||||
dc->hwss.disable_stream(pipe_ctx);
|
||||
} else {
|
||||
dc->hwss.disable_stream(pipe_ctx);
|
||||
disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
|
||||
disable_link(link, &pipe_ctx->link_res, stream->signal);
|
||||
}
|
||||
edp_set_panel_assr(link, pipe_ctx, &panel_mode_dp, false);
|
||||
|
||||
if (pipe_ctx->stream->timing.flags.DSC) {
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
if (stream->timing.flags.DSC) {
|
||||
if (dc_is_dp_signal(stream->signal))
|
||||
link_set_dsc_enable(pipe_ctx, false);
|
||||
else if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal))
|
||||
else if (dc_is_hdmi_frl_signal(stream->signal))
|
||||
link_set_dsc_on_stream(pipe_ctx, false);
|
||||
}
|
||||
if (dp_is_128b_132b_signal(pipe_ctx)) {
|
||||
@@ -2468,7 +2477,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
|
||||
/* for psp not exist case */
|
||||
if (link->connector_signal == SIGNAL_TYPE_EDP && dc->debug.psp_disabled_wa) {
|
||||
/* reset internal save state to default since eDP is off */
|
||||
enum dp_panel_mode panel_mode = dp_get_panel_mode(pipe_ctx->stream->link);
|
||||
enum dp_panel_mode panel_mode = dp_get_panel_mode(link);
|
||||
/* since current psp not loaded, we need to reset it to default */
|
||||
link->panel_mode = panel_mode;
|
||||
}
|
||||
@@ -2478,62 +2487,57 @@ void link_set_dpms_on(
|
||||
struct dc_state *state,
|
||||
struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct dc_link *link = stream->sink->link;
|
||||
struct dc *dc = stream->ctx->dc;
|
||||
struct dc_link *link = stream->link;
|
||||
enum dc_status status;
|
||||
struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc;
|
||||
enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO;
|
||||
struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
|
||||
struct vpg *vpg = get_vpg(pipe_ctx);
|
||||
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
|
||||
bool apply_edp_fast_boot_optimization =
|
||||
pipe_ctx->stream->apply_edp_fast_boot_optimization;
|
||||
|
||||
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
|
||||
stream->apply_edp_fast_boot_optimization;
|
||||
|
||||
ASSERT(is_master_pipe_for_link(link, pipe_ctx));
|
||||
|
||||
if (dp_is_128b_132b_signal(pipe_ctx))
|
||||
vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
|
||||
if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal))
|
||||
vpg = pipe_ctx->stream_res.hpo_frl_stream_enc->vpg;
|
||||
if (dc_is_virtual_signal(pipe_ctx->stream->signal))
|
||||
if (dc_is_virtual_signal(stream->signal))
|
||||
return;
|
||||
|
||||
if (pipe_ctx->stream->sink) {
|
||||
if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
|
||||
pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
|
||||
if (stream->sink) {
|
||||
if (stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
|
||||
stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
|
||||
DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x link=%d sink_count=%d\n", __func__,
|
||||
pipe_ctx->stream->sink->edid_caps.display_name,
|
||||
pipe_ctx->stream->signal,
|
||||
stream->sink->edid_caps.display_name,
|
||||
stream->signal,
|
||||
link->link_index,
|
||||
link->sink_count);
|
||||
}
|
||||
}
|
||||
|
||||
link_wait_for_unlocked(stream->link);
|
||||
link_wait_for_unlocked(link);
|
||||
if (!dc->config.unify_link_enc_assignment)
|
||||
link_enc = link_enc_cfg_get_link_enc(link);
|
||||
ASSERT(link_enc);
|
||||
|
||||
if (!dc_is_virtual_signal(pipe_ctx->stream->signal)
|
||||
&& !dc_is_hdmi_frl_signal(pipe_ctx->stream->signal)
|
||||
if (!dc_is_virtual_signal(stream->signal)
|
||||
&& !dc_is_hdmi_frl_signal(stream->signal)
|
||||
&& !dp_is_128b_132b_signal(pipe_ctx)) {
|
||||
if (link_enc)
|
||||
link_enc->funcs->setup(
|
||||
link_enc,
|
||||
pipe_ctx->stream->signal);
|
||||
stream->signal);
|
||||
}
|
||||
|
||||
pipe_ctx->stream->link->link_state_valid = true;
|
||||
link->link_state_valid = true;
|
||||
|
||||
if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal))
|
||||
hdmi_frl_decide_link_settings(stream, &stream->link->frl_link_settings, &pipe_ctx->dsc_padding_params);
|
||||
if (dc_is_hdmi_frl_signal(stream->signal))
|
||||
hdmi_frl_decide_link_settings(stream, &link->frl_link_settings, &pipe_ctx->dsc_padding_params);
|
||||
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_out_mux) {
|
||||
if (dp_is_128b_132b_signal(pipe_ctx))
|
||||
otg_out_dest = OUT_MUX_HPO_DP;
|
||||
else if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal))
|
||||
else if (dc_is_hdmi_frl_signal(stream->signal))
|
||||
otg_out_dest = OUT_MUX_HPO_FRL;
|
||||
else
|
||||
otg_out_dest = OUT_MUX_DIO;
|
||||
@@ -2542,7 +2546,7 @@ void link_set_dpms_on(
|
||||
|
||||
link_hwss->setup_stream_attribute(pipe_ctx);
|
||||
|
||||
pipe_ctx->stream->apply_edp_fast_boot_optimization = false;
|
||||
stream->apply_edp_fast_boot_optimization = false;
|
||||
|
||||
// Enable VPG before building infoframe
|
||||
if (vpg && vpg->funcs->vpg_poweron)
|
||||
@@ -2551,15 +2555,15 @@ void link_set_dpms_on(
|
||||
resource_build_info_frame(pipe_ctx);
|
||||
dc->hwss.update_info_frame(pipe_ctx);
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
if (dc_is_dp_signal(stream->signal))
|
||||
dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
|
||||
|
||||
/* Do not touch link on seamless boot optimization. */
|
||||
if (pipe_ctx->stream->apply_seamless_boot_optimization) {
|
||||
pipe_ctx->stream->dpms_off = false;
|
||||
if (stream->apply_seamless_boot_optimization) {
|
||||
stream->dpms_off = false;
|
||||
|
||||
/* Still enable stream features & audio on seamless boot for DP external displays */
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
enable_stream_features(pipe_ctx);
|
||||
dc->hwss.enable_audio_stream(pipe_ctx);
|
||||
}
|
||||
@@ -2569,11 +2573,11 @@ void link_set_dpms_on(
|
||||
}
|
||||
|
||||
/* eDP lit up by bios already, no need to enable again. */
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
|
||||
if (stream->signal == SIGNAL_TYPE_EDP &&
|
||||
apply_edp_fast_boot_optimization &&
|
||||
!pipe_ctx->stream->timing.flags.DSC &&
|
||||
!stream->timing.flags.DSC &&
|
||||
!pipe_ctx->next_odm_pipe) {
|
||||
pipe_ctx->stream->dpms_off = false;
|
||||
stream->dpms_off = false;
|
||||
update_psp_stream_config(pipe_ctx, false);
|
||||
|
||||
if (link->is_dds) {
|
||||
@@ -2586,7 +2590,7 @@ void link_set_dpms_on(
|
||||
return;
|
||||
}
|
||||
|
||||
if (pipe_ctx->stream->dpms_off)
|
||||
if (stream->dpms_off)
|
||||
return;
|
||||
|
||||
/* For Dp tunneling link, a pending HPD means that we have a race condition between processing
|
||||
@@ -2604,9 +2608,9 @@ void link_set_dpms_on(
|
||||
* will be automatically set at a later time when the video is enabled
|
||||
* (DP_VID_STREAM_EN = 1).
|
||||
*/
|
||||
if (pipe_ctx->stream->timing.flags.DSC) {
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
|
||||
dc_is_virtual_signal(pipe_ctx->stream->signal))
|
||||
if (stream->timing.flags.DSC) {
|
||||
if (dc_is_dp_signal(stream->signal) ||
|
||||
dc_is_virtual_signal(stream->signal))
|
||||
link_set_dsc_enable(pipe_ctx, true);
|
||||
}
|
||||
|
||||
@@ -2617,7 +2621,7 @@ void link_set_dpms_on(
|
||||
|
||||
if (status != DC_OK) {
|
||||
DC_LOG_WARNING("enabling link %u failed: %d\n",
|
||||
pipe_ctx->stream->link->link_index,
|
||||
link->link_index,
|
||||
status);
|
||||
|
||||
/* Abort stream enable *unless* the failure was due to
|
||||
@@ -2627,19 +2631,18 @@ void link_set_dpms_on(
|
||||
*/
|
||||
if ((status != DC_FAIL_DP_LINK_TRAINING &&
|
||||
status != DC_FAIL_HDMI_FRL_LINK_TRAINING) ||
|
||||
pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
|
||||
if (false == stream->link->link_status.link_active)
|
||||
disable_link(stream->link, &pipe_ctx->link_res,
|
||||
pipe_ctx->stream->signal);
|
||||
stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
|
||||
if (false == link->link_status.link_active)
|
||||
disable_link(link, &pipe_ctx->link_res,
|
||||
stream->signal);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pipe_ctx->stream->timing.flags.DSC &&
|
||||
dc_is_hdmi_frl_signal(pipe_ctx->stream->signal))
|
||||
//TODO: bring HDMI FRL in line with DP
|
||||
link_set_dsc_on_stream(pipe_ctx, true);
|
||||
if (stream->timing.flags.DSC && dc_is_hdmi_frl_signal(stream->signal))
|
||||
//TODO: bring HDMI FRL in line with DP
|
||||
link_set_dsc_on_stream(pipe_ctx, true);
|
||||
|
||||
/* turn off otg test pattern if enable */
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
|
||||
@@ -2651,37 +2654,37 @@ void link_set_dpms_on(
|
||||
* as a workaround for the incorrect value being applied
|
||||
* from transmitter control.
|
||||
*/
|
||||
if (!(dc_is_virtual_signal(pipe_ctx->stream->signal) ||
|
||||
dc_is_hdmi_frl_signal(pipe_ctx->stream->signal) ||
|
||||
if (!(dc_is_virtual_signal(stream->signal) ||
|
||||
dc_is_hdmi_frl_signal(stream->signal) ||
|
||||
dp_is_128b_132b_signal(pipe_ctx))) {
|
||||
|
||||
if (link_enc)
|
||||
link_enc->funcs->setup(
|
||||
link_enc,
|
||||
pipe_ctx->stream->signal);
|
||||
stream->signal);
|
||||
|
||||
}
|
||||
|
||||
dc->hwss.enable_stream(pipe_ctx);
|
||||
|
||||
/* Set DPS PPS SDP (AKA "info frames") */
|
||||
if (pipe_ctx->stream->timing.flags.DSC) {
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
|
||||
dc_is_virtual_signal(pipe_ctx->stream->signal)) {
|
||||
if (stream->timing.flags.DSC) {
|
||||
if (dc_is_dp_signal(stream->signal) ||
|
||||
dc_is_virtual_signal(stream->signal)) {
|
||||
dp_set_dsc_on_rx(pipe_ctx, true);
|
||||
link_set_dsc_pps_packet(pipe_ctx, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
if (dc_is_dp_signal(stream->signal))
|
||||
dp_set_hblank_reduction_on_rx(pipe_ctx);
|
||||
|
||||
if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation)
|
||||
allocate_usb4_bandwidth(pipe_ctx->stream);
|
||||
allocate_usb4_bandwidth(stream);
|
||||
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
allocate_mst_payload(pipe_ctx);
|
||||
else if (dc_is_dp_sst_signal(pipe_ctx->stream->signal) &&
|
||||
else if (dc_is_dp_sst_signal(stream->signal) &&
|
||||
dp_is_128b_132b_signal(pipe_ctx))
|
||||
update_sst_payload(pipe_ctx, true);
|
||||
|
||||
@@ -2690,23 +2693,22 @@ void link_set_dpms_on(
|
||||
* training and stream unblank resolves the corruption issue.
|
||||
* This is workaround.
|
||||
*/
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
|
||||
if (stream->signal == SIGNAL_TYPE_EDP &&
|
||||
link->is_display_mux_present)
|
||||
msleep(20);
|
||||
|
||||
dc->hwss.unblank_stream(pipe_ctx,
|
||||
&pipe_ctx->stream->link->cur_link_settings);
|
||||
&link->cur_link_settings);
|
||||
|
||||
if (stream->sink_patches.delay_ignore_msa > 0)
|
||||
msleep(stream->sink_patches.delay_ignore_msa);
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
if (dc_is_dp_signal(stream->signal))
|
||||
enable_stream_features(pipe_ctx);
|
||||
update_psp_stream_config(pipe_ctx, false);
|
||||
|
||||
dc->hwss.enable_audio_stream(pipe_ctx);
|
||||
|
||||
if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
|
||||
if (dc_is_hdmi_signal(stream->signal))
|
||||
set_avmute(pipe_ctx, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user