summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c75
1 files changed, 50 insertions, 25 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index c2092775ca88..a9b9490a532c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -302,29 +302,32 @@ static uint8_t dc_dmub_srv_get_pipes_for_stream(struct dc *dc, struct dc_stream_
return pipes;
}
-static int dc_dmub_srv_get_timing_generator_offset(struct dc *dc, struct dc_stream_state *stream)
+static void dc_dmub_srv_populate_fams_pipe_info(struct dc *dc, struct dc_state *context,
+ struct pipe_ctx *head_pipe,
+ struct dmub_cmd_fw_assisted_mclk_switch_pipe_data *fams_pipe_data)
{
- int tg_inst = 0;
- int i = 0;
+ int j;
+ int pipe_idx = 0;
- for (i = 0; i < MAX_PIPES; i++) {
- struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ fams_pipe_data->pipe_index[pipe_idx++] = head_pipe->plane_res.hubp->inst;
+ for (j = 0; j < dc->res_pool->pipe_count; j++) {
+ struct pipe_ctx *split_pipe = &context->res_ctx.pipe_ctx[j];
- if (pipe->stream == stream && pipe->stream_res.tg) {
- tg_inst = pipe->stream_res.tg->inst;
- break;
+ if (split_pipe->stream == head_pipe->stream && (split_pipe->top_pipe || split_pipe->prev_odm_pipe)) {
+ fams_pipe_data->pipe_index[pipe_idx++] = split_pipe->plane_res.hubp->inst;
}
}
- return tg_inst;
+ fams_pipe_data->pipe_count = pipe_idx;
}
bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, struct dc_state *context)
{
union dmub_rb_cmd cmd = { 0 };
struct dmub_cmd_fw_assisted_mclk_switch_config *config_data = &cmd.fw_assisted_mclk_switch.config_data;
- int i = 0;
+ int i = 0, k = 0;
int ramp_up_num_steps = 1; // TODO: Ramp is currently disabled. Reenable it.
uint8_t visual_confirm_enabled;
+ int pipe_idx = 0;
if (dc == NULL)
return false;
@@ -337,17 +340,40 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru
cmd.fw_assisted_mclk_switch.config_data.fams_enabled = should_manage_pstate;
cmd.fw_assisted_mclk_switch.config_data.visual_confirm_enabled = visual_confirm_enabled;
- for (i = 0; context && i < context->stream_count; i++) {
- struct dc_stream_state *stream = context->streams[i];
- uint8_t min_refresh_in_hz = (stream->timing.min_refresh_in_uhz + 999999) / 1000000;
- int tg_inst = dc_dmub_srv_get_timing_generator_offset(dc, stream);
+ if (should_manage_pstate) {
+ for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+ if (!pipe->stream)
+ continue;
- config_data->pipe_data[tg_inst].pix_clk_100hz = stream->timing.pix_clk_100hz;
- config_data->pipe_data[tg_inst].min_refresh_in_hz = min_refresh_in_hz;
- config_data->pipe_data[tg_inst].max_ramp_step = ramp_up_num_steps;
- config_data->pipe_data[tg_inst].pipes = dc_dmub_srv_get_pipes_for_stream(dc, stream);
+ /* If FAMS is being used to support P-State and there is a stream
+ * that does not use FAMS, we are in an FPO + VActive scenario.
+ * Assign vactive stretch margin in this case.
+ */
+ if (!pipe->stream->fpo_in_use) {
+ cmd.fw_assisted_mclk_switch.config_data.vactive_stretch_margin_us = dc->debug.fpo_vactive_margin_us;
+ break;
+ }
+ pipe_idx++;
+ }
}
+ for (i = 0, k = 0; context && i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+ if (!pipe->top_pipe && !pipe->prev_odm_pipe && pipe->stream && pipe->stream->fpo_in_use) {
+ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+ uint8_t min_refresh_in_hz = (pipe->stream->timing.min_refresh_in_uhz + 999999) / 1000000;
+
+ config_data->pipe_data[k].pix_clk_100hz = pipe->stream->timing.pix_clk_100hz;
+ config_data->pipe_data[k].min_refresh_in_hz = min_refresh_in_hz;
+ config_data->pipe_data[k].max_ramp_step = ramp_up_num_steps;
+ config_data->pipe_data[k].pipes = dc_dmub_srv_get_pipes_for_stream(dc, pipe->stream);
+ dc_dmub_srv_populate_fams_pipe_info(dc, context, pipe, &config_data->pipe_data[k]);
+ k++;
+ }
+ }
cmd.fw_assisted_mclk_switch.header.payload_bytes =
sizeof(cmd.fw_assisted_mclk_switch) - sizeof(cmd.fw_assisted_mclk_switch.header);
@@ -421,7 +447,6 @@ void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pi
}
}
-#ifdef CONFIG_DRM_AMD_DC_DCN
/**
* populate_subvp_cmd_drr_info - Helper to populate DRR pipe info for the DMCUB subvp command
*
@@ -638,7 +663,7 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
pipe_data->pipe_config.subvp_data.main_vblank_end =
main_timing->v_total - main_timing->v_front_porch - main_timing->v_addressable;
pipe_data->pipe_config.subvp_data.mall_region_lines = phantom_timing->v_addressable;
- pipe_data->pipe_config.subvp_data.main_pipe_index = subvp_pipe->pipe_idx;
+ pipe_data->pipe_config.subvp_data.main_pipe_index = subvp_pipe->stream_res.tg->inst;
pipe_data->pipe_config.subvp_data.is_drr = subvp_pipe->stream->ignore_msa_timing_param;
/* Calculate the scaling factor from the src and dst height.
@@ -680,11 +705,11 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
struct pipe_ctx *phantom_pipe = &context->res_ctx.pipe_ctx[j];
if (phantom_pipe->stream == subvp_pipe->stream->mall_stream_config.paired_stream) {
- pipe_data->pipe_config.subvp_data.phantom_pipe_index = phantom_pipe->pipe_idx;
+ pipe_data->pipe_config.subvp_data.phantom_pipe_index = phantom_pipe->stream_res.tg->inst;
if (phantom_pipe->bottom_pipe) {
- pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->bottom_pipe->pipe_idx;
+ pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->bottom_pipe->plane_res.hubp->inst;
} else if (phantom_pipe->next_odm_pipe) {
- pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->next_odm_pipe->pipe_idx;
+ pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = phantom_pipe->next_odm_pipe->plane_res.hubp->inst;
} else {
pipe_data->pipe_config.subvp_data.phantom_split_pipe_index = 0;
}
@@ -750,7 +775,8 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
!pipe->top_pipe && !pipe->prev_odm_pipe &&
pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
populate_subvp_cmd_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++);
- } else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE) {
+ } else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE &&
+ !pipe->top_pipe && !pipe->prev_odm_pipe) {
// Don't need to check for ActiveDRAMClockChangeMargin < 0, not valid in cases where
// we run through DML without calculating "natural" P-state support
populate_subvp_cmd_vblank_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++);
@@ -775,7 +801,6 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
}
-#endif
bool dc_dmub_srv_get_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv, struct dmub_diagnostic_data *diag_data)
{