diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc.c | 77 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 133 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link.c | 65 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 42 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 6 |
7 files changed, 315 insertions, 43 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index f03889b3654b..be1dbd3136ec 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -325,6 +325,48 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc, return ret; } +/** + ***************************************************************************** + * Function: dc_stream_get_last_vrr_vtotal + * + * @brief + * Looks up the pipe context of dc_stream_state and gets the + * last VTOTAL used by DRR (Dynamic Refresh Rate) + * + * @param [in] dc: dc reference + * @param [in] stream: Initial dc stream state + * @param [in] adjust: Updated parameters for vertical_total_min and + * vertical_total_max + ***************************************************************************** + */ +bool dc_stream_get_last_used_drr_vtotal(struct dc *dc, + struct dc_stream_state *stream, + uint32_t *refresh_rate) +{ + bool status = false; + + int i = 0; + + 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.tg) { + /* Only execute if a function pointer has been defined for + * the DC version in question + */ + if (pipe->stream_res.tg->funcs->get_last_used_drr_vtotal) { + pipe->stream_res.tg->funcs->get_last_used_drr_vtotal(pipe->stream_res.tg, refresh_rate); + + status = true; + + break; + } + } + } + + 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) @@ -1482,6 +1524,13 @@ static uint8_t get_stream_mask(struct dc *dc, struct dc_state *context) return stream_mask; } +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) +void dc_z10_restore(struct dc *dc) +{ + if (dc->hwss.z10_restore) + dc->hwss.z10_restore(dc); +} +#endif /* * Applies given context to HW and copy it into current context. * It's up to the user to release the src context afterwards. @@ -1495,6 +1544,9 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c struct dc_stream_state *dc_streams[MAX_STREAMS] = {0}; #if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + dc_z10_restore(dc); +#endif dc_allow_idle_optimizations(dc, false); #endif @@ -1917,8 +1969,13 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa if (u->plane_info->dcc.enable != u->surface->dcc.enable || u->plane_info->dcc.independent_64b_blks != u->surface->dcc.independent_64b_blks || u->plane_info->dcc.meta_pitch != u->surface->dcc.meta_pitch) { + /* During DCC on/off, stutter period is calculated before + * DCC has fully transitioned. This results in incorrect + * stutter period calculation. Triggering a full update will + * recalculate stutter period. + */ update_flags->bits.dcc_change = 1; - elevate_update_type(&update_type, UPDATE_TYPE_MED); + elevate_update_type(&update_type, UPDATE_TYPE_FULL); } if (resource_pixel_format_to_bpp(u->plane_info->format) != @@ -2569,6 +2626,10 @@ static void commit_planes_for_stream(struct dc *dc, int i, j; struct pipe_ctx *top_pipe_to_program = NULL; +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + dc_z10_restore(dc); +#endif + if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) { /* Optimize seamless boot flag keeps clocks and watermarks high until * first flip. After first flip, optimization is required to lower @@ -3024,6 +3085,9 @@ void dc_set_power_state( case DC_ACPI_CM_POWER_STATE_D0: dc_resource_state_construct(dc, dc->current_state); +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + dc_z10_restore(dc); +#endif if (dc->ctx->dmub_srv) dc_dmub_srv_wait_phy_init(dc->ctx->dmub_srv); @@ -3256,10 +3320,13 @@ bool dc_set_psr_allow_active(struct dc *dc, bool enable) continue; if (link->psr_settings.psr_feature_enabled) { - if (enable && !link->psr_settings.psr_allow_active) - return dc_link_set_psr_allow_active(link, true, false, false); - else if (!enable && link->psr_settings.psr_allow_active) - return dc_link_set_psr_allow_active(link, false, true, false); + if (enable && !link->psr_settings.psr_allow_active) { + if (!dc_link_set_psr_allow_active(link, true, false, false)) + return false; + } else if (!enable && link->psr_settings.psr_allow_active) { + if (!dc_link_set_psr_allow_active(link, false, true, false)) + return false; + } } } 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 2a9080400bdd..15f987a63025 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 @@ -291,3 +291,136 @@ bool hwss_wait_for_blank_complete( return true; } + +void get_mpctree_visual_confirm_color( + struct pipe_ctx *pipe_ctx, + struct tg_color *color) +{ + const struct tg_color pipe_colors[6] = { + {MAX_TG_COLOR_VALUE, 0, 0}, /* red */ + {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE / 4, 0}, /* orange */ + {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, 0}, /* yellow */ + {0, MAX_TG_COLOR_VALUE, 0}, /* green */ + {0, 0, MAX_TG_COLOR_VALUE}, /* blue */ + {MAX_TG_COLOR_VALUE / 2, 0, MAX_TG_COLOR_VALUE / 2}, /* purple */ + }; + + struct pipe_ctx *top_pipe = pipe_ctx; + + while (top_pipe->top_pipe) + top_pipe = top_pipe->top_pipe; + + *color = pipe_colors[top_pipe->pipe_idx]; +} + +void get_surface_visual_confirm_color( + const struct pipe_ctx *pipe_ctx, + struct tg_color *color) +{ + uint32_t color_value = MAX_TG_COLOR_VALUE; + + switch (pipe_ctx->plane_res.scl_data.format) { + case PIXEL_FORMAT_ARGB8888: + /* set border color to red */ + color->color_r_cr = color_value; + if (pipe_ctx->plane_state->layer_index > 0) { + /* set border color to pink */ + color->color_b_cb = color_value; + color->color_g_y = color_value * 0.5; + } + break; + + case PIXEL_FORMAT_ARGB2101010: + /* set border color to blue */ + color->color_b_cb = color_value; + if (pipe_ctx->plane_state->layer_index > 0) { + /* set border color to cyan */ + color->color_g_y = color_value; + } + break; + case PIXEL_FORMAT_420BPP8: + /* set border color to green */ + color->color_g_y = color_value; + break; + case PIXEL_FORMAT_420BPP10: + /* set border color to yellow */ + color->color_g_y = color_value; + color->color_r_cr = color_value; + break; + case PIXEL_FORMAT_FP16: + /* set border color to white */ + color->color_r_cr = color_value; + color->color_b_cb = color_value; + color->color_g_y = color_value; + if (pipe_ctx->plane_state->layer_index > 0) { + /* set border color to orange */ + color->color_g_y = 0.22 * color_value; + color->color_b_cb = 0; + } + break; + default: + break; + } +} + +void get_hdr_visual_confirm_color( + struct pipe_ctx *pipe_ctx, + struct tg_color *color) +{ + uint32_t color_value = MAX_TG_COLOR_VALUE; + + /* Determine the overscan color based on the top-most (desktop) plane's context */ + struct pipe_ctx *top_pipe_ctx = pipe_ctx; + + while (top_pipe_ctx->top_pipe != NULL) + top_pipe_ctx = top_pipe_ctx->top_pipe; + + switch (top_pipe_ctx->plane_res.scl_data.format) { + case PIXEL_FORMAT_ARGB2101010: + if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) { + /* HDR10, ARGB2101010 - set border color to red */ + color->color_r_cr = color_value; + } else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) { + /* FreeSync 2 ARGB2101010 - set border color to pink */ + color->color_r_cr = color_value; + color->color_b_cb = color_value; + } + break; + case PIXEL_FORMAT_FP16: + if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) { + /* HDR10, FP16 - set border color to blue */ + color->color_b_cb = color_value; + } else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) { + /* FreeSync 2 HDR - set border color to green */ + color->color_g_y = color_value; + } + break; + default: + /* SDR - set border color to Gray */ + color->color_r_cr = color_value/2; + color->color_b_cb = color_value/2; + color->color_g_y = color_value/2; + break; + } +} + +void get_surface_tile_visual_confirm_color( + struct pipe_ctx *pipe_ctx, + struct tg_color *color) +{ + uint32_t color_value = MAX_TG_COLOR_VALUE; + /* Determine the overscan color based on the top-most (desktop) plane's context */ + struct pipe_ctx *top_pipe_ctx = pipe_ctx; + + while (top_pipe_ctx->top_pipe != NULL) + top_pipe_ctx = top_pipe_ctx->top_pipe; + + switch (top_pipe_ctx->plane_state->tiling_info.gfx9.swizzle) { + case DC_SW_LINEAR: + /* LINEAR Surface - set border color to red */ + color->color_r_cr = color_value; + break; + default: + break; + } +} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index c07b45c021d5..0f91280883a6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1099,24 +1099,6 @@ static bool dc_link_detect_helper(struct dc_link *link, dc_is_dvi_signal(link->connector_signal)) { if (prev_sink) dc_sink_release(prev_sink); - link_disconnect_sink(link); - - return false; - } - /* - * Abort detection for DP connectors if we have - * no EDID and connector is active converter - * as there are no display downstream - * - */ - if (dc_is_dp_sst_signal(link->connector_signal) && - (link->dpcd_caps.dongle_type == - DISPLAY_DONGLE_DP_VGA_CONVERTER || - link->dpcd_caps.dongle_type == - DISPLAY_DONGLE_DP_DVI_CONVERTER)) { - if (prev_sink) - dc_sink_release(prev_sink); - link_disconnect_sink(link); return false; } @@ -2701,16 +2683,24 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; struct dmub_psr *psr = dc->res_pool->psr; + unsigned int panel_inst; if (psr == NULL && force_static) return false; + if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) + return false; + link->psr_settings.psr_allow_active = allow_active; +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + if (!allow_active) + dc_z10_restore(dc); +#endif if (psr != NULL && link->psr_settings.psr_feature_enabled) { if (force_static && psr->funcs->psr_force_static) - psr->funcs->psr_force_static(psr); - psr->funcs->psr_enable(psr, allow_active, wait); + psr->funcs->psr_force_static(psr, panel_inst); + psr->funcs->psr_enable(psr, allow_active, wait, panel_inst); } else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled) dmcu->funcs->set_psr_enable(dmcu, allow_active, wait); else @@ -2724,9 +2714,13 @@ bool dc_link_get_psr_state(const struct dc_link *link, enum dc_psr_state *state) struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; struct dmub_psr *psr = dc->res_pool->psr; + unsigned int panel_inst; + + if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) + return false; if (psr != NULL && link->psr_settings.psr_feature_enabled) - psr->funcs->psr_get_state(psr, state); + psr->funcs->psr_get_state(psr, state, panel_inst); else if (dmcu != NULL && link->psr_settings.psr_feature_enabled) dmcu->funcs->get_psr_state(dmcu, state); @@ -2776,6 +2770,7 @@ bool dc_link_setup_psr(struct dc_link *link, struct dmcu *dmcu; struct dmub_psr *psr; int i; + unsigned int panel_inst; /* updateSinkPsrDpcdConfig*/ union dpcd_psr_configuration psr_configuration; @@ -2791,6 +2786,9 @@ bool dc_link_setup_psr(struct dc_link *link, if (!dmcu && !psr) return false; + if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) + return false; + memset(&psr_configuration, 0, sizeof(psr_configuration)); @@ -2875,8 +2873,16 @@ bool dc_link_setup_psr(struct dc_link *link, psr_context->psr_level.u32all = 0; /*skip power down the single pipe since it blocks the cstate*/ +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + if (link->ctx->asic_id.chip_family >= FAMILY_RV) { + psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true; + if (link->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && !dc->debug.disable_z10) + psr_context->psr_level.bits.SKIP_CRTC_DISABLE = false; + } +#else if (link->ctx->asic_id.chip_family >= FAMILY_RV) psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true; +#endif /* SMU will perform additional powerdown sequence. * For unsupported ASICs, set psr_level flag to skip PSR @@ -2897,7 +2903,8 @@ bool dc_link_setup_psr(struct dc_link *link, psr_context->frame_delay = 0; if (psr) - link->psr_settings.psr_feature_enabled = psr->funcs->psr_copy_settings(psr, link, psr_context); + link->psr_settings.psr_feature_enabled = psr->funcs->psr_copy_settings(psr, + link, psr_context, panel_inst); else link->psr_settings.psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context); @@ -2915,10 +2922,14 @@ void dc_link_get_psr_residency(const struct dc_link *link, uint32_t *residency) { struct dc *dc = link->ctx->dc; struct dmub_psr *psr = dc->res_pool->psr; + unsigned int panel_inst; - // PSR residency measurements only supported on DMCUB + if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) + return; + + /* PSR residency measurements only supported on DMCUB */ if (psr != NULL && link->psr_settings.psr_feature_enabled) - psr->funcs->psr_get_residency(psr, residency); + psr->funcs->psr_get_residency(psr, residency, panel_inst); else *residency = 0; } @@ -3208,8 +3219,14 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off) dp_get_panel_mode(pipe_ctx->stream->link); config.otg_inst = (uint8_t) pipe_ctx->stream_res.tg->inst; + /*stream_enc_inst*/ config.dig_fe = (uint8_t) pipe_ctx->stream_res.stream_enc->stream_enc_inst; config.dig_be = pipe_ctx->stream->link->link_enc_hw_inst; +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA; + config.link_enc_idx = pipe_ctx->stream->link->link_enc->transmitter - TRANSMITTER_UNIPHY_A; + config.phy_idx = pipe_ctx->stream->link->link_enc->transmitter - TRANSMITTER_UNIPHY_A; +#endif config.dpms_off = dpms_off; config.dm_stream_ctx = pipe_ctx->stream->dm_stream_context; config.assr_enabled = (panel_mode == DP_PANEL_MODE_EDP); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 5a70f55e075c..919c94de2a20 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -435,7 +435,7 @@ bool dp_is_cr_done(enum dc_lane_count ln_count, return true; } -static bool is_ch_eq_done(enum dc_lane_count ln_count, +bool dp_is_ch_eq_done(enum dc_lane_count ln_count, union lane_status *dpcd_lane_status) { bool done = true; @@ -446,7 +446,7 @@ static bool is_ch_eq_done(enum dc_lane_count ln_count, return done; } -static bool is_symbol_locked(enum dc_lane_count ln_count, +bool dp_is_symbol_locked(enum dc_lane_count ln_count, union lane_status *dpcd_lane_status) { bool locked = true; @@ -457,7 +457,7 @@ static bool is_symbol_locked(enum dc_lane_count ln_count, return locked; } -static inline bool is_interlane_aligned(union lane_align_status_updated align_status) +bool dp_is_interlane_aligned(union lane_align_status_updated align_status) { return align_status.bits.INTERLANE_ALIGN_DONE == 1; } @@ -865,9 +865,9 @@ static bool perform_post_lt_adj_req_sequence( if (!dp_is_cr_done(lane_count, dpcd_lane_status)) return false; - if (!is_ch_eq_done(lane_count, dpcd_lane_status) || - !is_symbol_locked(lane_count, dpcd_lane_status) || - !is_interlane_aligned(dpcd_lane_status_updated)) + if (!dp_is_ch_eq_done(lane_count, dpcd_lane_status) || + !dp_is_symbol_locked(lane_count, dpcd_lane_status) || + !dp_is_interlane_aligned(dpcd_lane_status_updated)) return false; for (lane = 0; lane < (uint32_t)(lane_count); lane++) { @@ -913,7 +913,7 @@ static bool perform_post_lt_adj_req_sequence( } /* Only used for channel equalization */ -static uint32_t translate_training_aux_read_interval(uint32_t dpcd_aux_read_interval) +uint32_t dp_translate_training_aux_read_interval(uint32_t dpcd_aux_read_interval) { unsigned int aux_rd_interval_us = 400; @@ -998,7 +998,7 @@ static enum link_training_result perform_channel_equalization_sequence( if (is_repeater(link, offset)) wait_time_microsec = - translate_training_aux_read_interval( + dp_translate_training_aux_read_interval( link->dpcd_caps.lttpr_caps.aux_rd_interval[offset - 1]); dp_wait_for_training_aux_rd_interval( @@ -1021,9 +1021,9 @@ static enum link_training_result perform_channel_equalization_sequence( return LINK_TRAINING_EQ_FAIL_CR; /* 6. check CHEQ done*/ - if (is_ch_eq_done(lane_count, dpcd_lane_status) && - is_symbol_locked(lane_count, dpcd_lane_status) && - is_interlane_aligned(dpcd_lane_status_updated)) + if (dp_is_ch_eq_done(lane_count, dpcd_lane_status) && + dp_is_symbol_locked(lane_count, dpcd_lane_status) && + dp_is_interlane_aligned(dpcd_lane_status_updated)) return LINK_TRAINING_SUCCESS; /* 7. update VS/PE/PC2 in lt_settings*/ @@ -1917,6 +1917,8 @@ static void set_dp_mst_mode(struct dc_link *link, bool mst_enable) link->type = dc_connection_single; link->local_sink = link->remote_sinks[0]; link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT; + dc_sink_retain(link->local_sink); + dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); } else if (mst_enable == true && link->type == dc_connection_single && link->remote_sinks[0] != NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index 13c5c4a34a58..f7dfc8fefdfa 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -332,7 +332,16 @@ void dp_set_hw_test_pattern( uint32_t custom_pattern_size) { struct encoder_set_dp_phy_pattern_param pattern_param = {0}; - struct link_encoder *encoder = link->link_enc; + struct link_encoder *encoder; + + /* Access link encoder based on whether it is statically + * or dynamically assigned to a link. + */ + if (link->is_dig_mapping_flexible && + link->dc->res_pool->funcs->link_encs_assign) + encoder = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link); + else + encoder = link->link_enc; pattern_param.dp_phy_pattern = test_pattern; pattern_param.custom_pattern = custom_pattern; 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 cd864cc83539..5fe4c5f80b54 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -58,6 +58,9 @@ #include "dcn301/dcn301_resource.h" #include "dcn302/dcn302_resource.h" #include "dcn303/dcn303_resource.h" +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) +#include "../dcn31/dcn31_resource.h" +#endif #endif #define DC_LOGGER_INIT(logger) @@ -139,6 +142,14 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) dc_version = DCN_VERSION_3_01; break; #endif + +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + case FAMILY_YELLOW_CARP: + if (ASICREV_IS_YELLOW_CARP(asic_id.hw_internal_rev)) + dc_version = DCN_VERSION_3_1; + break; +#endif + default: dc_version = DCE_VERSION_UNKNOWN; break; @@ -222,6 +233,11 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc, case DCN_VERSION_3_03: res_pool = dcn303_create_resource_pool(init_data, dc); break; +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + case DCN_VERSION_3_1: + res_pool = dcn31_create_resource_pool(init_data, dc); + break; +#endif #endif default: break; @@ -783,6 +799,11 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx) if (split_idx == split_count) { /* rightmost pipe is the remainder recout */ data->recout.width -= data->h_active * split_count - data->recout.x; + + /* ODM combine cases with MPO we can get negative widths */ + if (data->recout.width < 0) + data->recout.width = 0; + data->recout.x = 0; } else data->recout.width = data->h_active - data->recout.x; @@ -1042,9 +1063,16 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) * on certain displays, such as the Sharp 4k. 36bpp is needed * to support SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 and * SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616 with actual > 10 bpc - * precision on at least DCN display engines. + * precision on at least DCN display engines. However, at least + * Carrizo with DCE_VERSION_11_0 does not like 36 bpp lb depth, + * so use only 30 bpp on DCE_VERSION_11_0. Testing with DCE 11.2 and 8.3 + * did not show such problems, so this seems to be the exception. */ - pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_36BPP; + if (plane_state->ctx->dce_version != DCE_VERSION_11_0) + pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_36BPP; + else + pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; + pipe_ctx->plane_res.scl_data.lb_params.alpha_en = plane_state->per_pixel_alpha; if (pipe_ctx->plane_res.xfm != NULL) @@ -2114,6 +2142,16 @@ enum dc_status dc_validate_global_state( if (!new_ctx) return DC_ERROR_UNEXPECTED; +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + + /* + * Update link encoder to stream assignment. + * TODO: Split out reason allocation from validation. + */ + if (dc->res_pool->funcs->link_encs_assign) + dc->res_pool->funcs->link_encs_assign( + dc, new_ctx, new_ctx->streams, new_ctx->stream_count); +#endif if (dc->res_pool->funcs->validate_global) { result = dc->res_pool->funcs->validate_global(dc, new_ctx); 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 25fa712a7847..5420fda47bb7 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -294,6 +294,9 @@ bool dc_stream_set_cursor_attributes( stream->cursor_attributes = *attributes; #if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + dc_z10_restore(dc); +#endif /* disable idle optimizations while updating cursor */ if (dc->idle_optimizations_allowed) { dc_allow_idle_optimizations(dc, false); @@ -355,6 +358,9 @@ bool dc_stream_set_cursor_position( dc = stream->ctx->dc; res_ctx = &dc->current_state->res_ctx; #if defined(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + dc_z10_restore(dc); +#endif /* disable idle optimizations if enabling cursor */ if (dc->idle_optimizations_allowed && !stream->cursor_position.enable && position->enable) { |