diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc.c | 193 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_debug.c | 120 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 78 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 304 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 31 |
8 files changed, 497 insertions, 274 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index f84e795e35f5..28d1353f403d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -276,6 +276,7 @@ static bool create_links( link->link_id.type = OBJECT_TYPE_CONNECTOR; link->link_id.id = CONNECTOR_ID_VIRTUAL; link->link_id.enum_id = ENUM_ID_1; + link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; link->link_enc = kzalloc(sizeof(*link->link_enc), GFP_KERNEL); if (!link->link_enc) { @@ -452,6 +453,7 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc, if (dc->caps.max_v_total != 0 && (adjust->v_total_max > dc->caps.max_v_total || adjust->v_total_min > dc->caps.max_v_total)) { + stream->adjust.timing_adjust_pending = false; if (adjust->allow_otg_v_count_halt) return set_long_vtotal(dc, stream, adjust); else @@ -465,7 +467,7 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc, dc->hwss.set_drr(&pipe, 1, *adjust); - + stream->adjust.timing_adjust_pending = false; return true; } } @@ -515,33 +517,6 @@ bool dc_stream_get_last_used_drr_vtotal(struct dc *dc, return status; } -bool dc_stream_get_crtc_position(struct dc *dc, - struct dc_stream_state **streams, int num_streams, - unsigned int *v_pos, unsigned int *nom_v_pos) -{ - /* TODO: Support multiple streams */ - const struct dc_stream_state *stream = streams[0]; - int i; - bool ret = false; - struct crtc_position position; - - dc_exit_ips_for_hw_access(dc); - - for (i = 0; i < MAX_PIPES; i++) { - struct pipe_ctx *pipe = - &dc->current_state->res_ctx.pipe_ctx[i]; - - if (pipe->stream == stream && pipe->stream_res.stream_enc) { - dc->hwss.get_position(&pipe, 1, &position); - - *v_pos = position.vertical_count; - *nom_v_pos = position.nominal_vcount; - ret = true; - } - } - return ret; -} - #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) static inline void dc_stream_forward_dmub_crc_window(struct dc_dmub_srv *dmub_srv, @@ -931,7 +906,8 @@ void dc_stream_set_static_screen_params(struct dc *dc, static void dc_destruct(struct dc *dc) { // reset link encoder assignment table on destruct - if (dc->res_pool && dc->res_pool->funcs->link_encs_assign) + if (dc->res_pool && dc->res_pool->funcs->link_encs_assign && + !dc->config.unify_link_enc_assignment) link_enc_cfg_init(dc, dc->current_state); if (dc->current_state) { @@ -1227,6 +1203,8 @@ static void dc_update_visual_confirm_color(struct dc *dc, struct dc_state *conte get_surface_tile_visual_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color)); else if (dc->debug.visual_confirm == VISUAL_CONFIRM_HW_CURSOR) get_cursor_visual_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color)); + else if (dc->debug.visual_confirm == VISUAL_CONFIRM_DCC) + get_dcc_visual_confirm_color(dc, pipe_ctx, &(pipe_ctx->visual_confirm_color)); else { if (dc->ctx->dce_version < DCN_VERSION_2_0) color_space_to_black_color( @@ -1720,17 +1698,23 @@ bool dc_validate_boot_timing(const struct dc *dc, return false; } - if (dc->debug.force_odm_combine) + if (dc->debug.force_odm_combine) { + DC_LOG_DEBUG("boot timing validation failed due to force_odm_combine\n"); return false; + } /* Check for enabled DIG to identify enabled display */ - if (!link->link_enc->funcs->is_dig_enabled(link->link_enc)) + if (!link->link_enc->funcs->is_dig_enabled(link->link_enc)) { + DC_LOG_DEBUG("boot timing validation failed due to disabled DIG\n"); return false; + } enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc); - if (enc_inst == ENGINE_ID_UNKNOWN) + if (enc_inst == ENGINE_ID_UNKNOWN) { + DC_LOG_DEBUG("boot timing validation failed due to unknown DIG engine ID\n"); return false; + } for (i = 0; i < dc->res_pool->stream_enc_count; i++) { if (dc->res_pool->stream_enc[i]->id == enc_inst) { @@ -1744,62 +1728,98 @@ bool dc_validate_boot_timing(const struct dc *dc, } // tg_inst not found - if (i == dc->res_pool->stream_enc_count) + if (i == dc->res_pool->stream_enc_count) { + DC_LOG_DEBUG("boot timing validation failed due to timing generator instance not found\n"); return false; + } - if (tg_inst >= dc->res_pool->timing_generator_count) + if (tg_inst >= dc->res_pool->timing_generator_count) { + DC_LOG_DEBUG("boot timing validation failed due to invalid timing generator count\n"); return false; + } - if (tg_inst != link->link_enc->preferred_engine) + if (tg_inst != link->link_enc->preferred_engine) { + DC_LOG_DEBUG("boot timing validation failed due to non-preferred timing generator\n"); return false; + } tg = dc->res_pool->timing_generators[tg_inst]; - if (!tg->funcs->get_hw_timing) + if (!tg->funcs->get_hw_timing) { + DC_LOG_DEBUG("boot timing validation failed due to missing get_hw_timing callback\n"); return false; + } - if (!tg->funcs->get_hw_timing(tg, &hw_crtc_timing)) + if (!tg->funcs->get_hw_timing(tg, &hw_crtc_timing)) { + DC_LOG_DEBUG("boot timing validation failed due to failed get_hw_timing return\n"); return false; + } - if (crtc_timing->h_total != hw_crtc_timing.h_total) + if (crtc_timing->h_total != hw_crtc_timing.h_total) { + DC_LOG_DEBUG("boot timing validation failed due to h_total mismatch\n"); return false; + } - if (crtc_timing->h_border_left != hw_crtc_timing.h_border_left) + if (crtc_timing->h_border_left != hw_crtc_timing.h_border_left) { + DC_LOG_DEBUG("boot timing validation failed due to h_border_left mismatch\n"); return false; + } - if (crtc_timing->h_addressable != hw_crtc_timing.h_addressable) + if (crtc_timing->h_addressable != hw_crtc_timing.h_addressable) { + DC_LOG_DEBUG("boot timing validation failed due to h_addressable mismatch\n"); return false; + } - if (crtc_timing->h_border_right != hw_crtc_timing.h_border_right) + if (crtc_timing->h_border_right != hw_crtc_timing.h_border_right) { + DC_LOG_DEBUG("boot timing validation failed due to h_border_right mismatch\n"); return false; + } - if (crtc_timing->h_front_porch != hw_crtc_timing.h_front_porch) + if (crtc_timing->h_front_porch != hw_crtc_timing.h_front_porch) { + DC_LOG_DEBUG("boot timing validation failed due to h_front_porch mismatch\n"); return false; + } - if (crtc_timing->h_sync_width != hw_crtc_timing.h_sync_width) + if (crtc_timing->h_sync_width != hw_crtc_timing.h_sync_width) { + DC_LOG_DEBUG("boot timing validation failed due to h_sync_width mismatch\n"); return false; + } - if (crtc_timing->v_total != hw_crtc_timing.v_total) + if (crtc_timing->v_total != hw_crtc_timing.v_total) { + DC_LOG_DEBUG("boot timing validation failed due to v_total mismatch\n"); return false; + } - if (crtc_timing->v_border_top != hw_crtc_timing.v_border_top) + if (crtc_timing->v_border_top != hw_crtc_timing.v_border_top) { + DC_LOG_DEBUG("boot timing validation failed due to v_border_top mismatch\n"); return false; + } - if (crtc_timing->v_addressable != hw_crtc_timing.v_addressable) + if (crtc_timing->v_addressable != hw_crtc_timing.v_addressable) { + DC_LOG_DEBUG("boot timing validation failed due to v_addressable mismatch\n"); return false; + } - if (crtc_timing->v_border_bottom != hw_crtc_timing.v_border_bottom) + if (crtc_timing->v_border_bottom != hw_crtc_timing.v_border_bottom) { + DC_LOG_DEBUG("boot timing validation failed due to v_border_bottom mismatch\n"); return false; + } - if (crtc_timing->v_front_porch != hw_crtc_timing.v_front_porch) + if (crtc_timing->v_front_porch != hw_crtc_timing.v_front_porch) { + DC_LOG_DEBUG("boot timing validation failed due to v_front_porch mismatch\n"); return false; + } - if (crtc_timing->v_sync_width != hw_crtc_timing.v_sync_width) + if (crtc_timing->v_sync_width != hw_crtc_timing.v_sync_width) { + DC_LOG_DEBUG("boot timing validation failed due to v_sync_width mismatch\n"); return false; + } /* block DSC for now, as VBIOS does not currently support DSC timings */ - if (crtc_timing->flags.DSC) + if (crtc_timing->flags.DSC) { + DC_LOG_DEBUG("boot timing validation failed due to DSC\n"); return false; + } if (dc_is_dp_signal(link->connector_signal)) { unsigned int pix_clk_100hz = 0; @@ -1821,39 +1841,55 @@ bool dc_validate_boot_timing(const struct dc *dc, } else if (se && se->funcs->get_pixels_per_cycle) { uint32_t pixels_per_cycle = se->funcs->get_pixels_per_cycle(se); - if (pixels_per_cycle != 1 && !dc->debug.enable_dp_dig_pixel_rate_div_policy) + if (pixels_per_cycle != 1 && !dc->debug.enable_dp_dig_pixel_rate_div_policy) { + DC_LOG_DEBUG("boot timing validation failed due to pixels_per_cycle\n"); return false; + } pix_clk_100hz *= pixels_per_cycle; } // Note: In rare cases, HW pixclk may differ from crtc's pixclk // slightly due to rounding issues in 10 kHz units. - if (crtc_timing->pix_clk_100hz != pix_clk_100hz) + if (crtc_timing->pix_clk_100hz != pix_clk_100hz) { + DC_LOG_DEBUG("boot timing validation failed due to pix_clk_100hz mismatch\n"); return false; + } - if (!se || !se->funcs->dp_get_pixel_format) + if (!se || !se->funcs->dp_get_pixel_format) { + DC_LOG_DEBUG("boot timing validation failed due to missing dp_get_pixel_format\n"); return false; + } if (!se->funcs->dp_get_pixel_format( se, &hw_crtc_timing.pixel_encoding, - &hw_crtc_timing.display_color_depth)) + &hw_crtc_timing.display_color_depth)) { + DC_LOG_DEBUG("boot timing validation failed due to dp_get_pixel_format failure\n"); return false; + } - if (hw_crtc_timing.display_color_depth != crtc_timing->display_color_depth) + if (hw_crtc_timing.display_color_depth != crtc_timing->display_color_depth) { + DC_LOG_DEBUG("boot timing validation failed due to display_color_depth mismatch\n"); return false; + } - if (hw_crtc_timing.pixel_encoding != crtc_timing->pixel_encoding) + if (hw_crtc_timing.pixel_encoding != crtc_timing->pixel_encoding) { + DC_LOG_DEBUG("boot timing validation failed due to pixel_encoding mismatch\n"); return false; + } } + if (link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED) { + DC_LOG_DEBUG("boot timing validation failed due to VSC SDP colorimetry\n"); return false; } - if (link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) + if (link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) { + DC_LOG_DEBUG("boot timing validation failed due to DP 128b/132b\n"); return false; + } if (dc->link_srv->edp_is_ilr_optimization_required(link, crtc_timing)) { DC_LOG_EVENT_LINK_TRAINING("Seamless boot disabled to optimize eDP link rate\n"); @@ -2266,7 +2302,7 @@ enum dc_status dc_commit_streams(struct dc *dc, struct dc_commit_streams_params /* * Only update link encoder to stream assignment after bandwidth validation passed. */ - if (res == DC_OK && dc->res_pool->funcs->link_encs_assign) + if (res == DC_OK && dc->res_pool->funcs->link_encs_assign && !dc->config.unify_link_enc_assignment) dc->res_pool->funcs->link_encs_assign( dc, context, context->streams, context->stream_count); @@ -2834,10 +2870,13 @@ static enum surface_update_type check_update_surfaces_for_stream( if (stream_update->sharpening_required) su_flags->bits.sharpening_required = 1; + if (stream_update->output_color_space) + su_flags->bits.out_csc = 1; + if (su_flags->raw != 0) overall_type = UPDATE_TYPE_FULL; - if (stream_update->output_csc_transform || stream_update->output_color_space) + if (stream_update->output_csc_transform) su_flags->bits.out_csc = 1; /* Output transfer function changes do not require bandwidth recalculation, @@ -3127,8 +3166,13 @@ static void copy_stream_update_to_stream(struct dc *dc, if (update->vrr_active_fixed) stream->vrr_active_fixed = *update->vrr_active_fixed; - if (update->crtc_timing_adjust) + if (update->crtc_timing_adjust) { + if (stream->adjust.v_total_min != update->crtc_timing_adjust->v_total_min || + stream->adjust.v_total_max != update->crtc_timing_adjust->v_total_max) + update->crtc_timing_adjust->timing_adjust_pending = true; stream->adjust = *update->crtc_timing_adjust; + update->crtc_timing_adjust->timing_adjust_pending = false; + } if (update->dpms_off) stream->dpms_off = *update->dpms_off; @@ -3920,6 +3964,9 @@ static void commit_planes_for_stream(struct dc *dc, if (update_type == UPDATE_TYPE_FULL && dc->optimized_required) hwss_process_outstanding_hw_updates(dc, dc->current_state); + if (update_type != UPDATE_TYPE_FAST && dc->res_pool->funcs->prepare_mcache_programming) + dc->res_pool->funcs->prepare_mcache_programming(dc, context); + for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; @@ -3978,9 +4025,6 @@ static void commit_planes_for_stream(struct dc *dc, odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU; } - if (update_type != UPDATE_TYPE_FAST && dc->res_pool->funcs->prepare_mcache_programming) - dc->res_pool->funcs->prepare_mcache_programming(dc, context); - if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) if (top_pipe_to_program && top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { @@ -4902,7 +4946,8 @@ static bool full_update_required(struct dc *dc, stream_update->lut3d_func || stream_update->pending_test_pattern || stream_update->crtc_timing_adjust || - stream_update->scaler_sharpener_update)) + stream_update->scaler_sharpener_update || + stream_update->hw_cursor_req)) return true; if (stream) { @@ -5414,18 +5459,6 @@ bool dc_is_dmcu_initialized(struct dc *dc) return false; } -void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info) -{ - info->displayClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz; - info->engineClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_khz; - info->memoryClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dramclk_khz; - info->maxSupportedDppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz; - info->dppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dppclk_khz; - info->socClock = (unsigned int)state->bw_ctx.bw.dcn.clk.socclk_khz; - info->dcfClockDeepSleep = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz; - info->fClock = (unsigned int)state->bw_ctx.bw.dcn.clk.fclk_khz; - info->phyClock = (unsigned int)state->bw_ctx.bw.dcn.clk.phyclk_khz; -} enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping) { if (dc->hwss.set_clock) @@ -5549,9 +5582,11 @@ void dc_allow_idle_optimizations_internal(struct dc *dc, bool allow, char const if (dc->clk_mgr != NULL && dc->clk_mgr->funcs->get_hard_min_memclk) idle_dramclk_khz = dc->clk_mgr->funcs->get_hard_min_memclk(dc->clk_mgr); - for (i = 0; i < dc->res_pool->pipe_count; i++) { - pipe = &context->res_ctx.pipe_ctx[i]; - subvp_pipe_type[i] = dc_state_get_pipe_subvp_type(context, pipe); + if (dc->res_pool && context) { + for (i = 0; i < dc->res_pool->pipe_count; i++) { + pipe = &context->res_ctx.pipe_ctx[i]; + subvp_pipe_type[i] = dc_state_get_pipe_subvp_type(context, pipe); + } } DC_LOG_DC("%s: allow_idle=%d\n HardMinUClk_Khz=%d HardMinDramclk_Khz=%d\n Pipe_0=%d Pipe_1=%d Pipe_2=%d Pipe_3=%d Pipe_4=%d Pipe_5=%d (caller=%s)\n", diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c index af1ea5792560..650e89825968 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c @@ -51,126 +51,6 @@ DC_LOG_BANDWIDTH_CALCS(__VA_ARGS__); \ } while (0) -void pre_surface_trace( - struct dc *dc, - const struct dc_plane_state *const *plane_states, - int surface_count) -{ - int i; - DC_LOGGER_INIT(dc->ctx->logger); - - for (i = 0; i < surface_count; i++) { - const struct dc_plane_state *plane_state = plane_states[i]; - - SURFACE_TRACE("Planes %d:\n", i); - - SURFACE_TRACE( - "plane_state->visible = %d;\n" - "plane_state->flip_immediate = %d;\n" - "plane_state->address.type = %d;\n" - "plane_state->address.grph.addr.quad_part = 0x%llX;\n" - "plane_state->address.grph.meta_addr.quad_part = 0x%llX;\n" - "plane_state->scaling_quality.h_taps = %d;\n" - "plane_state->scaling_quality.v_taps = %d;\n" - "plane_state->scaling_quality.h_taps_c = %d;\n" - "plane_state->scaling_quality.v_taps_c = %d;\n", - plane_state->visible, - plane_state->flip_immediate, - plane_state->address.type, - plane_state->address.grph.addr.quad_part, - plane_state->address.grph.meta_addr.quad_part, - plane_state->scaling_quality.h_taps, - plane_state->scaling_quality.v_taps, - plane_state->scaling_quality.h_taps_c, - plane_state->scaling_quality.v_taps_c); - - SURFACE_TRACE( - "plane_state->src_rect.x = %d;\n" - "plane_state->src_rect.y = %d;\n" - "plane_state->src_rect.width = %d;\n" - "plane_state->src_rect.height = %d;\n" - "plane_state->dst_rect.x = %d;\n" - "plane_state->dst_rect.y = %d;\n" - "plane_state->dst_rect.width = %d;\n" - "plane_state->dst_rect.height = %d;\n" - "plane_state->clip_rect.x = %d;\n" - "plane_state->clip_rect.y = %d;\n" - "plane_state->clip_rect.width = %d;\n" - "plane_state->clip_rect.height = %d;\n", - plane_state->src_rect.x, - plane_state->src_rect.y, - plane_state->src_rect.width, - plane_state->src_rect.height, - plane_state->dst_rect.x, - plane_state->dst_rect.y, - plane_state->dst_rect.width, - plane_state->dst_rect.height, - plane_state->clip_rect.x, - plane_state->clip_rect.y, - plane_state->clip_rect.width, - plane_state->clip_rect.height); - - SURFACE_TRACE( - "plane_state->plane_size.surface_size.x = %d;\n" - "plane_state->plane_size.surface_size.y = %d;\n" - "plane_state->plane_size.surface_size.width = %d;\n" - "plane_state->plane_size.surface_size.height = %d;\n" - "plane_state->plane_size.surface_pitch = %d;\n", - plane_state->plane_size.surface_size.x, - plane_state->plane_size.surface_size.y, - plane_state->plane_size.surface_size.width, - plane_state->plane_size.surface_size.height, - plane_state->plane_size.surface_pitch); - - - SURFACE_TRACE( - "plane_state->tiling_info.gfx8.num_banks = %d;\n" - "plane_state->tiling_info.gfx8.bank_width = %d;\n" - "plane_state->tiling_info.gfx8.bank_width_c = %d;\n" - "plane_state->tiling_info.gfx8.bank_height = %d;\n" - "plane_state->tiling_info.gfx8.bank_height_c = %d;\n" - "plane_state->tiling_info.gfx8.tile_aspect = %d;\n" - "plane_state->tiling_info.gfx8.tile_aspect_c = %d;\n" - "plane_state->tiling_info.gfx8.tile_split = %d;\n" - "plane_state->tiling_info.gfx8.tile_split_c = %d;\n" - "plane_state->tiling_info.gfx8.tile_mode = %d;\n" - "plane_state->tiling_info.gfx8.tile_mode_c = %d;\n", - plane_state->tiling_info.gfx8.num_banks, - plane_state->tiling_info.gfx8.bank_width, - plane_state->tiling_info.gfx8.bank_width_c, - plane_state->tiling_info.gfx8.bank_height, - plane_state->tiling_info.gfx8.bank_height_c, - plane_state->tiling_info.gfx8.tile_aspect, - plane_state->tiling_info.gfx8.tile_aspect_c, - plane_state->tiling_info.gfx8.tile_split, - plane_state->tiling_info.gfx8.tile_split_c, - plane_state->tiling_info.gfx8.tile_mode, - plane_state->tiling_info.gfx8.tile_mode_c); - - SURFACE_TRACE( - "plane_state->tiling_info.gfx8.pipe_config = %d;\n" - "plane_state->tiling_info.gfx8.array_mode = %d;\n" - "plane_state->color_space = %d;\n" - "plane_state->dcc.enable = %d;\n" - "plane_state->format = %d;\n" - "plane_state->rotation = %d;\n" - "plane_state->stereo_format = %d;\n", - plane_state->tiling_info.gfx8.pipe_config, - plane_state->tiling_info.gfx8.array_mode, - plane_state->color_space, - plane_state->dcc.enable, - plane_state->format, - plane_state->rotation, - plane_state->stereo_format); - - SURFACE_TRACE("plane_state->tiling_info.gfx9.swizzle = %d;\n", - plane_state->tiling_info.gfx9.swizzle); - - SURFACE_TRACE("\n"); - } - SURFACE_TRACE("\n"); -} - void update_surface_trace( struct dc *dc, const struct dc_surface_update *updates, diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c index 6eb9bae3af91..55b32dfbfdd6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c @@ -34,6 +34,7 @@ #include "dc_state_priv.h" #define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0])) +#define MAX_NUM_MCACHE 8 /* used as index in array of black_color_format */ enum black_color_format { @@ -176,7 +177,7 @@ static bool is_ycbcr2020_type( { bool ret = false; - if (color_space == COLOR_SPACE_2020_YCBCR) + if (color_space == COLOR_SPACE_2020_YCBCR_LIMITED || color_space == COLOR_SPACE_2020_YCBCR_FULL) ret = true; return ret; } @@ -247,7 +248,8 @@ void color_space_to_black_color( case COLOR_SPACE_YCBCR709_BLACK: case COLOR_SPACE_YCBCR601_LIMITED: case COLOR_SPACE_YCBCR709_LIMITED: - case COLOR_SPACE_2020_YCBCR: + case COLOR_SPACE_2020_YCBCR_LIMITED: + case COLOR_SPACE_2020_YCBCR_FULL: *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV]; break; @@ -552,6 +554,53 @@ void get_cursor_visual_confirm_color( } } +void get_dcc_visual_confirm_color( + struct dc *dc, + struct pipe_ctx *pipe_ctx, + struct tg_color *color) +{ + const uint32_t MCACHE_ID_UNASSIGNED = 0xF; + + if (!pipe_ctx->plane_state->dcc.enable) { + color->color_r_cr = 0; /* black - DCC disabled */ + color->color_g_y = 0; + color->color_b_cb = 0; + return; + } + + if (dc->ctx->dce_version < DCN_VERSION_4_01) { + color->color_r_cr = MAX_TG_COLOR_VALUE; /* red - DCC enabled */ + color->color_g_y = 0; + color->color_b_cb = 0; + return; + } + + uint32_t first_id = pipe_ctx->mcache_regs.main.p0.mcache_id_first; + uint32_t second_id = pipe_ctx->mcache_regs.main.p0.mcache_id_second; + + if (first_id != MCACHE_ID_UNASSIGNED && second_id != MCACHE_ID_UNASSIGNED && first_id != second_id) { + color->color_r_cr = MAX_TG_COLOR_VALUE/2; /* grey - 2 mcache */ + color->color_g_y = MAX_TG_COLOR_VALUE/2; + color->color_b_cb = MAX_TG_COLOR_VALUE/2; + } + + else if (first_id != MCACHE_ID_UNASSIGNED || second_id != MCACHE_ID_UNASSIGNED) { + const struct tg_color id_colors[MAX_NUM_MCACHE] = { + {0, MAX_TG_COLOR_VALUE, 0}, /* green */ + {0, 0, MAX_TG_COLOR_VALUE}, /* blue */ + {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, 0}, /* yellow */ + {MAX_TG_COLOR_VALUE, 0, MAX_TG_COLOR_VALUE}, /* magenta */ + {0, MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE}, /* cyan */ + {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE}, /* white */ + {MAX_TG_COLOR_VALUE/2, 0, 0}, /* dark red */ + {0, MAX_TG_COLOR_VALUE/2, 0}, /* dark green */ + }; + + uint32_t assigned_id = (first_id != MCACHE_ID_UNASSIGNED) ? first_id : second_id; + *color = id_colors[assigned_id]; + } +} + void set_p_state_switch_method( struct dc *dc, struct dc_state *context, @@ -563,6 +612,7 @@ void set_p_state_switch_method( if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !vba) return; + pipe_ctx->p_state_type = P_STATE_UNKNOWN; if (vba->DRAMClockChangeSupport[vba->VoltageLevel][vba->maxMpcComb] != dm_dram_clock_change_unsupported) { /* MCLK switching is supported */ @@ -609,6 +659,21 @@ void set_p_state_switch_method( } } +void set_drr_and_clear_adjust_pending( + struct pipe_ctx *pipe_ctx, + struct dc_stream_state *stream, + struct drr_params *params) +{ + /* params can be null.*/ + if (pipe_ctx && pipe_ctx->stream_res.tg && + pipe_ctx->stream_res.tg->funcs->set_drr) + pipe_ctx->stream_res.tg->funcs->set_drr( + pipe_ctx->stream_res.tg, params); + + if (stream) + stream->adjust.timing_adjust_pending = false; +} + void get_fams2_visual_confirm_color( struct dc *dc, struct dc_state *context, @@ -752,7 +817,14 @@ void hwss_build_fast_sequence(struct dc *dc, block_sequence[*num_steps].func = DPP_SET_OUTPUT_TRANSFER_FUNC; (*num_steps)++; } - + if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE && + dc->hwss.update_visual_confirm_color) { + block_sequence[*num_steps].params.update_visual_confirm_params.dc = dc; + block_sequence[*num_steps].params.update_visual_confirm_params.pipe_ctx = current_mpc_pipe; + block_sequence[*num_steps].params.update_visual_confirm_params.mpcc_id = current_mpc_pipe->plane_res.hubp->inst; + block_sequence[*num_steps].func = MPC_UPDATE_VISUAL_CONFIRM; + (*num_steps)++; + } if (current_mpc_pipe->stream->update_flags.bits.out_csc) { block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpc = dc->res_pool->mpc; block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpcc_id = current_mpc_pipe->plane_res.hubp->inst; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c index 039b176e086d..814f68d76257 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c @@ -44,20 +44,8 @@ static bool is_dig_link_enc_stream(struct dc_stream_state *stream) * yet match. */ if (link_enc && ((uint32_t)stream->link->connector_signal & link_enc->output_signals)) { - if (dc_is_dp_signal(stream->signal)) { - /* DIGs do not support DP2.0 streams with 128b/132b encoding. */ - struct dc_link_settings link_settings = {0}; - - stream->ctx->dc->link_srv->dp_decide_link_settings(stream, &link_settings); - if ((link_settings.link_rate >= LINK_RATE_LOW) && - link_settings.link_rate <= LINK_RATE_HIGH3) { - is_dig_stream = true; - break; - } - } else { - is_dig_stream = true; - break; - } + is_dig_stream = true; + break; } } } @@ -559,17 +547,6 @@ struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc) return link_enc; } -struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream( - struct dc *dc, - const struct dc_stream_state *stream) -{ - struct link_encoder *link_enc; - - link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, stream->link); - - return link_enc; -} - struct link_encoder *link_enc_cfg_get_link_enc( const struct dc_link *link) { diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index c1b79b379447..71e15da4bb69 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -150,6 +150,12 @@ bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx) return link->dc->link_srv->update_dsc_config(pipe_ctx); } +struct ddc_service * +dc_get_oem_i2c_device(struct dc *dc) +{ + return dc->res_pool->oem_device; +} + bool dc_is_oem_i2c_device_present( struct dc *dc, size_t slave_address) @@ -364,15 +370,10 @@ bool dc_link_should_enable_fec(const struct dc_link *link) return link->dc->link_srv->dp_should_enable_fec(link); } -int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link( +void dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link( struct dc_link *link, int peak_bw) { - return link->dc->link_srv->dpia_handle_usb4_bandwidth_allocation_for_link(link, peak_bw); -} - -void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result) -{ - link->dc->link_srv->dpia_handle_bw_alloc_response(link, bw, result); + link->dc->link_srv->dpia_handle_usb4_bandwidth_allocation_for_link(link, peak_bw); } bool dc_link_check_link_loss_status( diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 298668e9729c..313a32248cd7 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -76,6 +76,7 @@ #include "dcn321/dcn321_resource.h" #include "dcn35/dcn35_resource.h" #include "dcn351/dcn351_resource.h" +#include "dcn36/dcn36_resource.h" #include "dcn401/dcn401_resource.h" #if defined(CONFIG_DRM_AMD_DC_FP) #include "dc_spl_translate.h" @@ -204,6 +205,8 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) dc_version = DCN_VERSION_3_5; if (ASICREV_IS_GC_11_0_4(asic_id.hw_internal_rev)) dc_version = DCN_VERSION_3_51; + if (ASICREV_IS_DCN36(asic_id.hw_internal_rev)) + dc_version = DCN_VERSION_3_6; break; case AMDGPU_FAMILY_GC_12_0_0: if (ASICREV_IS_GC_12_0_1_A0(asic_id.hw_internal_rev) || @@ -320,6 +323,9 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc, case DCN_VERSION_3_51: res_pool = dcn351_create_resource_pool(init_data, dc); break; + case DCN_VERSION_3_6: + res_pool = dcn36_create_resource_pool(init_data, dc); + break; case DCN_VERSION_4_01: res_pool = dcn401_create_resource_pool(init_data, dc); break; @@ -941,6 +947,17 @@ static void calculate_adjust_recout_for_visual_confirm(struct pipe_ctx *pipe_ctx *base_offset = VISUAL_CONFIRM_BASE_DEFAULT; } +static void reverse_adjust_recout_for_visual_confirm(struct rect *recout, + struct pipe_ctx *pipe_ctx) +{ + int dpp_offset, base_offset; + + calculate_adjust_recout_for_visual_confirm(pipe_ctx, &base_offset, + &dpp_offset); + recout->height += base_offset; + recout->height += dpp_offset; +} + static void adjust_recout_for_visual_confirm(struct rect *recout, struct pipe_ctx *pipe_ctx) { @@ -1642,6 +1659,62 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) return res; } +bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) +{ + struct pipe_ctx *test_pipe, *split_pipe; + struct rect r1 = pipe_ctx->plane_res.scl_data.recout; + int r1_right, r1_bottom; + int cur_layer = pipe_ctx->plane_state->layer_index; + + reverse_adjust_recout_for_visual_confirm(&r1, pipe_ctx); + r1_right = r1.x + r1.width; + r1_bottom = r1.y + r1.height; + + /** + * Disable the cursor if there's another pipe above this with a + * plane that contains this pipe's viewport to prevent double cursor + * and incorrect scaling artifacts. + */ + for (test_pipe = pipe_ctx->top_pipe; test_pipe; + test_pipe = test_pipe->top_pipe) { + struct rect r2; + int r2_right, r2_bottom; + // Skip invisible layer and pipe-split plane on same layer + if (!test_pipe->plane_state || + !test_pipe->plane_state->visible || + test_pipe->plane_state->layer_index == cur_layer) + continue; + + r2 = test_pipe->plane_res.scl_data.recout; + reverse_adjust_recout_for_visual_confirm(&r2, test_pipe); + r2_right = r2.x + r2.width; + r2_bottom = r2.y + r2.height; + + /** + * 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) { + struct rect r2_half; + + r2_half = split_pipe->plane_res.scl_data.recout; + reverse_adjust_recout_for_visual_confirm(&r2_half, split_pipe); + r2.x = min(r2_half.x, r2.x); + r2.width = r2.width + r2_half.width; + r2_right = r2.x + r2.width; + r2_bottom = min(r2_bottom, r2_half.y + r2_half.height); + break; + } + + if (r1.x >= r2.x && r1.y >= r2.y && r1_right <= r2_right && r1_bottom <= r2_bottom) + return true; + } + + return false; +} + enum dc_status resource_build_scaling_params_for_context( const struct dc *dc, @@ -2617,6 +2690,162 @@ static void remove_hpo_dp_link_enc_from_ctx(struct resource_context *res_ctx, } } +static inline int find_acquired_dio_link_enc_for_link( + const struct resource_context *res_ctx, + const struct dc_link *link) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(res_ctx->dio_link_enc_ref_cnts); i++) + if (res_ctx->dio_link_enc_ref_cnts[i] > 0 && + res_ctx->dio_link_enc_to_link_idx[i] == link->link_index) + return i; + + return -1; +} + +static inline int find_fixed_dio_link_enc(const struct dc_link *link) +{ + /* the 8b10b dp phy can only use fixed link encoder */ + return link->eng_id; +} + +static inline int find_free_dio_link_enc(const struct resource_context *res_ctx, + const struct dc_link *link, const struct resource_pool *pool) +{ + int i; + int enc_count = pool->dig_link_enc_count; + + /* for dpia, check preferred encoder first and then the next one */ + for (i = 0; i < enc_count; i++) + if (res_ctx->dio_link_enc_ref_cnts[(link->dpia_preferred_eng_id + i) % enc_count] == 0) + break; + + return (i >= 0 && i < enc_count) ? (link->dpia_preferred_eng_id + i) % enc_count : -1; +} + +static inline void acquire_dio_link_enc( + struct resource_context *res_ctx, + unsigned int link_index, + int enc_index) +{ + res_ctx->dio_link_enc_to_link_idx[enc_index] = link_index; + res_ctx->dio_link_enc_ref_cnts[enc_index] = 1; +} + +static inline void retain_dio_link_enc( + struct resource_context *res_ctx, + int enc_index) +{ + res_ctx->dio_link_enc_ref_cnts[enc_index]++; +} + +static inline void release_dio_link_enc( + struct resource_context *res_ctx, + int enc_index) +{ + ASSERT(res_ctx->dio_link_enc_ref_cnts[enc_index] > 0); + res_ctx->dio_link_enc_ref_cnts[enc_index]--; +} + +static bool is_dio_enc_acquired_by_other_link(const struct dc_link *link, + int enc_index, + int *link_index) +{ + const struct dc *dc = link->dc; + const struct resource_context *res_ctx = &dc->current_state->res_ctx; + + /* pass the link_index that acquired the enc_index */ + if (res_ctx->dio_link_enc_ref_cnts[enc_index] > 0 && + res_ctx->dio_link_enc_to_link_idx[enc_index] != link->link_index) { + *link_index = res_ctx->dio_link_enc_to_link_idx[enc_index]; + return true; + } + + return false; +} + +static void swap_dio_link_enc_to_muxable_ctx(struct dc_state *context, + const struct resource_pool *pool, + int new_encoder, + int old_encoder) +{ + struct resource_context *res_ctx = &context->res_ctx; + int stream_count = context->stream_count; + int i = 0; + + res_ctx->dio_link_enc_ref_cnts[new_encoder] = res_ctx->dio_link_enc_ref_cnts[old_encoder]; + res_ctx->dio_link_enc_to_link_idx[new_encoder] = res_ctx->dio_link_enc_to_link_idx[old_encoder]; + res_ctx->dio_link_enc_ref_cnts[old_encoder] = 0; + + for (i = 0; i < stream_count; i++) { + struct dc_stream_state *stream = context->streams[i]; + struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream(&context->res_ctx, stream); + + if (pipe_ctx && pipe_ctx->link_res.dio_link_enc == pool->link_encoders[old_encoder]) + pipe_ctx->link_res.dio_link_enc = pool->link_encoders[new_encoder]; + } +} + +static bool add_dio_link_enc_to_ctx(const struct dc *dc, + struct dc_state *context, + const struct resource_pool *pool, + struct pipe_ctx *pipe_ctx, + struct dc_stream_state *stream) +{ + struct resource_context *res_ctx = &context->res_ctx; + int enc_index; + + enc_index = find_acquired_dio_link_enc_for_link(res_ctx, stream->link); + + if (enc_index >= 0) { + retain_dio_link_enc(res_ctx, enc_index); + } else { + if (stream->link->is_dig_mapping_flexible) + enc_index = find_free_dio_link_enc(res_ctx, stream->link, pool); + else { + int link_index = 0; + + enc_index = find_fixed_dio_link_enc(stream->link); + /* Fixed mapping link can only use its fixed link encoder. + * If the encoder is acquired by other link then get a new free encoder and swap the new + * one into the acquiring link. + */ + if (enc_index >= 0 && is_dio_enc_acquired_by_other_link(stream->link, enc_index, &link_index)) { + int new_enc_index = find_free_dio_link_enc(res_ctx, dc->links[link_index], pool); + + if (new_enc_index >= 0) + swap_dio_link_enc_to_muxable_ctx(context, pool, new_enc_index, enc_index); + else + return false; + } + } + + if (enc_index >= 0) + acquire_dio_link_enc(res_ctx, stream->link->link_index, enc_index); + } + + if (enc_index >= 0) + pipe_ctx->link_res.dio_link_enc = pool->link_encoders[enc_index]; + + return pipe_ctx->link_res.dio_link_enc != NULL; +} + +static void remove_dio_link_enc_from_ctx(struct resource_context *res_ctx, + struct pipe_ctx *pipe_ctx, + struct dc_stream_state *stream) +{ + int enc_index = -1; + + if (stream->link) + enc_index = find_acquired_dio_link_enc_for_link(res_ctx, stream->link); + + if (enc_index >= 0) { + release_dio_link_enc(res_ctx, enc_index); + pipe_ctx->link_res.dio_link_enc = NULL; + } +} + static int get_num_of_free_pipes(const struct resource_pool *pool, const struct dc_state *context) { int i; @@ -2664,6 +2893,10 @@ void resource_remove_otg_master_for_stream_output(struct dc_state *context, remove_hpo_dp_link_enc_from_ctx( &context->res_ctx, otg_master, stream); } + + if (stream->ctx->dc->config.unify_link_enc_assignment) + remove_dio_link_enc_from_ctx(&context->res_ctx, otg_master, stream); + if (otg_master->stream_res.audio) update_audio_usage( &context->res_ctx, @@ -2678,6 +2911,7 @@ void resource_remove_otg_master_for_stream_output(struct dc_state *context, if (pool->funcs->remove_stream_from_ctx) pool->funcs->remove_stream_from_ctx( stream->ctx->dc, context, stream); + memset(otg_master, 0, sizeof(*otg_master)); } @@ -3529,16 +3763,22 @@ static int acquire_resource_from_hw_enabled_state( return -1; } -static void mark_seamless_boot_stream( - const struct dc *dc, - struct dc_stream_state *stream) +static void mark_seamless_boot_stream(const struct dc *dc, + struct dc_stream_state *stream) { struct dc_bios *dcb = dc->ctx->dc_bios; - if (dc->config.allow_seamless_boot_optimization && - !dcb->funcs->is_accelerated_mode(dcb)) { - if (dc_validate_boot_timing(dc, stream->sink, &stream->timing)) - stream->apply_seamless_boot_optimization = true; + DC_LOGGER_INIT(dc->ctx->logger); + + if (stream->apply_seamless_boot_optimization) + return; + if (!dc->config.allow_seamless_boot_optimization) + return; + if (dcb->funcs->is_accelerated_mode(dcb)) + return; + if (dc_validate_boot_timing(dc, stream->sink, &stream->timing)) { + stream->apply_seamless_boot_optimization = true; + DC_LOG_DC("Marked stream for seamless boot optimization\n"); } } @@ -3649,6 +3889,7 @@ enum dc_status resource_map_pool_resources( struct pipe_ctx *pipe_ctx = NULL; int pipe_idx = -1; bool acquired = false; + bool is_dio_encoder = true; calculate_phy_pix_clks(stream); @@ -3714,6 +3955,10 @@ enum dc_status resource_map_pool_resources( } } + if (dc->config.unify_link_enc_assignment && is_dio_encoder) + if (!add_dio_link_enc_to_ctx(dc, context, pool, pipe_ctx, stream)) + return DC_NO_LINK_ENC_RESOURCE; + /* TODO: Add check if ASIC support and EDID audio */ if (!stream->converter_disable_audio && dc_is_audio_capable_signal(pipe_ctx->stream->signal) && @@ -4247,7 +4492,7 @@ static void set_avi_info_frame( break; case COLOR_SPACE_2020_RGB_FULLRANGE: case COLOR_SPACE_2020_RGB_LIMITEDRANGE: - case COLOR_SPACE_2020_YCBCR: + case COLOR_SPACE_2020_YCBCR_LIMITED: hdmi_info.bits.EC0_EC2 = COLORIMETRYEX_BT2020RGBYCBCR; hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED; break; @@ -4261,7 +4506,7 @@ static void set_avi_info_frame( break; } - if (pixel_encoding && color_space == COLOR_SPACE_2020_YCBCR && + if (pixel_encoding && color_space == COLOR_SPACE_2020_YCBCR_LIMITED && stream->out_transfer_func.tf == TRANSFER_FUNCTION_GAMMA22) { hdmi_info.bits.EC0_EC2 = 0; hdmi_info.bits.C0_C1 = COLORIMETRY_ITU709; @@ -4684,7 +4929,10 @@ bool pipe_need_reprogram( return true; /* DIG link encoder resource assignment for stream changed. */ - if (pipe_ctx_old->stream->ctx->dc->res_pool->funcs->link_encs_assign) { + if (pipe_ctx_old->stream->ctx->dc->config.unify_link_enc_assignment) { + if (pipe_ctx_old->link_res.dio_link_enc != pipe_ctx->link_res.dio_link_enc) + return true; + } else if (pipe_ctx_old->stream->ctx->dc->res_pool->funcs->link_encs_assign) { bool need_reprogram = false; struct dc *dc = pipe_ctx_old->stream->ctx->dc; struct link_encoder *link_enc_prev = @@ -4950,6 +5198,28 @@ void get_audio_check(struct audio_info *aud_modes, } } +struct link_encoder *get_temp_dio_link_enc( + const struct resource_context *res_ctx, + const struct resource_pool *const pool, + const struct dc_link *link) +{ + struct link_encoder *link_enc = NULL; + int enc_index; + + if (link->is_dig_mapping_flexible) + enc_index = find_acquired_dio_link_enc_for_link(res_ctx, link); + else + enc_index = link->eng_id; + + if (enc_index < 0) + enc_index = find_free_dio_link_enc(res_ctx, link, pool); + + if (enc_index >= 0) + link_enc = pool->link_encoders[enc_index]; + + return link_enc; +} + static struct hpo_dp_link_encoder *get_temp_hpo_dp_link_enc( const struct resource_context *res_ctx, const struct resource_pool *const pool, @@ -4979,11 +5249,17 @@ bool get_temp_dp_link_res(struct dc_link *link, memset(link_res, 0, sizeof(*link_res)); if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) { - link_res->hpo_dp_link_enc = get_temp_hpo_dp_link_enc(res_ctx, - dc->res_pool, link); + link_res->hpo_dp_link_enc = get_temp_hpo_dp_link_enc(res_ctx, dc->res_pool, link); if (!link_res->hpo_dp_link_enc) return false; + } else if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING && + dc->config.unify_link_enc_assignment) { + link_res->dio_link_enc = get_temp_dio_link_enc(res_ctx, + dc->res_pool, link); + if (!link_res->dio_link_enc) + return false; } + return true; } @@ -5255,6 +5531,10 @@ enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc, remove_hpo_dp_link_enc_from_ctx(&context->res_ctx, pipe_ctx, pipe_ctx->stream); } + if (pipe_ctx->link_res.dio_link_enc == NULL && dc->config.unify_link_enc_assignment) + if (!add_dio_link_enc_to_ctx(dc, context, dc->res_pool, pipe_ctx, pipe_ctx->stream)) + return DC_NO_LINK_ENC_RESOURCE; + return DC_OK; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index e8134c47fe0d..0478dd856d8c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -201,7 +201,8 @@ struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream) dc_stream_assign_stream_id(new_stream); /* If using dynamic encoder assignment, wait till stream committed to assign encoder. */ - if (new_stream->ctx->dc->res_pool->funcs->link_encs_assign) + if (new_stream->ctx->dc->res_pool->funcs->link_encs_assign && + !new_stream->ctx->dc->config.unify_link_enc_assignment) new_stream->link_enc = NULL; kref_init(&new_stream->refcount); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index f3471d45b312..e6fcc21bb9bc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -270,8 +270,8 @@ void dc_3dlut_func_retain(struct dc_3dlut *lut) kref_get(&lut->refcount); } -void dc_plane_force_update_for_panic(struct dc_plane_state *plane_state, - bool clear_tiling) +void dc_plane_force_dcc_and_tiling_disable(struct dc_plane_state *plane_state, + bool clear_tiling) { struct dc *dc; int i; @@ -290,30 +290,7 @@ void dc_plane_force_update_for_panic(struct dc_plane_state *plane_state, if (!pipe_ctx) continue; - if (dc->ctx->dce_version >= DCE_VERSION_MAX) { - struct hubp *hubp = pipe_ctx->plane_res.hubp; - if (!hubp) - continue; - /* if framebuffer is tiled, disable tiling */ - if (clear_tiling && hubp->funcs->hubp_clear_tiling) - hubp->funcs->hubp_clear_tiling(hubp); - - /* force page flip to see the new content of the framebuffer */ - hubp->funcs->hubp_program_surface_flip_and_addr(hubp, - &plane_state->address, - true); - } else { - struct mem_input *mi = pipe_ctx->plane_res.mi; - if (!mi) - continue; - /* if framebuffer is tiled, disable tiling */ - if (clear_tiling && mi->funcs->mem_input_clear_tiling) - mi->funcs->mem_input_clear_tiling(mi); - - /* force page flip to see the new content of the framebuffer */ - mi->funcs->mem_input_program_surface_flip_and_addr(mi, - &plane_state->address, - true); - } + if (dc->hwss.clear_surface_dcc_and_tiling) + dc->hwss.clear_surface_dcc_and_tiling(pipe_ctx, plane_state, clear_tiling); } } |